compiler.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  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, BindingsUnitsFolder: 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. { When compiling the bindings we use a relative directory to get the output dir }
  67. BindingsUnitsFolder := MakeFolder + '../../units/i386-symbian/';
  68. AProcess.Options := AProcess.Options + [poWaitOnExit];
  69. end;
  70. {*******************************************************************
  71. * TCompiler.Destroy ()
  72. *
  73. * DESCRIPTION: Finalizes the compiler controlling object
  74. *
  75. * PARAMETERS: None
  76. *
  77. * RETURNS: Nothing
  78. *
  79. *******************************************************************}
  80. destructor TCompiler.Destroy;
  81. begin
  82. AProcess.Free;
  83. inherited Destroy;
  84. end;
  85. {*******************************************************************
  86. * TCompiler.FileCopy ()
  87. *
  88. * DESCRIPTION: Copyes a file from source to dest
  89. *
  90. * PARAMETERS: source - Source file
  91. * dest - Destination file
  92. *
  93. * RETURNS: Nothing
  94. *
  95. *******************************************************************}
  96. procedure TCompiler.FileCopy(source, dest: string);
  97. var
  98. SourceStream, DestStream: TFileStream;
  99. begin
  100. SourceStream := TFileStream.Create(source, fmOpenRead);
  101. try
  102. DestStream := TFileStream.Create(dest, fmCreate);
  103. try
  104. DestStream.CopyFrom(SourceStream, 0);
  105. finally
  106. DestStream.Free;
  107. end;
  108. finally
  109. SourceStream.Free;
  110. end;
  111. end;
  112. {*******************************************************************
  113. * TCompiler.MakeBuildPascal ()
  114. *
  115. * DESCRIPTION: Builds and links a Object Pascal project
  116. *
  117. * PARAMETERS: None
  118. *
  119. * RETURNS: Nothing
  120. *
  121. *******************************************************************}
  122. procedure TCompiler.MakeBuildPascal;
  123. var
  124. STR_LINK_FLAGSUDEB, STR_EPOCBLDUDEB, STR_LINK_OBJSUDEB: string;
  125. STR_FPC_RTL_OBJECTS: string;
  126. i: Integer;
  127. begin
  128. WriteLn('');
  129. WriteLn('Preparations for compiling');
  130. WriteLn('');
  131. // First command
  132. { AProcess.CommandLine := 'perl -S makmake.pl -D ' + MakePartialFolder + 'QHELLOWORLD WINSCW';
  133. WriteLn(AProcess.CommandLine);
  134. AProcess.Execute;}
  135. { Creation of directories }
  136. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\DATA\Z\private\10003a3f\apps');
  137. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\RELEASE\WINSCW\UDEB\Z\private\10003a3f\apps');
  138. ForceDirectories(MakeFolder + 'WINSCW\UDEB');
  139. { Compilation }
  140. WriteLn('');
  141. WriteLn('Compiling file ' + vProject.MainSource);
  142. WriteLn('');
  143. AProcess.CommandLine := vProject.CompilerPath + ' -a -s -Fu' + vProject.RTLUnitsDir +
  144. ' -Tsymbian QPasHello.pas';
  145. WriteLn(AProcess.CommandLine);
  146. AProcess.Execute;
  147. WriteLn('');
  148. WriteLn('Assembling file QPasHello.s');
  149. WriteLn('');
  150. AProcess.CommandLine := vProject.AssemblerPath + ' QPasHello.s -o QPasHello.o';
  151. WriteLn(AProcess.CommandLine);
  152. AProcess.Execute;
  153. { UID File }
  154. BuildUIDFile;
  155. { Linking }
  156. STR_LINK_FLAGSUDEB := '-msgstyle gcc -stdlib "' +
  157. vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EEXE.LIB" -m' +
  158. ' "?_E32Bootstrap@@YGXXZ" -subsystem windows -g ' +
  159. vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EUSER.LIB ' +
  160. '-o "' + MakeFolder + 'QPasHello.exe" -noimplib';
  161. STR_EPOCBLDUDEB := MakeFolder + 'WINSCW\UDEB';
  162. STR_LINK_OBJSUDEB :=
  163. ' ' + MakeFolder + UID_OBJECT_FILENAME;
  164. for i := 0 to vProject.ObjectFiles.Count - 1 do
  165. STR_LINK_OBJSUDEB := STR_LINK_OBJSUDEB +
  166. ' ' + MakeFolder + vProject.ObjectFiles.Strings[i];
  167. STR_FPC_RTL_OBJECTS :=
  168. ' ' + vProject.RTLUnitsDir + 'system.o' +
  169. ' ' + vProject.RTLUnitsDir + 'symbian.o' +
  170. ' ' + vProject.RTLUnitsDir + 'ctypes.o' +
  171. ' ' + vProject.RTLUnitsDir + 'objpas.o' +
  172. ' ' + vProject.RTLUnitsDir + 'pbeexe.o';
  173. WriteLn('');
  174. WriteLn('Linking stage');
  175. WriteLn('');
  176. AProcess.CommandLine := vSDKUtil.SDKFolder + Str_Path_CWTools +
  177. 'mwldsym2.exe ' + STR_LINK_FLAGSUDEB +
  178. ' -l ' + MakeFolder +
  179. ' -search ' + STR_LINK_OBJSUDEB + STR_FPC_RTL_OBJECTS;
  180. WriteLn(AProcess.CommandLine);
  181. AProcess.Execute;
  182. FileCopy(MakeFolder + 'QPasHello.exe',
  183. vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\' + 'QPasHello.exe');
  184. end;
  185. {*******************************************************************
  186. * TCompiler.MakeBuildCpp ()
  187. *
  188. * DESCRIPTION: Builds and links a C++ project
  189. *
  190. * PARAMETERS: None
  191. *
  192. * RETURNS: Nothing
  193. *
  194. *******************************************************************}
  195. procedure TCompiler.MakeBuildCpp;
  196. var
  197. STR_LINK_FLAGSUDEB, STR_EPOCBLDUDEB, STR_LINK_OBJSUDEB,
  198. STR_CWUFLAGS, STR_CWDEFS, STR_INCDIR, STR_CWUDEB: string;
  199. begin
  200. WriteLn('');
  201. WriteLn('Preparations for compiling');
  202. WriteLn('');
  203. // First command
  204. AProcess.CommandLine := 'perl -S makmake.pl -D ' + MakePartialFolder + 'QHELLOWORLD WINSCW';
  205. WriteLn(AProcess.CommandLine);
  206. AProcess.Execute;
  207. { Creation of directories }
  208. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\DATA\Z\private\10003a3f\apps');
  209. ForceDirectories(vSDKUtil.SDKFolder + 'EPOC32\RELEASE\WINSCW\UDEB\Z\private\10003a3f\apps');
  210. ForceDirectories(MakeFolder + 'WINSCW\UDEB');
  211. // TODO: Check if this can be safely removed
  212. // ForceDirectories(MakeFolder + 'QHelloWorld\WINSCW');
  213. { Compilation }
  214. STR_CWUFLAGS := '-wchar_t off -align 4 -warnings on ' +
  215. '-w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostdinc';
  216. STR_CWDEFS := '-d "__SYMBIAN32__" -d "__CW32__" -d "__WINS__" -d "__WINSCW__" -d "__EXE__" -d "__SUPPORT_CPP_EXCEPTIONS__" ';
  217. STR_INCDIR := '-cwd source -i- ' +
  218. '-i "' + vSDKUtil.SDKPartialFolder + 'EPOC32\include" ' +
  219. '-i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant" ' +
  220. '-i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant\ " ' +
  221. '-include "UIQ_3.0.hrh"';
  222. STR_CWUDEB := 'mwccsym2.exe -g -O0 -inline off ' + STR_CWUFLAGS + ' -d _DEBUG -d _UNICODE ' + STR_CWDEFS + STR_INCDIR;
  223. WriteLn('');
  224. WriteLn('Compiling file ' + vProject.MainSource);
  225. WriteLn('');
  226. AProcess.CommandLine := STR_CWUDEB +
  227. ' -o "' + MakeFolder + 'WINSCW\UDEB\' + vProject.MainSourceNoExt + '.o"' +
  228. ' -c "' + MakeFolder + 'src\' + vProject.MainSource + '"';
  229. WriteLn(AProcess.CommandLine);
  230. AProcess.Execute;
  231. { UID File }
  232. BuildUIDFile;
  233. { Linking }
  234. STR_LINK_FLAGSUDEB := '-msgstyle gcc' +
  235. ' -stdlib "' + vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EEXE.LIB"' +
  236. ' -m "?_E32Bootstrap@@YGXXZ" -subsystem windows' +
  237. ' -g ' + vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\EUSER.LIB' +
  238. ' -o "' + vSDKUtil.SDKPartialFolder + 'EPOC32\RELEASE\WINSCW\UDEB\' + vProject.MainSourceNoExt + '.exe"' +
  239. ' -noimplib';
  240. STR_EPOCBLDUDEB := MakeFolder + 'WINSCW\UDEB';
  241. STR_LINK_OBJSUDEB := vProject.MainSourceNoExt + '.o ' + UID_OBJECT_FILENAME;
  242. WriteLn('');
  243. WriteLn('Linking stage');
  244. WriteLn('');
  245. AProcess.CommandLine := 'mwldsym2.exe ' + STR_LINK_FLAGSUDEB +
  246. ' -l ' + STR_EPOCBLDUDEB +
  247. ' -search ' + STR_LINK_OBJSUDEB;
  248. WriteLn(AProcess.CommandLine);
  249. AProcess.Execute;
  250. end;
  251. {*******************************************************************
  252. * TCompiler.MakeBuildBindings ()
  253. *
  254. * DESCRIPTION: Builds and links the C interface for the symbian libraries
  255. *
  256. * Note the we use a output directory relative to the current directory
  257. *
  258. * PARAMETERS: None
  259. *
  260. * RETURNS: Nothing
  261. *
  262. *******************************************************************}
  263. procedure TCompiler.MakeBuildBindings;
  264. var
  265. STR_CWUFLAGS, STR_CWDEFS, STR_INCDIR, STR_CWUDEB, STR_CWCOMPILER: string;
  266. begin
  267. { Makes sure that the output directory exists }
  268. SysUtils.ForceDirectories(BindingsUnitsFolder);
  269. { Compilation }
  270. STR_CWUFLAGS := '-wchar_t off -align 4 -warnings on ' +
  271. '-w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostdinc';
  272. STR_CWDEFS := '-d "__SYMBIAN32__" -d "__CW32__" -d "__WINS__" -d "__WINSCW__" -d "__EXE__" -d "__SUPPORT_CPP_EXCEPTIONS__" ';
  273. STR_INCDIR := '-cwd source -i-' +
  274. ' -i "' + vSDKUtil.SDKPartialFolder + 'EPOC32\include"' +
  275. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant"' +
  276. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant\ "' +
  277. ' -include "UIQ_3.0.hrh"';
  278. STR_CWCOMPILER := vSDKUtil.SDKFolder + Str_Path_CWTools + 'mwccsym2.exe';
  279. STR_CWUDEB := STR_CWCOMPILER + ' -g -O0 -inline off ' + STR_CWUFLAGS + ' -d _DEBUG -d _UNICODE ' + STR_CWDEFS + STR_INCDIR;
  280. WriteLn('');
  281. WriteLn('Compiling file pbeexe.cpp');
  282. WriteLn('');
  283. AProcess.CommandLine := STR_CWUDEB +
  284. ' -o "' + BindingsUnitsFolder + 'pbeexe.o" ' +
  285. '-c "' + MakePartialFolder + 'pbeexe.cpp"';
  286. WriteLn(AProcess.CommandLine);
  287. AProcess.Execute;
  288. end;
  289. {*******************************************************************
  290. * TCompiler.BuildUIDFile ()
  291. *
  292. * DESCRIPTION: Generates and compiles a UID file
  293. *
  294. * PARAMETERS: None
  295. *
  296. * RETURNS: Nothing
  297. *
  298. *******************************************************************}
  299. procedure TCompiler.BuildUIDFile;
  300. var
  301. Str_UIDFile: string;
  302. UIDFile: TFileStream;
  303. STR_CWUFLAGS, STR_CWDEFS, STR_INCDIR, STR_CWUDEB, STR_CWCOMPILER: string;
  304. begin
  305. { First creates the UID file }
  306. WriteLn('');
  307. WriteLn('Creating UID file');
  308. WriteLn('');
  309. Str_UIDFile :=
  310. '// mksymbian-generated uid source file' + LineEnding +
  311. '#include <e32cmn.h>' + LineEnding +
  312. '#pragma data_seg(".SYMBIAN")' + LineEnding +
  313. '__EMULATOR_IMAGE_HEADER2(0x1000007a,' + vProject.UID2 + ',' + vProject.UID3 +
  314. ',EPriorityForeground,0x00000000u,0x00000000u,0x01000001,0,0x00010000,0)' + LineEnding +
  315. '#pragma data_seg()' + LineEnding;
  316. UIDFile := TFileStream.Create(UID_SOURCE_FILENAME, fmCreate);
  317. try
  318. UIDFile.Write(Pointer(Str_UIDFile)^, Length(Str_UIDFile));
  319. finally
  320. UIDFile.Free;
  321. end;
  322. { Compilation }
  323. STR_CWUFLAGS := '-wchar_t off -align 4 -warnings on ' +
  324. '-w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostdinc';
  325. STR_CWDEFS := '-d "__SYMBIAN32__" -d "__CW32__" -d "__WINS__" -d "__WINSCW__" -d "__EXE__" -d "__SUPPORT_CPP_EXCEPTIONS__" ';
  326. STR_INCDIR := '-cwd source -i- ' +
  327. ' -i "' + vSDKUtil.SDKPartialFolder + 'EPOC32\include" ' +
  328. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant" ' +
  329. ' -i "' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant\ "' +
  330. ' -include "UIQ_3.0.hrh"';
  331. STR_CWCOMPILER := vSDKUtil.SDKFolder + Str_Path_CWTools + 'mwccsym2.exe';
  332. STR_CWUDEB := STR_CWCOMPILER + ' -g -O0 -inline off ' + STR_CWUFLAGS + ' -d _DEBUG -d _UNICODE ' + STR_CWDEFS + STR_INCDIR;
  333. WriteLn('');
  334. WriteLn('Compiling file ' + UID_SOURCE_FILENAME);
  335. WriteLn('');
  336. AProcess.CommandLine := STR_CWUDEB +
  337. ' -o "' + MakeFolder + UID_OBJECT_FILENAME + '"' +
  338. ' -c "' + MakeFolder + UID_SOURCE_FILENAME + '"';
  339. WriteLn(AProcess.CommandLine);
  340. AProcess.Execute;
  341. end;
  342. {*******************************************************************
  343. * TCompiler.BuildResource ()
  344. *
  345. * DESCRIPTION: Builds a resource file
  346. *
  347. * PARAMETERS: None
  348. *
  349. * RETURNS: Nothing
  350. *
  351. *******************************************************************}
  352. procedure TCompiler.BuildResource(AFileName: string);
  353. begin
  354. WriteLn('');
  355. WriteLn('Preprocessing resource file: ' + AFileName);
  356. WriteLn('');
  357. AProcess.CommandLine := vSDKUtil.SDKFolder + Str_Path_Cpp +
  358. ' -lang-c++' +
  359. ' -I ' + vSDKUtil.SDKPartialFolder + 'EPOC32\include' +
  360. ' -I ' + vSDKUtil.SDKPartialFolder + 'epoc32\include\variant' +
  361. ' ' + MakeFolder + AFileName +
  362. ' ' + MakeFolder + ChangeFileExt(AFileName, STR_RESOURCE_TMP_EXT);
  363. WriteLn(AProcess.CommandLine);
  364. AProcess.Execute;
  365. WriteLn('');
  366. WriteLn('Building resource file: ' + AFileName);
  367. WriteLn('');
  368. AProcess.CommandLine := vSDKUtil.SDKFolder + Str_Path_RComp +
  369. ' -v -u' +
  370. ' -o"' + MakeFolder + ChangeFileExt(AFileName, STR_RESOURCE_EXT) + '"' +
  371. ' -s"' + MakeFolder + ChangeFileExt(AFileName, STR_RESOURCE_TMP_EXT) + '"';
  372. WriteLn(AProcess.CommandLine);
  373. AProcess.Execute;
  374. end;
  375. {*******************************************************************
  376. * TCompiler.RegisterInEmulator ()
  377. *
  378. * DESCRIPTION: Registers a software in the emulator
  379. * At this point the resource file must already be compiled
  380. *
  381. * PARAMETERS: None
  382. *
  383. * RETURNS: Nothing
  384. *
  385. *******************************************************************}
  386. procedure TCompiler.RegisterInEmulator;
  387. var
  388. StrFrom, StrTo: string;
  389. begin
  390. WriteLn('');
  391. WriteLn('Registering the software on the emulator');
  392. WriteLn('');
  393. StrFrom := MakeFolder + ChangeFileExt(vProject.MainResource, STR_RESOURCE_EXT);
  394. StrTo := vSDKUtil.SDKFolder + Str_Path_Emulator_Registration +
  395. ChangeFileExt(vProject.MainResource, STR_RESOURCE_EXT);
  396. WriteLn('');
  397. WriteLn('Copying file: ', StrFrom);
  398. WriteLn('To: ', StrTo);
  399. WriteLn('');
  400. FileCopy(StrFrom, StrTo);
  401. end;
  402. end.