compiler.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. {
  2. compiler.pas
  3. Compiling, Linking and Registering in Emulator methods
  4. Copyright (C) 2006-2007 Felipe Monteiro de Carvalho
  5. This file is part of MkSymbian build tool.
  6. MkSymbian is free software;
  7. you can redistribute it and/or modify it under the
  8. terms of the GNU General Public License version 2
  9. as published by the Free Software Foundation.
  10. MkSymbian is distributed in the hope
  11. that it will be useful, but WITHOUT ANY WARRANTY; without even
  12. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13. PURPOSE. See the GNU General Public License for more details.
  14. Please note that the General Public License version 2 does not permit
  15. incorporating MkSymbian into proprietary programs.
  16. }
  17. unit compiler;
  18. {$ifdef fpc}
  19. {$mode delphi}{$H+}
  20. {$endif}
  21. interface
  22. uses
  23. Classes, SysUtils, Process,
  24. constants;
  25. type
  26. { TCompiler }
  27. TCompiler = class(TObject)
  28. private
  29. AProcess: TProcess;
  30. CurrentDirectory: string;
  31. MakeFolder, MakePartialFolder: string;
  32. public
  33. opts: TMkSymbianOptions;
  34. constructor Create;
  35. destructor Destroy; override;
  36. procedure FileCopy(source, dest: string);
  37. procedure MakeBuildPascal;
  38. procedure MakeBuildCpp;
  39. procedure MakeBuildBindings;
  40. procedure BuildUIDFile;
  41. procedure BuildResource(AFileName: string);
  42. procedure RegisterInEmulator;
  43. end;
  44. var
  45. vCompiler: TCompiler;
  46. implementation
  47. uses sdkutil, projectparser;
  48. { TCompiler }
  49. {*******************************************************************
  50. * TCompiler.Create ()
  51. *
  52. * DESCRIPTION: Initializes the compiler controlling object
  53. *
  54. * PARAMETERS: None
  55. *
  56. * RETURNS: Nothing
  57. *
  58. *******************************************************************}
  59. constructor TCompiler.Create;
  60. begin
  61. inherited Create;
  62. AProcess := TProcess.Create(nil);
  63. CurrentDirectory := ExtractFilePath(ParamStr(0));
  64. MakePartialFolder := Copy(CurrentDirectory, 3, Length(CurrentDirectory) - 2);
  65. MakeFolder := IncludeTrailingBackslash(CurrentDirectory);
  66. AProcess.Options := AProcess.Options + [poWaitOnExit];
  67. end;
  68. {*******************************************************************
  69. * TCompiler.Destroy ()
  70. *
  71. * DESCRIPTION: Finalizes the compiler controlling object
  72. *
  73. * PARAMETERS: None
  74. *
  75. * RETURNS: Nothing
  76. *
  77. *******************************************************************}
  78. destructor TCompiler.Destroy;
  79. begin
  80. AProcess.Free;
  81. inherited Destroy;
  82. end;
  83. {*******************************************************************
  84. * TCompiler.FileCopy ()
  85. *
  86. * DESCRIPTION: Copyes a file from source to dest
  87. *
  88. * PARAMETERS: source - Source file
  89. * dest - Destination file
  90. *
  91. * RETURNS: Nothing
  92. *
  93. *******************************************************************}
  94. procedure TCompiler.FileCopy(source, dest: string);
  95. var
  96. SourceStream, DestStream: TFileStream;
  97. begin
  98. SourceStream := TFileStream.Create(source, fmOpenRead);
  99. try
  100. DestStream := TFileStream.Create(dest, fmCreate);
  101. try
  102. DestStream.CopyFrom(SourceStream, 0);
  103. finally
  104. DestStream.Free;
  105. end;
  106. finally
  107. SourceStream.Free;
  108. end;
  109. end;
  110. {*******************************************************************
  111. * TCompiler.MakeBuildPascal ()
  112. *
  113. * DESCRIPTION: Builds and links a Object Pascal project
  114. *
  115. * PARAMETERS: None
  116. *
  117. * RETURNS: Nothing
  118. *
  119. *******************************************************************}
  120. procedure TCompiler.MakeBuildPascal;
  121. var
  122. STR_LINK_FLAGSUDEB, STR_EPOCBLDUDEB, STR_LINK_OBJSUDEB: string;
  123. STR_GAS: string;
  124. STR_FPC_RTL_OBJECTS: string;
  125. begin
  126. WriteLn('');
  127. WriteLn('Preparations for compiling');
  128. WriteLn('');
  129. // First command
  130. { AProcess.CommandLine := 'perl -S makmake.pl -D ' + MakePartialFolder + 'QHELLOWORLD WINSCW';
  131. WriteLn(AProcess.CommandLine);
  132. AProcess.Execute;}
  133. { Creation of directories }
  134. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\DATA\Z\private\10003a3f\apps');
  135. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\RELEASE\WINSCW\UDEB\Z\private\10003a3f\apps');
  136. ForceDirectories(MakeFolder + 'WINSCW\UDEB');
  137. { Compilation }
  138. STR_GAS := 'C:\Programas\lazarus20\fpc\2.0.4\bin\i386-win32\as.exe';
  139. WriteLn('');
  140. WriteLn('Compiling file ' + vProject.MainSource);
  141. WriteLn('');
  142. AProcess.CommandLine := vProject.CompilerPath + ' -a -s -Fu' + vProject.RTLUnitsDir +
  143. ' -Tsymbian QPasHello.pas';
  144. WriteLn(AProcess.CommandLine);
  145. AProcess.Execute;
  146. WriteLn('');
  147. WriteLn('Assembling file QPasHello.s');
  148. WriteLn('');
  149. AProcess.CommandLine := STR_GAS + ' QPasHello.s -o QPasHello.o';
  150. WriteLn(AProcess.CommandLine);
  151. AProcess.Execute;
  152. { UID File }
  153. BuildUIDFile;
  154. { Linking }
  155. STR_LINK_FLAGSUDEB := '-msgstyle gcc -stdlib "' +
  156. vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EEXE.LIB" -m' +
  157. ' "?_E32Bootstrap@@YGXXZ" -subsystem windows -g ' +
  158. vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EUSER.LIB ' +
  159. '-o "' + MakeFolder + 'QPasHello.exe" -noimplib';
  160. STR_EPOCBLDUDEB := MakeFolder + 'WINSCW\UDEB';
  161. STR_LINK_OBJSUDEB := 'QPasHello.o ' + UID_OBJECT_FILENAME;
  162. STR_FPC_RTL_OBJECTS :=
  163. ' ' + vProject.RTLUnitsDir + 'system.o' +
  164. ' ' + vProject.RTLUnitsDir + 'symbian.o' +
  165. ' ' + vProject.RTLUnitsDir + 'ctypes.o' +
  166. ' ' + vProject.RTLUnitsDir + 'objpas.o' +
  167. ' ' + vProject.RTLUnitsDir + 'pbeexe.o';
  168. WriteLn('');
  169. WriteLn('Linking stage');
  170. WriteLn('');
  171. AProcess.CommandLine := vSDKUtil.SDKFolder + Str_Path_CWTools +
  172. 'mwldsym2.exe ' + STR_LINK_FLAGSUDEB +
  173. ' -l ' + STR_EPOCBLDUDEB +
  174. ' -search ' + STR_LINK_OBJSUDEB + STR_FPC_RTL_OBJECTS;
  175. WriteLn(AProcess.CommandLine);
  176. AProcess.Execute;
  177. FileCopy(MakeFolder + 'QPasHello.exe',
  178. vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\' + 'QPasHello.exe');
  179. end;
  180. {*******************************************************************
  181. * TCompiler.MakeBuildCpp ()
  182. *
  183. * DESCRIPTION: Builds and links a C++ project
  184. *
  185. * PARAMETERS: None
  186. *
  187. * RETURNS: Nothing
  188. *
  189. *******************************************************************}
  190. procedure TCompiler.MakeBuildCpp;
  191. var
  192. STR_LINK_FLAGSUDEB, STR_EPOCBLDUDEB, STR_LINK_OBJSUDEB,
  193. STR_CWUFLAGS, STR_CWDEFS, STR_INCDIR, STR_CWUDEB: string;
  194. begin
  195. WriteLn('');
  196. WriteLn('Preparations for compiling');
  197. WriteLn('');
  198. // First command
  199. AProcess.CommandLine := 'perl -S makmake.pl -D ' + MakePartialFolder + 'QHELLOWORLD WINSCW';
  200. WriteLn(AProcess.CommandLine);
  201. AProcess.Execute;
  202. { Creation of directories }
  203. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\DATA\Z\private\10003a3f\apps');
  204. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\RELEASE\WINSCW\UDEB\Z\private\10003a3f\apps');
  205. ForceDirectories(MakeFolder + 'WINSCW\UDEB');
  206. // TODO: Check if this can be safely removed
  207. // ForceDirectories(MakeFolder + 'QHelloWorld\WINSCW');
  208. { Compilation }
  209. STR_CWUFLAGS := '-wchar_t off -align 4 -warnings on ' +
  210. '-w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostdinc';
  211. STR_CWDEFS := '-d "__SYMBIAN32__" -d "__CW32__" -d "__WINS__" -d "__WINSCW__" -d "__EXE__" -d "__SUPPORT_CPP_EXCEPTIONS__" ';
  212. STR_INCDIR := '-cwd source -i- ' +
  213. '-i "' + vSDKUtil.SDKPartialFolder + 'EPOC32\include" ' +
  214. '-i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant" ' +
  215. '-i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant\ " ' +
  216. '-include "UIQ_3.0.hrh"';
  217. STR_CWUDEB := 'mwccsym2.exe -g -O0 -inline off ' + STR_CWUFLAGS + ' -d _DEBUG -d _UNICODE ' + STR_CWDEFS + STR_INCDIR;
  218. WriteLn('');
  219. WriteLn('Compiling file ' + vProject.MainSource);
  220. WriteLn('');
  221. AProcess.CommandLine := STR_CWUDEB +
  222. ' -o "' + MakeFolder + 'WINSCW\UDEB\' + vProject.MainSourceNoExt + '.o"' +
  223. ' -c "' + MakeFolder + 'src\' + vProject.MainSource + '"';
  224. WriteLn(AProcess.CommandLine);
  225. AProcess.Execute;
  226. { UID File }
  227. BuildUIDFile;
  228. { Linking }
  229. STR_LINK_FLAGSUDEB := '-msgstyle gcc' +
  230. ' -stdlib "' + vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EEXE.LIB"' +
  231. ' -m "?_E32Bootstrap@@YGXXZ" -subsystem windows' +
  232. ' -g ' + vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EUSER.LIB' +
  233. ' -o "' + vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\' + vProject.MainSourceNoExt + '.exe"' +
  234. ' -noimplib';
  235. STR_EPOCBLDUDEB := MakeFolder + 'WINSCW\UDEB';
  236. STR_LINK_OBJSUDEB := vProject.MainSourceNoExt + '.o ' + UID_OBJECT_FILENAME;
  237. WriteLn('');
  238. WriteLn('Linking stage');
  239. WriteLn('');
  240. AProcess.CommandLine := 'mwldsym2.exe ' + STR_LINK_FLAGSUDEB +
  241. ' -l ' + STR_EPOCBLDUDEB +
  242. ' -search ' + STR_LINK_OBJSUDEB;
  243. WriteLn(AProcess.CommandLine);
  244. AProcess.Execute;
  245. end;
  246. {*******************************************************************
  247. * TCompiler.MakeBuildBindings ()
  248. *
  249. * DESCRIPTION: Builds and links the C interface for the symbian libraries
  250. *
  251. * PARAMETERS: None
  252. *
  253. * RETURNS: Nothing
  254. *
  255. *******************************************************************}
  256. procedure TCompiler.MakeBuildBindings;
  257. var
  258. STR_CWUFLAGS, STR_CWDEFS, STR_INCDIR, STR_CWUDEB, STR_CWCOMPILER: string;
  259. begin
  260. { Compilation }
  261. STR_CWUFLAGS := '-wchar_t off -align 4 -warnings on ' +
  262. '-w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostdinc';
  263. STR_CWDEFS := '-d "__SYMBIAN32__" -d "__CW32__" -d "__WINS__" -d "__WINSCW__" -d "__EXE__" -d "__SUPPORT_CPP_EXCEPTIONS__" ';
  264. STR_INCDIR := '-cwd source -i-' +
  265. ' -i "' + vSDKUtil.SDKPartialFolder + 'EPOC32\include"' +
  266. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant"' +
  267. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant\ "' +
  268. ' -include "UIQ_3.0.hrh"';
  269. STR_CWCOMPILER := vSDKUtil.SDKFolder + Str_Path_CWTools + 'mwccsym2.exe';
  270. STR_CWUDEB := STR_CWCOMPILER + ' -g -O0 -inline off ' + STR_CWUFLAGS + ' -d _DEBUG -d _UNICODE ' + STR_CWDEFS + STR_INCDIR;
  271. WriteLn('');
  272. WriteLn('Compiling file pbeexe.cpp');
  273. WriteLn('');
  274. AProcess.CommandLine := STR_CWUDEB + ' -o "' + MakePartialFolder + 'pbeexe.o" ' +
  275. '-c "' + MakePartialFolder + 'pbeexe.cpp"';
  276. WriteLn(AProcess.CommandLine);
  277. AProcess.Execute;
  278. FileCopy(MakePartialFolder + 'pbeexe.o', vProject.RTLUnitsDir + 'pbeexe.o');
  279. end;
  280. {*******************************************************************
  281. * TCompiler.BuildUIDFile ()
  282. *
  283. * DESCRIPTION: Generates and compiles a UID file
  284. *
  285. * PARAMETERS: None
  286. *
  287. * RETURNS: Nothing
  288. *
  289. *******************************************************************}
  290. procedure TCompiler.BuildUIDFile;
  291. var
  292. Str_UIDFile: string;
  293. UIDFile: TFileStream;
  294. STR_CWUFLAGS, STR_CWDEFS, STR_INCDIR, STR_CWUDEB, STR_CWCOMPILER: string;
  295. begin
  296. { First creates the UID file }
  297. WriteLn('');
  298. WriteLn('Creating UID file');
  299. WriteLn('');
  300. Str_UIDFile :=
  301. '// mksymbian-generated uid source file' + LineEnding +
  302. '#include <e32cmn.h>' + LineEnding +
  303. '#pragma data_seg(".SYMBIAN")' + LineEnding +
  304. '__EMULATOR_IMAGE_HEADER2(0x1000007a,' + vProject.UID2 + ',' + vProject.UID3 +
  305. ',EPriorityForeground,0x00000000u,0x00000000u,0x01000001,0,0x00010000,0)' + LineEnding +
  306. '#pragma data_seg()' + LineEnding;
  307. UIDFile := TFileStream.Create(UID_SOURCE_FILENAME, fmCreate);
  308. try
  309. UIDFile.Write(Pointer(Str_UIDFile)^, Length(Str_UIDFile));
  310. finally
  311. UIDFile.Free;
  312. end;
  313. { Compilation }
  314. STR_CWUFLAGS := '-wchar_t off -align 4 -warnings on ' +
  315. '-w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostdinc';
  316. STR_CWDEFS := '-d "__SYMBIAN32__" -d "__CW32__" -d "__WINS__" -d "__WINSCW__" -d "__EXE__" -d "__SUPPORT_CPP_EXCEPTIONS__" ';
  317. STR_INCDIR := '-cwd source -i- ' +
  318. ' -i "' + vSDKUtil.SDKPartialFolder + 'EPOC32\include" ' +
  319. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant" ' +
  320. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant\ "' +
  321. ' -include "UIQ_3.0.hrh"';
  322. STR_CWCOMPILER := vSDKUtil.SDKFolder + Str_Path_CWTools + 'mwccsym2.exe';
  323. STR_CWUDEB := STR_CWCOMPILER + ' -g -O0 -inline off ' + STR_CWUFLAGS + ' -d _DEBUG -d _UNICODE ' + STR_CWDEFS + STR_INCDIR;
  324. WriteLn('');
  325. WriteLn('Compiling file ' + UID_SOURCE_FILENAME);
  326. WriteLn('');
  327. AProcess.CommandLine := STR_CWUDEB +
  328. ' -o "' + MakeFolder + UID_OBJECT_FILENAME + '"' +
  329. ' -c "' + MakeFolder + UID_SOURCE_FILENAME + '"';
  330. WriteLn(AProcess.CommandLine);
  331. AProcess.Execute;
  332. end;
  333. {*******************************************************************
  334. * TCompiler.BuildResource ()
  335. *
  336. * DESCRIPTION: Builds a resource file
  337. *
  338. * PARAMETERS: None
  339. *
  340. * RETURNS: Nothing
  341. *
  342. *******************************************************************}
  343. procedure TCompiler.BuildResource(AFileName: string);
  344. begin
  345. WriteLn('');
  346. WriteLn('Preprocessing resource file: ' + AFileName);
  347. WriteLn('');
  348. AProcess.CommandLine := vSDKUtil.SDKFolder + Str_Path_Cpp +
  349. ' -lang-c++' +
  350. ' -I ' + vSDKUtil.SDKPartialFolder + 'EPOC32\include' +
  351. ' -I ' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant' +
  352. ' ' + MakeFolder + AFileName +
  353. ' ' + MakeFolder + ChangeFileExt(AFileName, STR_RESOURCE_TMP_EXT);
  354. WriteLn(AProcess.CommandLine);
  355. AProcess.Execute;
  356. WriteLn('');
  357. WriteLn('Building resource file: ' + AFileName);
  358. WriteLn('');
  359. AProcess.CommandLine := vSDKUtil.SDKFolder + Str_Path_RComp +
  360. ' -v -u' +
  361. ' -o"' + MakeFolder + ChangeFileExt(AFileName, STR_RESOURCE_EXT) + '"' +
  362. ' -s"' + MakeFolder + ChangeFileExt(AFileName, STR_RESOURCE_TMP_EXT) + '"';
  363. WriteLn(AProcess.CommandLine);
  364. AProcess.Execute;
  365. end;
  366. {*******************************************************************
  367. * TCompiler.RegisterInEmulator ()
  368. *
  369. * DESCRIPTION: Registers a software in the emulator
  370. * At this point the resource file must already be compiled
  371. *
  372. * PARAMETERS: None
  373. *
  374. * RETURNS: Nothing
  375. *
  376. *******************************************************************}
  377. procedure TCompiler.RegisterInEmulator;
  378. var
  379. StrFrom, StrTo: string;
  380. begin
  381. WriteLn('');
  382. WriteLn('Registering the software on the emulator');
  383. WriteLn('');
  384. StrFrom := MakeFolder + ChangeFileExt(vProject.MainResource, STR_RESOURCE_EXT);
  385. StrTo := vSDKUtil.SDKFolder + Str_Path_Emulator_Registration +
  386. ChangeFileExt(vProject.MainResource, STR_RESOURCE_EXT);
  387. WriteLn('');
  388. WriteLn('Copying file: ', StrFrom);
  389. WriteLn('To: ', StrTo);
  390. WriteLn('');
  391. FileCopy(StrFrom, StrTo);
  392. end;
  393. end.