compiler.pas 16 KB

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