fpmake.pp 15 KB

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