fpmake.pp 9.5 KB

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