fpmake.pp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. program fpmake;
  2. {$coperators on}
  3. {$mode objfpc}{$H+}
  4. uses
  5. fpmkunit, SysUtils, Classes;
  6. const
  7. AllMyUnixOSes = AllUnixOSes - [Darwin, Haiku];
  8. const
  9. CommonComponents: array[1..10] of String =
  10. (
  11. 'components\chsdet\chsdet.lpk',
  12. 'components\multithreadprocs\multithreadprocslaz.lpk',
  13. 'components\kascrypt\kascrypt.lpk',
  14. 'components\doublecmd\doublecmd_common.lpk',
  15. 'components\Image32\Image32.lpk',
  16. 'components\KASToolBar\kascomp.lpk',
  17. 'components\viewer\viewerpackage.lpk',
  18. 'components\gifanim\pkg_gifanim.lpk',
  19. 'components\synunihighlighter\synuni.lpk',
  20. 'components\virtualterminal\virtualterminal.lpk'
  21. );
  22. CommonPlugins: array[1..9] of String =
  23. (
  24. 'plugins/wcx/base64/src/base64wcx.lpi',
  25. 'plugins/wcx/deb/src/deb.lpi',
  26. 'plugins/wcx/rpm/src/rpm.lpi',
  27. 'plugins/wcx/unrar/src/unrar.lpi',
  28. 'plugins/wcx/zip/src/Zip.lpi',
  29. 'plugins/wdx/rpm_wdx/src/rpm_wdx.lpi',
  30. 'plugins/wdx/deb_wdx/src/deb_wdx.lpi',
  31. 'plugins/wdx/audioinfo/src/AudioInfo.lpi',
  32. 'plugins/wfx/ftp/src/ftp.lpi'
  33. );
  34. UnixPlugins: array[1..4] of String =
  35. (
  36. 'plugins/wcx/cpio/src/cpio.lpi',
  37. 'plugins/wfx/samba/src/samba.lpi',
  38. 'plugins/wlx/WlxMplayer/src/wlxMplayer.lpi',
  39. 'plugins/dsx/DSXLocate/src/DSXLocate.lpi'
  40. );
  41. HaikuPlugins: array[1..1] of String =
  42. (
  43. 'plugins/wcx/cpio/src/cpio.lpi'
  44. );
  45. DarwinPlugins: array[1..2] of String =
  46. (
  47. 'plugins/wcx/cpio/src/cpio.lpi',
  48. 'plugins/wlx/MacPreview/src/MacPreview.lpi'
  49. );
  50. WindowsPlugins: array[1..4] of String =
  51. (
  52. 'plugins\wcx\sevenzip\src\SevenZipWcx.lpi',
  53. 'plugins\wlx\richview\src\richview.lpi',
  54. 'plugins\wlx\preview\src\preview.lpi',
  55. 'plugins\wlx\wmp\src\wmp.lpi'
  56. );
  57. DeleteFiles: array[1..6] of String =
  58. (
  59. 'doublecmd',
  60. 'doublecmd.exe',
  61. 'doublecmd.dbg',
  62. 'doublecmd.zdli',
  63. 'src\doublecmd.res',
  64. 'tools\extractdwrflnfo'
  65. );
  66. var
  67. FLazBuild: String = 'lazbuild';
  68. type
  69. { TDCDefaults }
  70. TDCDefaults = class(TFPCDefaults)
  71. private
  72. FWS: String;
  73. public
  74. procedure CompilerDefaults; override;
  75. property WS: String read FWS write FWS;
  76. end;
  77. { TDCBuildEngine }
  78. TDCBuildEngine = class(TBuildEngine)
  79. end;
  80. { TDCInstaller }
  81. TDCInstaller = class(TCustomInstaller)
  82. private
  83. FLazBuildParams: String;
  84. private
  85. procedure CleanDirectory(const Directory: String);
  86. procedure CleanComponents;
  87. procedure BuildComponents;
  88. procedure CleanPlugins;
  89. procedure BuildPlugins;
  90. procedure Clean; overload;
  91. procedure Build;
  92. function ReadOutputDirectory(const FileName: String): String;
  93. procedure CleanOutputDirectory(const FileName: String);
  94. protected
  95. procedure Clean(AllTargets: boolean); override;
  96. public
  97. constructor Create(AOwner : TComponent); override;
  98. end;
  99. { TDCDefaults }
  100. procedure TDCDefaults.CompilerDefaults;
  101. var
  102. AValue: String;
  103. begin
  104. if Defaults.OS = osNone then
  105. begin
  106. AValue:= GetEnvironmentVariable('OS_TARGET');
  107. if Length(AValue) > 0 then Defaults.OS:= StringToOS(AValue);
  108. end;
  109. if Defaults.CPU = cpuNone then
  110. begin
  111. AValue:= GetEnvironmentVariable('CPU_TARGET');
  112. if Length(AValue) > 0 then Defaults.CPU:= StringToCPU(AValue);
  113. end;
  114. AValue:= GetEnvironmentVariable('LCL_PLATFORM');
  115. if Length(AValue) > 0 then (Defaults as TDCDefaults).FWS:= AValue;
  116. inherited CompilerDefaults;
  117. end;
  118. procedure TDCInstaller.BuildComponents;
  119. var
  120. I: Integer;
  121. Args : String;
  122. begin
  123. for I:= Low(CommonComponents) to High(CommonComponents) do
  124. begin
  125. Args:= SetDirSeparators(CommonComponents[I]) + FLazBuildParams;
  126. BuildEngine.ExecuteCommand(FLazBuild, Args);
  127. end;
  128. end;
  129. procedure TDCInstaller.CleanPlugins;
  130. var
  131. I: Integer;
  132. begin
  133. for I:= Low(CommonPlugins) to High(CommonPlugins) do
  134. begin
  135. CleanOutputDirectory(CommonPlugins[I]);
  136. end;
  137. end;
  138. function TDCInstaller.ReadOutputDirectory(const FileName: String): String;
  139. var
  140. I: Integer;
  141. AFile: TStringList;
  142. begin
  143. try
  144. AFile:= TStringList.Create;
  145. try
  146. AFile.LoadFromFile(SetDirSeparators(FileName));
  147. I:= Pos('UnitOutputDirectory Value', AFile.Text);
  148. if I = 0 then Exit;
  149. Result:= Copy(AFile.Text, I + 27, MaxInt);
  150. I:= Pos('"', Result);
  151. if I = 0 then Exit;
  152. Result:= ExtractFilePath(FileName) + Copy(Result, 1, I - 1);
  153. Result:= StringReplace(Result, '$(TargetOS)', OSToString(Defaults.OS), [rfReplaceAll, rfIgnoreCase]);
  154. Result:= StringReplace(Result, '$(TargetCPU)', CPUToString(Defaults.CPU), [rfReplaceAll, rfIgnoreCase]);
  155. Result:= SetDirSeparators(Result);
  156. finally
  157. AFile.Free;
  158. end;
  159. except
  160. Result:= EmptyStr;
  161. end;
  162. end;
  163. procedure TDCInstaller.CleanOutputDirectory(const FileName: String);
  164. begin
  165. CleanDirectory(ReadOutputDirectory(FileName));
  166. end;
  167. procedure TDCInstaller.Clean(AllTargets: boolean);
  168. begin
  169. // Clean components
  170. CleanComponents;
  171. // Clean plugins
  172. CleanPlugins;
  173. // Clean Double Commander
  174. Clean;
  175. end;
  176. constructor TDCInstaller.Create(AOwner: TComponent);
  177. begin
  178. Defaults:= TDCDefaults.Create;
  179. Defaults.IgnoreInvalidOptions:= True;
  180. inherited Create(AOwner);
  181. end;
  182. procedure TDCInstaller.BuildPlugins;
  183. var
  184. I: Integer;
  185. begin
  186. for I:= Low(CommonPlugins) to High(CommonPlugins) do
  187. BuildEngine.ExecuteCommand(FLazBuild, SetDirSeparators(CommonPlugins[I]) + FLazBuildParams);
  188. if Defaults.OS in AllMyUnixOSes then
  189. begin
  190. for I:= Low(UnixPlugins) to High(UnixPlugins) do
  191. BuildEngine.ExecuteCommand(FLazBuild, SetDirSeparators(UnixPlugins[I]) + FLazBuildParams);
  192. end;
  193. if Defaults.OS = Haiku then
  194. begin
  195. for I:= Low(HaikuPlugins) to High(HaikuPlugins) do
  196. BuildEngine.ExecuteCommand(FLazBuild, SetDirSeparators(HaikuPlugins[I]) + FLazBuildParams);
  197. end;
  198. if Defaults.OS = Darwin then
  199. begin
  200. for I:= Low(DarwinPlugins) to High(DarwinPlugins) do
  201. BuildEngine.ExecuteCommand(FLazBuild, SetDirSeparators(DarwinPlugins[I]) + FLazBuildParams);
  202. end;
  203. if Defaults.OS in AllWindowsOSes then
  204. begin
  205. for I:= Low(WindowsPlugins) to High(WindowsPlugins) do
  206. BuildEngine.ExecuteCommand(FLazBuild, SetDirSeparators(WindowsPlugins[I]) + FLazBuildParams);
  207. end;
  208. end;
  209. procedure TDCInstaller.Clean;
  210. const
  211. OutputPath = 'units' + PathDelim;
  212. var
  213. I: Integer;
  214. AInfo : TSearchRec;
  215. begin
  216. // Clean output directories
  217. if FindFirst(OutputPath + AllFilesMask, faAnyFile - faHidden, AInfo) = 0 then
  218. repeat
  219. if ((AInfo.Attr and faDirectory) = faDirectory) and (AInfo.Name <> '.') and (AInfo.Name <> '..') then
  220. CleanDirectory(OutputPath + AInfo.Name);
  221. until FindNext(AInfo) <> 0;
  222. FindClose(AInfo);
  223. TDCBuildEngine(BuildEngine).SysDeleteTree('tools' + PathDelim + 'lib');
  224. // Clean files
  225. for I:= Low(DeleteFiles) to High(DeleteFiles) do
  226. TDCBuildEngine(BuildEngine).SysDeleteFile(SetDirSeparators(DeleteFiles[I]));
  227. // Clean debug directory
  228. if Defaults.OS = Darwin then
  229. begin
  230. TDCBuildEngine(BuildEngine).SysDeleteTree('doublecmd.dSYM');
  231. end;
  232. // Clean fpmake output files
  233. TDCBuildEngine(BuildEngine).SysDeleteFile('fpmake.o');
  234. end;
  235. procedure TDCInstaller.Build;
  236. begin
  237. // Build components
  238. BuildComponents;
  239. // Build plugins
  240. BuildPlugins;
  241. // Set default build mode
  242. if Pos('--bm=', FLazBuildParams) = 0 then
  243. FLazBuildParams+= ' --bm=release';
  244. // Build Double Commander
  245. BuildEngine.ExecuteCommand(FLazBuild, SetDirSeparators('src/doublecmd.lpi') + FLazBuildParams);
  246. if Pos('--bm=release', FLazBuildParams) > 0 then
  247. begin
  248. // Build Dwarf LineInfo Extractor
  249. BuildEngine.ExecuteCommand(FLazBuild, SetDirSeparators('tools/extractdwrflnfo.lpi'));
  250. // Extract debug line info
  251. if Defaults.OS = Darwin then
  252. begin
  253. BuildEngine.CmdRenameFile('doublecmd.dSYM/Contents/Resources/DWARF/doublecmd', 'doublecmd.dbg');
  254. end;
  255. BuildEngine.ExecuteCommand(SetDirSeparators('tools/extractdwrflnfo'), 'doublecmd.dbg');
  256. end;
  257. end;
  258. procedure TDCInstaller.CleanDirectory(const Directory: String);
  259. var
  260. List: TStrings;
  261. begin
  262. List:= TStringList.Create;
  263. try
  264. SearchFiles(IncludeTrailingPathDelimiter(Directory) + AllFilesMask, EmptyStr, False, List);
  265. BuildEngine.CmdDeleteFiles(List);
  266. finally
  267. List.Free;
  268. end;
  269. end;
  270. procedure TDCInstaller.CleanComponents;
  271. var
  272. I: Integer;
  273. begin
  274. for I:= Low(CommonComponents) to High(CommonComponents) do
  275. begin
  276. CleanOutputDirectory(CommonComponents[I]);
  277. end;
  278. end;
  279. var
  280. I: Integer;
  281. var
  282. OptArg: String;
  283. BuildTarget: String;
  284. begin
  285. AddCustomFpmakeCommandlineOption('bm', 'Override the project build mode.');
  286. AddCustomFpmakeCommandlineOption('ws', 'Override the project widgetset, e.g. gtk2 qt qt5 win32 cocoa.');
  287. with Installer(TDCInstaller) as TDCInstaller do
  288. begin
  289. CreateBuildEngine;
  290. BuildTarget:= ParamStr(1);
  291. FLazBuildParams:= ' --os=' + OSToString(Defaults.OS);
  292. FLazBuildParams+= ' --cpu=' + CPUToString(Defaults.CPU);
  293. if BuildTarget = 'clean' then
  294. begin
  295. Clean(True);
  296. Exit;
  297. end;
  298. for I:= 0 to ParamCount do WriteLn(ParamStr(I));
  299. OptArg:= GetCustomFpmakeCommandlineOptionValue('bm');
  300. if Length(OptArg) > 0 then begin
  301. FLazBuildParams+= ' --bm=' + OptArg;
  302. end;
  303. OptArg:= GetCustomFpmakeCommandlineOptionValue('ws');
  304. if Length(OptArg) > 0 then begin
  305. FLazBuildParams+= ' --ws=' + OptArg;
  306. end;
  307. if (Defaults.HaveOptions) then begin
  308. FLazBuildParams+= ' ' + TDCDefaults(Defaults).CmdLineOptions;
  309. end;
  310. if BuildEngine.Verbose then begin
  311. FLazBuildParams+= ' --verbose';
  312. end;
  313. if (Pos('--ws', FLazBuildParams) = 0) and (Length((Defaults as TDCDefaults).WS) > 0) then
  314. FLazBuildParams+= ' --ws=' + (Defaults as TDCDefaults).WS;
  315. WriteLn(FLazBuildParams);
  316. if BuildTarget = 'components' then
  317. BuildComponents
  318. else if BuildTarget = 'plugins' then
  319. BuildPlugins
  320. else
  321. Build;
  322. end;
  323. end.