fpmake.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. {$ifndef ALLPACKAGES}
  2. {$mode objfpc}{$H+}
  3. program fpmake;
  4. uses
  5. {$ifdef unix}cthreads,{$endif} fpmkunit,
  6. sysutils, classes;
  7. {$endif ALLPACKAGES}
  8. const
  9. NoGDBOption: boolean = false;
  10. GDBMIOption: boolean = false;
  11. GDBMI_Disabled: boolean = false;
  12. LLVM_Disabled: boolean = false;
  13. GDBMI_DEFAULT_OSes = [aix, darwin, freebsd, haiku, linux, netbsd, openbsd, solaris, win32, win64];
  14. const
  15. CompilerGitDate : ansistring = '';
  16. procedure ide_check_gdb_availability(Sender: TObject);
  17. procedure GetCompilerGitDate;
  18. var
  19. Cmd : string;
  20. Opts : TStringList;
  21. begin
  22. Cmd:=ExeSearch(AddProgramExtension('git',Defaults.SourceOS),{$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}SysUtils.GetEnvironmentVariable('PATH'));
  23. if Cmd <> '' then
  24. begin
  25. Opts:=TStringList.Create;
  26. try
  27. try
  28. Opts.Add('log');
  29. Opts.Add('-1');
  30. Opts.Add('--pretty=%cd');
  31. Opts.Add('--date=format:%Y/%m/%d');
  32. CompilerGitDate:=Installer.BuildEngine.GetExecuteCommandOutput(Cmd,Opts);
  33. while (length(CompilerGitDate)>0) and (CompilerGitDate[length(CompilerGitDate)] in [#10,#13]) do
  34. SetLength(CompilerGitDate,length(CompilerGitDate)-1);
  35. except
  36. CompilerGitDate:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}SysUtils.GetEnvironmentVariable('COMPDATESTR');
  37. end;
  38. finally
  39. Opts.Free;
  40. end;
  41. end
  42. else
  43. CompilerGitDate:={$IFDEF FPC_DOTTEDUNITS}System.{$ENDIF}SysUtils.GetEnvironmentVariable('COMPDATESTR');
  44. end;
  45. function DetectLibGDBDir: string;
  46. var
  47. SearchPath: string;
  48. const
  49. LibGDBName = 'libgdb.a';
  50. begin
  51. result:='';
  52. // First look for the GDBLIBDIR environment variable
  53. SearchPath := GetEnvironmentVariable('GDBLIBDIR');
  54. if (SearchPath<>'') and DirectoryExists(SearchPath) and FileExists(IncludeTrailingPathDelimiter(SearchPath)+LibGDBName) then
  55. begin
  56. result:=IncludeTrailingPathDelimiter(SearchPath);
  57. exit;
  58. end;
  59. // Search in the default locations
  60. SearchPath := '..'+PathDelim+'libgdb'+PathDelim+OSToString(Defaults.OS)+PathDelim+CPUToString(Defaults.CPU)+PathDelim;
  61. if DirectoryExists(SearchPath) and FileExists(SearchPath+LibGDBName) then
  62. begin
  63. result := SearchPath;
  64. exit;
  65. end;
  66. SearchPath := '..'+PathDelim+'libgdb'+PathDelim+OSToString(Defaults.OS)+PathDelim;
  67. if DirectoryExists(SearchPath) and FileExists(SearchPath+LibGDBName) then
  68. begin
  69. result := SearchPath;
  70. exit;
  71. end;
  72. // No custom libgdb.a found, try using system default library if available
  73. SearchPath := '..'+PathDelim+'lib'+PathDelim;
  74. if DirectoryExists(SearchPath) and FileExists(SearchPath+LibGDBName) then
  75. begin
  76. result := SearchPath;
  77. installer.BuildEngine.Log(vlWarning, 'Using system default libgdb file located in '+Result);
  78. exit;
  79. end;
  80. SearchPath := '..'+PathDelim+'usr'+PathDelim+'lib'+PathDelim;
  81. if DirectoryExists(SearchPath) and FileExists(SearchPath+LibGDBName) then
  82. begin
  83. result := SearchPath;
  84. installer.BuildEngine.Log(vlWarning, 'Using system default libgdb file located in '+Result);
  85. exit;
  86. end;
  87. SearchPath := '..'+PathDelim+'usr'+PathDelim+'local'+PathDelim+'lib'+PathDelim;
  88. if DirectoryExists(SearchPath) and FileExists(SearchPath+LibGDBName) then
  89. begin
  90. result := SearchPath;
  91. installer.BuildEngine.Log(vlWarning, 'Using system default libgdb file located in '+Result);
  92. exit;
  93. end;
  94. end;
  95. var
  96. CompilerDir, GDBLibDir: string;
  97. P: TPackage;
  98. procedure maybe_regenerate_msg_files;
  99. var
  100. cmd, msgfile, msgidxfile, msgtxtfile, fpclang : string;
  101. Opts : TStringList;
  102. begin
  103. msgidxfile:=CompilerDir+PathDelim+'msgidx.inc';
  104. msgtxtfile:=CompilerDir+PathDelim+'msgtxt.inc';
  105. if FileExists(msgidxfile) and FileExists(msgtxtfile) then
  106. Exit;
  107. fpclang:=GetEnvironmentVariable('FPCLANG');
  108. if fpclang='' then
  109. fpclang:='e';
  110. msgfile:=CompilerDir+PathDelim+'msg/error'+fpclang+'.msg';
  111. if not FileExists(msgfile) and (fpclang<>'e') then
  112. begin
  113. fpclang:='e';
  114. msgfile:=CompilerDir+PathDelim+'msg/error'+fpclang+'.msg';
  115. end;
  116. if not FileExists(msgfile) then
  117. Exit;
  118. Cmd:=CompilerDir+PathDelim+AddProgramExtension('msg2inc',Defaults.BuildOS);
  119. if not FileExists(Cmd) then
  120. Cmd:=FileSearch(AddProgramExtension('msg2inc',Defaults.BuildOS),GetEnvironmentVariable('PATH'),False);
  121. if not FileExists(Cmd) then
  122. begin
  123. Installer.BuildEngine.log(vlWarning, 'msg2inc utility not found');
  124. exit;
  125. end;
  126. Opts:=TStringList.Create;
  127. try
  128. Opts.Add(msgfile);
  129. Opts.Add(CompilerDir+PathDelim+'msg');
  130. Opts.Add('msg');
  131. Installer.BuildEngine.log(vlCommand, 'Regenerating msg files');
  132. Installer.BuildEngine.ExecuteCommand(Cmd,Opts);
  133. finally
  134. Opts.Free;
  135. end;
  136. end;
  137. begin
  138. P := sender as TPackage;
  139. with installer do
  140. begin
  141. CompilerDir:=P.Directory +'../../compiler';
  142. maybe_regenerate_msg_files;
  143. if GDBMIOption then
  144. begin
  145. BuildEngine.log(vlCommand, 'Compiling IDE with GDB/MI debugger support, LibGDB is not needed');
  146. P.Options.Add('-dGDBMI');
  147. { AIX also requires -CTsmalltoc for gdbmi }
  148. if Defaults.OS=aix then
  149. P.Options.Add('-CTsmalltoc');
  150. end
  151. else if not (NoGDBOption) then
  152. begin
  153. // Detection of GDB.
  154. GDBLibDir := DetectLibGDBDir;
  155. if GDBLibDir<>'' then
  156. begin
  157. // Include GDB
  158. BuildEngine.log(vlCommand, 'LibGDB was found, build IDE with debugger support');
  159. if FileExists(GDBLibDir+'gdblib.inc') then
  160. begin
  161. P.Options.Add('-dUSE_GDBLIBINC');
  162. P.Options.Add('-I'+GDBLibDir);
  163. end;
  164. P.Options.Add('-Fl'+GDBLibDir);
  165. case Defaults.OS of
  166. win32,
  167. win64 : begin
  168. P.Options.Add('-Xe');
  169. P.Options.Add('-k--allow-multiple-definition');
  170. end;
  171. freebsd : begin
  172. P.Options.Add('-Fl/usr/local/lib');
  173. P.Options.Add('-Xd');
  174. end;
  175. openbsd : begin
  176. P.Options.Add('-Fl/usr/local/lib');
  177. P.Options.Add('-Fl/usr/lib');
  178. P.Options.Add('-Xd');
  179. end;
  180. netbsd : P.Options.Add('-Xd');
  181. linux : P.Options.Add('-Xd');
  182. aix : begin
  183. P.Options.Add('-Xd');
  184. P.Options.Add('-Fl/opt/freeware/lib');
  185. P.Options.Add('-k-bbigtoc');
  186. end;
  187. else
  188. ; // Avoid compiler warning
  189. end; {case}
  190. P.NeedLibc := true;
  191. end
  192. else
  193. begin
  194. BuildEngine.log(vlCommand, 'LibGDB was not found, IDE has no debugger support');
  195. P.Options.Add('-dNODEBUG');
  196. end;
  197. end
  198. else
  199. begin
  200. BuildEngine.log(vlCommand, 'Debugger support disabled');
  201. P.Options.Add('-dNODEBUG');
  202. end;
  203. end;
  204. GetCompilerGitDate;
  205. if (CompilerGitDate<>'') then
  206. P.Options.Add('-DD'+CompilerGitDate);
  207. end;
  208. procedure add_ide_comandlineoptions();
  209. begin
  210. AddCustomFpmakeCommandlineOption('CompilerTarget','Target CPU for the IDE''s compiler');
  211. AddCustomFpmakeCommandlineOption('NoGDB','If value=1 or ''Y'', no GDB support');
  212. AddCustomFpmakeCommandlineOption('NoGDBMI','If value=1 or ''Y'', explicitly disable GDB/MI option');
  213. AddCustomFpmakeCommandlineOption('GDBMI','If value=1 or ''Y'', builds IDE with GDB/MI support (no need for LibGDB)');
  214. AddCustomFpmakeCommandlineOption('NoIDE','If value=1 or ''Y'', the IDE will be skipped');
  215. AddCustomFpmakeCommandlineOption('IDE','If value=1 or ''Y'', the IDE will be build for each target');
  216. AddCustomFpmakeCommandlineOption('LLVM','If value=1 or ''Y'', the Compiler codegenerator will use LLVM');
  217. AddCustomFpmakeCommandlineOption('NoLLVM','If value=1 or ''Y'', ito explicitly disable use of LLVM');
  218. end;
  219. procedure add_ide(const ADirectory: string);
  220. Var
  221. P : TPackage;
  222. T : TTarget;
  223. CompilerTarget : TCpu;
  224. CompilerDir,
  225. s: string;
  226. llvm: boolean;
  227. begin
  228. if SameText(Defaults.SubTarget,'unicodertl') then
  229. exit;
  230. if Defaults.Namespaces then
  231. exit;
  232. With Installer do
  233. begin
  234. s := GetCustomFpmakeCommandlineOptionValue('NoIDE');
  235. if (s='1') or (s='Y') then
  236. Exit;
  237. s := GetCustomFpmakeCommandlineOptionValue('NoGDB');
  238. if (s='1') or (s='Y') then
  239. NoGDBOption := true;
  240. s := GetCustomFpmakeCommandlineOptionValue('NOGDBMI');
  241. if (s='1') or (s='Y') then
  242. GDBMI_Disabled := true;
  243. if not GDBMI_Disabled then
  244. begin
  245. s := GetCustomFpmakeCommandlineOptionValue('GDBMI');
  246. if (s='1') or (s='Y') then
  247. GDBMIOption := true;
  248. if (Defaults.OS in GDBMI_DEFAULT_OSes) then
  249. GDBMIOption := True;
  250. end;
  251. s :=GetCustomFpmakeCommandlineOptionValue('CompilerTarget');
  252. if s <> '' then
  253. CompilerTarget:=StringToCPU(s)
  254. else
  255. CompilerTarget:=Defaults.CPU;
  256. {$ifdef CPULLVM}
  257. llvm:=true;
  258. {$else}
  259. llvm:=false;
  260. {$endif}
  261. s := GetCustomFpmakeCommandlineOptionValue('NOLLVM');
  262. if (s='1') or (s='Y') then
  263. LLVM_Disabled := true;
  264. if LLVM_Disabled then
  265. llvm:=false
  266. else
  267. begin
  268. s:=GetCustomFpmakeCommandlineOptionValue('LLVM');
  269. if (s='1') or (s='Y') then
  270. llvm:=true;
  271. end;
  272. { Only try to build natively }
  273. { or for cross-compile if the resulting executable
  274. does not depend on C libs }
  275. if ((GDBMIOption or NoGDBOption) and
  276. ((Defaults.BuildOS=Defaults.OS) and (Defaults.BuildCPU=Defaults.CPU)
  277. or (Defaults.OS in [go32v2,win32,win64,linux,freebsd])
  278. or not Defaults.SkipCrossPrograms)) or
  279. { This is the list of native targets that can be compiled natively with gdbint packages }
  280. ((((Defaults.BuildOS=Defaults.OS) and (Defaults.BuildCPU=Defaults.CPU)) or
  281. not Defaults.SkipCrossPrograms) and
  282. (Defaults.OS in [go32v2,win32,win64,linux,freebsd,os2,emx,beos,haiku])
  283. ) then
  284. begin
  285. P:=AddPackage('ide');
  286. P.Version:='3.3.1';
  287. {$ifdef ALLPACKAGES}
  288. P.Directory:=ADirectory;
  289. {$endif ALLPACKAGES}
  290. s :=GetCustomFpmakeCommandlineOptionValue('IDE');
  291. if (s='1') or (s='Y') then
  292. P.OSes := AllOSes
  293. else
  294. P.OSes := AllOSes-[darwin];
  295. P.Dependencies.Add('rtl-extra');
  296. P.Dependencies.Add('fv');
  297. P.Dependencies.Add('chm');
  298. { This one is only needed if DEBUG is set }
  299. P.Dependencies.Add('regexpr');
  300. if not (NoGDBOption) and not (GDBMIOption) then
  301. P.Dependencies.Add('gdbint',AllOSes-AllAmigaLikeOSes);
  302. if GDBMIOption then
  303. P.Dependencies.Add('fcl-process');
  304. P.Dependencies.Add('graph',[go32v2]);
  305. P.Dependencies.Add('ami-extra',AllAmigaLikeOSes);
  306. P.SupportBuildModes:=[bmOneByOne];
  307. P.Options.Add('-Ur');
  308. P.Options.Add('-dNOCATCH');
  309. P.Options.Add('-dBrowserCol');
  310. P.Options.Add('-dGDB');
  311. if CompilerTarget=wasm32 then
  312. P.Options.Add('-dNOOPT');
  313. CompilerDir:=P.Directory +'../../compiler';
  314. P.Options.Add('-d'+CPUToString(CompilerTarget));
  315. P.Options.Add('-Fu'+CompilerDir);
  316. P.Options.Add('-Fu'+CompilerDir+'/'+CPUToString(CompilerTarget));
  317. P.Options.Add('-Fu'+CompilerDir+'/targets');
  318. P.Options.Add('-Fu'+CompilerDir+'/systems');
  319. P.Options.Add('-Fi'+CompilerDir+'/'+CPUToString(CompilerTarget));
  320. P.Options.Add('-Fi'+CompilerDir);
  321. if CompilerTarget in [x86_64, i386, i8086] then
  322. P.Options.Add('-Fu'+CompilerDir+'/x86');
  323. if CompilerTarget in [powerpc, powerpc64] then
  324. P.Options.Add('-Fu'+CompilerDir+'/ppcgen');
  325. if CompilerTarget in [arm, aarch64] then
  326. P.Options.Add('-Fu'+CompilerDir+'/armgen');
  327. if CompilerTarget in [sparc, sparc64] then
  328. begin
  329. P.Options.Add('-Fu'+CompilerDir+'/sparcgen');
  330. P.Options.add('-Fi'+CompilerDir+'/sparcgen');
  331. end;
  332. if CompilerTarget in [riscv32, riscv64] then
  333. begin
  334. P.Options.Add('-Fu'+CompilerDir+'/riscv');
  335. end;
  336. if CompilerTarget = mipsel then
  337. P.Options.Add('-Fu'+CompilerDir+'/mips');
  338. if CompilerTarget = loongarch64 then
  339. P.Options.Add('-Fu'+CompilerDir+'/loongarch64');
  340. if llvm then
  341. begin
  342. P.Options.Add('-Fu'+CompilerDir+'/llvm');
  343. P.Options.Add('-Fi'+CompilerDir+'/llvm');
  344. end;
  345. { powerpc64-aix compiled IDE needs -CTsmalltoc option }
  346. if (Defaults.OS=aix) and (Defaults.CPU=powerpc64) then
  347. P.Options.Add('-CTsmalltoc');
  348. { Handle SPECIALLINK environment variable if available }
  349. s:=GetEnvironmentVariable('SPECIALLINK');
  350. if s<>'' then
  351. P.Options.Add(s);
  352. P.Options.Add('-Sg');
  353. P.IncludePath.Add('compiler');
  354. T:=P.Targets.AddProgram('fp.pas');
  355. if CompilerTarget<>Defaults.CPU then
  356. begin
  357. T.SetExeName(AddProgramExtension(CPUToString(CompilerTarget)+'-fp',Defaults.BuildOS));
  358. P.SetUnitsOutputDir(P.GetUnitsOutputDir(Defaults.BuildTarget)+CPUToString(CompilerTarget));
  359. P.Options.Add('-dCROSSGDB');
  360. end;
  361. with T.Dependencies do
  362. begin
  363. AddUnit('compunit');
  364. end;
  365. T:=P.Targets.AddUnit('compunit.pas');
  366. T.Directory:='compiler';
  367. T.Install:=false;
  368. if (OSToString(defaults.OS)=lowercase({$I %FPCTARGETOS%})) and
  369. (CPUToString(defaults.CPU)=lowercase({$I %FPCTARGETCPU%})) then
  370. begin
  371. P.InstallFiles.Add('fp.ans','$(bininstalldir)');
  372. P.InstallFiles.Add('gplprog.pt','$(bininstalldir)');
  373. P.InstallFiles.Add('gplunit.pt','$(bininstalldir)');
  374. P.InstallFiles.Add('program.pt','$(bininstalldir)');
  375. P.InstallFiles.Add('unit.pt','$(bininstalldir)');
  376. P.InstallFiles.Add('cvsco.tdf','$(bininstalldir)');
  377. P.InstallFiles.Add('cvsdiff.tdf','$(bininstalldir)');
  378. P.InstallFiles.Add('cvsup.tdf','$(bininstalldir)');
  379. P.InstallFiles.Add('grep.tdf','$(bininstalldir)');
  380. P.InstallFiles.Add('tpgrep.tdf','$(bininstalldir)');
  381. P.InstallFiles.Add('fp32.ico', [win32, win64], '$(bininstalldir)');
  382. end;
  383. with P.Sources do
  384. begin
  385. AddDoc('readme.ide');
  386. AddSrc('README.txt');
  387. AddSrc('TODO.txt');
  388. AddSrc('fp.ans');
  389. AddSrcFiles('*.tdf',P.Directory);
  390. AddSrcFiles('*.pas',P.Directory,true);
  391. AddSrcFiles('*.inc',P.Directory,true);
  392. AddSrcFiles('*.rc',P.Directory);
  393. AddSrcFiles('*.ico',P.Directory);
  394. AddSrcFiles('*.term',P.Directory);
  395. AddSrcFiles('*.pt',P.Directory);
  396. end;
  397. P.CleanFiles.Add('$(UNITSOUTPUTDIR)ppheap.ppu');
  398. P.CleanFiles.Add('$(UNITSOUTPUTDIR)compiler.ppu');
  399. P.CleanFiles.Add('$(UNITSOUTPUTDIR)comphook.ppu');
  400. P.CleanFiles.Add('$(UNITSOUTPUTDIR)cpuinfo.ppu');
  401. P.CleanFiles.Add('$(UNITSOUTPUTDIR)browcol.ppu');
  402. P.CleanFiles.Add('$(UNITSOUTPUTDIR)ppheap.o');
  403. P.CleanFiles.Add('$(UNITSOUTPUTDIR)compiler.o');
  404. P.CleanFiles.Add('$(UNITSOUTPUTDIR)comphook.o');
  405. P.CleanFiles.Add('$(UNITSOUTPUTDIR)cpuinfo.o');
  406. P.CleanFiles.Add('$(UNITSOUTPUTDIR)browcol.o');
  407. P.BeforeCompileProc:=@ide_check_gdb_availability;
  408. P.NamespaceMap:='namespaces.lst';
  409. end;
  410. end;
  411. end;
  412. {$ifndef ALLPACKAGES}
  413. begin
  414. If Assigned(Installer) and not Defaults.Namespaces then
  415. begin
  416. add_ide_comandlineoptions();
  417. add_ide('');
  418. Installer.Run;
  419. end;
  420. end.
  421. {$endif ALLPACKAGES}