fpmake.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. {$mode objfpc}{$H+}
  2. program fpmake;
  3. uses {$ifdef unix}cthreads,{$endif} sysutils, fpmkunit;
  4. function FilenameIsAbsolute(const TheFilename: string):boolean;
  5. begin
  6. {$IFDEF WINDOWS}
  7. // windows
  8. Result:=((length(TheFilename)>=2) and (TheFilename[1] in ['A'..'Z','a'..'z'])
  9. and (TheFilename[2]=':'))
  10. or ((length(TheFilename)>=2)
  11. and (TheFilename[1]='\') and (TheFilename[2]='\'));
  12. {$ELSE}
  13. // unix
  14. Result:=(TheFilename<>'') and (TheFilename[1]='/');
  15. {$ENDIF}
  16. end;
  17. Procedure CreateNamespacedConfigFile(CfgFile : string);
  18. var
  19. F : Text;
  20. Procedure AddLn(S : String);
  21. begin
  22. Writeln(F,S);
  23. end;
  24. begin
  25. if not ForceDirectories(ExtractFilePath(CfgFile)) then
  26. begin
  27. Writeln(StdErr,'Could not create destination directory ',ExtractFilePath(CfgFile));
  28. Halt(2);
  29. end;
  30. Assign(F,CfgFile);
  31. try
  32. Rewrite(F);
  33. except
  34. On E : exception do
  35. begin
  36. Writeln(StdErr,'Could not create config file ',CfgFile,' : ',E.Message);
  37. Halt(3);
  38. end;
  39. end;
  40. AddLn('-dUNICODERTL');
  41. Close(F);
  42. end;
  43. Procedure CreateConfigFile(CfgFile,BaseDir : String; rtl_js_dir: string = '');
  44. Var
  45. F : Text;
  46. Procedure AddLn(S : String);
  47. begin
  48. Writeln(F,S);
  49. end;
  50. Procedure AddPath(const aPrefix,aDir,Suffix : String);
  51. var
  52. aSubDir : String;
  53. begin
  54. aSubDir:=aDir;
  55. if Suffix<>'' then
  56. aSubDir:=aSubDir+Suffix;
  57. if not FilenameIsAbsolute(aDir) then
  58. aSubDir:='$CfgDir'+PathDelim+aSubDir;
  59. Addln(aPrefix+aSubDir);
  60. end;
  61. begin
  62. if not ForceDirectories(ExtractFilePath(CfgFile)) then
  63. begin
  64. Writeln(StdErr,'Could not create destination directory ',ExtractFilePath(CfgFile));
  65. Halt(2);
  66. end;
  67. Assign(F,CfgFile);
  68. try
  69. Rewrite(F);
  70. except
  71. On E : exception do
  72. begin
  73. Writeln(StdErr,'Could not create config file ',CfgFile,' : ',E.Message);
  74. Halt(3);
  75. end;
  76. end;
  77. if (BaseDir<>'') then
  78. BaseDir:=IncludeTrailingPathDelimiter(BaseDir);
  79. Addln('#');
  80. Addln('# Minimal config file for pas2js compiler');
  81. Addln('#');
  82. Addln('# -d is the same as #DEFINE');
  83. Addln('# -u is the same as #UNDEF');
  84. Addln('#');
  85. Addln('# Write always a nice logo ;)');
  86. Addln('-l');
  87. Addln('');
  88. Addln('# Display Warnings, Notes and Hints');
  89. Addln('-vwnh');
  90. Addln('# If you don''t want so much verbosity use');
  91. Addln('#-vw');
  92. Addln('');
  93. Addln('# Allow C-operators');
  94. Addln('-Sc');
  95. Addln('');
  96. Addln('#IFDEF FPC_SUBTARGET_NAMESPACED');
  97. AddPath('-Fu',BaseDir,'*/namespaced');
  98. AddPath('-Fi',BaseDir,'*/src');
  99. AddLn('#else');
  100. AddPath('-Fu',BaseDir,'*/src');
  101. AddLn('#endif');
  102. if rtl_js_dir<>'' then
  103. AddPath('-Fu',rtl_js_dir,'');
  104. Addln('');
  105. Addln('#IFDEF nodejs');
  106. Addln('-Jirtl.js');
  107. Addln('#ENDIF');
  108. Addln('');
  109. Addln('# Put all generated JavaScript into one file');
  110. Addln('-Jc');
  111. Addln('');
  112. Addln('# end.');
  113. Close(F);
  114. end;
  115. Procedure AddInstallFiles(Files : TConditionalDestStrings; ADir,AllowedExt,APrefix : String);
  116. Var
  117. Info : TSearchRec;
  118. ADestDir,E : String;
  119. P : Integer;
  120. begin
  121. ADestDir:=ADir;
  122. P:=Pos(PathDelim,ADestDir);
  123. if (P>0) then
  124. Delete(ADestDir,1,P);
  125. ADir:=IncludeTrailingPathDelimiter(ADir);
  126. ADestDir:=IncludeTrailingPathDelimiter(ADestDir);
  127. if FindFirst(aDir+AllFilesMask,0,Info)=0 then
  128. try
  129. Repeat
  130. E:=LowerCase(ExtractFileExt(Info.Name));
  131. if pos(E,AllowedExt)>0 then
  132. Files.Add(ADir+Info.Name,aPrefix+ADestDir);
  133. until (FindNext(Info)<>0);
  134. finally
  135. FindClose(Info);
  136. end;
  137. end;
  138. Procedure AddPackageFiles(Files : TConditionalDestStrings; ADir,APrefix : String);
  139. Const
  140. PackExt = '.pp.pas.inc.lpk';
  141. begin
  142. AddInstallFiles(Files,'packages'+PathDelim+ADir+PathDelim+'src',packExt,aPrefix);
  143. AddInstallFiles(Files,'packages'+PathDelim+ADir+PathDelim+'namespaced',packExt,aPrefix);
  144. end;
  145. Procedure AddDemoFiles(Files : TConditionalDestStrings; ADir,APrefix : String);
  146. Const
  147. DemoExt = '.pp.pas.inc.lpr.lpi.html.md.css';
  148. begin
  149. AddInstallFiles(Files,'demo'+PathDelim+ADir,demoExt,APrefix);
  150. end;
  151. const
  152. demos : Array of string = (
  153. 'apiclient','asyncawait','atom','bootstrap','chartjs','css','dataabstract',
  154. 'datamodule','datatables','debugcapture','design','dynload','electron',
  155. 'errorhandler','extend_jsclass','fcldb','fpcunit','fpreport','fullcalendar',
  156. 'hotreload','jitsimeet','jquery','jspdf','kurento','library','modules',
  157. 'nodehttpserver','opentok','pacman','player','promise','pushjs','pwa',
  158. 'regexp','resources','restbridge','router','rtl','scratch','templates',
  159. 'testinsight','tetris','tinyeditor','translate','ts2pas','uselibpas2js',
  160. 'vscode','wasienv','webcompiler','webgl','websockets','webwidget/designdemo',
  161. 'webwidget/nativedesign', 'webwidget/widgets','xterm','zenfs' );
  162. Var
  163. P : TPackage;
  164. aDemo, UnitDir,DemoDir,BD, TmpCfg, TmpCfg2: String;
  165. {$IF FPC_FULLVERSION>=30301}
  166. T: TTarget;
  167. {$ENDIF}
  168. FPCSrcDir, Pas2jsOFilename, RTLJSFilename: String;
  169. begin
  170. FPCSrcDir:=GetEnvironmentVariable('FPCDIR');
  171. if FPCSrcDir<>'' then
  172. FPCSrcDir:=IncludeTrailingPathDelimiter(ExpandFileName(FPCSrcDir));
  173. if FPCSrcDir='' then
  174. FPCSrcDir:=IncludeTrailingPathDelimiter(GetCurrentDir)+'compiler'+PathDelim;
  175. With Installer do
  176. begin
  177. P:=AddPackage('pas2js');
  178. P.Author := 'Free Pascal Team';
  179. P.License := 'LGPL with modification';
  180. P.HomepageURL := 'www.freepascal.org';
  181. P.Description := 'Convert pascal sources to javascript.';
  182. P.Email := '[email protected]';
  183. P.NeedLibC:= false;
  184. P.Version:='3.3.1';
  185. P.SourcePath.Add(FPCSrcDir+'utils/pas2js');
  186. P.UnitPath.Add(FPCSrcDir+'utils/pas2js');
  187. P.UnitPath.Add(FPCSrcDir+'packages/pastojs/src');
  188. P.UnitPath.Add(FPCSrcDir+'packages/fcl-passrc/src');
  189. P.UnitPath.Add(FPCSrcDir+'packages/fcl-js/src');
  190. P.UnitPath.Add(FPCSrcDir+'packages/fcl-json/src');
  191. {$IF FPC_FULLVERSION>=30301}
  192. P.UnitPath.Add(FPCSrcDir+'packages/fcl-base/src');
  193. P.UnitPath.Add(FPCSrcDir+'packages/fcl-web/src/base');
  194. P.UnitPath.Add(FPCSrcDir+'packages/fcl-net/src');
  195. P.IncludePath.Add(FPCSrcDir+'packages/fcl-net/src/unix',AllUnixOSes);
  196. P.IncludePath.Add(FPCSrcDir+'packages/fcl-net/src/win',AllWindowsOSes);
  197. P.IncludePath.Add(FPCSrcDir+'packages/fcl-net/src/os2',[EMX]);
  198. P.IncludePath.Add(FPCSrcDir+'packages/fcl-net/src/amiga',[morphos]);
  199. P.IncludePath.Add(FPCSrcDir+'packages/fcl-net/src/$(OS)',AllOSes-AllWindowsOSes-AllUnixOSes-[EMX]);
  200. P.UnitPath.Add(FPCSrcDir+'packages/fcl-base/src');
  201. P.IncludePath.Add(FPCSrcDir+'packages/fcl-base/src/dummy');
  202. P.UnitPath.Add(FPCSrcDir+'packages/webidl/src');
  203. {$ENDIF}
  204. P.IncludePath.Add(FPCSrcDir+'packages/pastojs/src');
  205. P.Dependencies.Clear;
  206. Defaults.Options.Add('-Sc');
  207. P.Targets.AddProgram('pas2js.pp');
  208. {$IF FPC_FULLVERSION>=30301}
  209. P.Targets.AddProgram('webidl2pas.pp');
  210. T:=P.Targets.AddProgram('compileserver.pp');
  211. T.OSes:=AllUnixOSes+AllWindowsOSES;
  212. P.Targets.AddProgram('makestub.pp');
  213. T:=P.Targets.AddLibrary('pas2jslib.pp');
  214. if Defaults.OS=Linux then
  215. T.SetExeName('libpas2js.so');
  216. {$ENDIF}
  217. P.Targets.AddImplicitUnit('fpjson',False).ResourceStrings:=True;
  218. P.Targets.AddImplicitUnit('fppas2js',False).ResourceStrings:=True;
  219. P.Targets.AddImplicitUnit('fppjssrcmap',False);
  220. P.Targets.AddImplicitUnit('jsbase',False);
  221. P.Targets.AddImplicitUnit('jsonparser',False).ResourceStrings:=True;
  222. P.Targets.AddImplicitUnit('jsonreader',False).ResourceStrings:=True;
  223. P.Targets.AddImplicitUnit('jsonscanner',False).ResourceStrings:=True;
  224. P.Targets.AddImplicitUnit('jssrcmap',False);
  225. P.Targets.AddImplicitUnit('jstoken',False);
  226. P.Targets.AddImplicitUnit('jstree',False);
  227. P.Targets.AddImplicitUnit('jswriter',False).ResourceStrings:=True;
  228. P.Targets.AddImplicitUnit('pas2jscompiler',False);
  229. P.Targets.AddImplicitUnit('pas2jslogger',False);
  230. P.Targets.AddImplicitUnit('pas2jspparser',False);
  231. P.Targets.AddImplicitUnit('pas2jsuseanalyzer',False);
  232. P.Targets.AddImplicitUnit('pas2jsfs',False);
  233. P.Targets.AddImplicitUnit('pas2jsfilecache',False);
  234. P.Targets.AddImplicitUnit('pas2jsfileutils',False);
  235. P.Targets.AddImplicitUnit('pas2jslibcompiler',False);
  236. P.Targets.AddImplicitUnit('pas2jsfscompiler',False);
  237. P.Targets.AddImplicitUnit('pas2jscompilercfg',False);
  238. P.Targets.AddImplicitUnit('pas2jscompilerpp',False);
  239. P.Targets.AddImplicitUnit('pas2jsutils',False);
  240. P.Targets.AddImplicitUnit('pasresolveeval',False).ResourceStrings:=True;
  241. P.Targets.AddImplicitUnit('pasresolver',False);
  242. P.Targets.AddImplicitUnit('pastree',False).ResourceStrings:=True;
  243. P.Targets.AddImplicitUnit('pasuseanalyzer',False);
  244. P.Targets.AddImplicitUnit('pparser',False).ResourceStrings:=True;
  245. P.Targets.AddImplicitUnit('pscanner',False).ResourceStrings:=True;
  246. P.Targets.AddImplicitUnit('pascodegen.o',False);
  247. {$IF FPC_FULLVERSION>=30301}
  248. P.Targets.AddImplicitUnit('webidldefs',False).ResourceStrings:=True;
  249. P.Targets.AddImplicitUnit('webidlscanner',False).ResourceStrings:=True;
  250. P.Targets.AddImplicitUnit('webidlparser',False).ResourceStrings:=True;
  251. P.Targets.AddImplicitUnit('webidltopas',False).ResourceStrings:=True;
  252. {$ENDIF}
  253. P.Targets.AddImplicitUnit('stubcreator',False).ResourceStrings:=True;
  254. // Determine unit files location
  255. {$IF DECLARED(TCompileTarget)}
  256. BD:=IncludeTrailingPathDelimiter(P.GetBinOutputDir(Defaults.BuildTarget));
  257. {$ELSE}
  258. BD:=IncludeTrailingPathDelimiter(P.GetBinOutputDir(Defaults.BuildCPU,Defaults.BuildOS));
  259. {$ENDIF}
  260. TmpCfg:=FPCSrcDir+'utils/pas2js/dist/pas2js.cfg';
  261. TmpCfg2:=FPCSrcDir+'utils/pas2js/dist/pas2js-namespaced.cfg';
  262. Case Installer.RunMode of
  263. rmCompile,rmBuild:
  264. begin
  265. RTLJSFilename:=SetDirSeparators(FPCSrcDir+'utils/pas2js/dist/');
  266. RTLJSFilename:=ExtractRelativePath(ExpandFileName(BD),RTLJSFilename);
  267. if not FileExists(BD+'pas2js.cfg') then
  268. CreateConfigFile(BD+'pas2js.cfg',SetDirSeparators('../../packages'),RTLJSFilename);
  269. if not FileExists(BD+'pas2js-namespaced.cfg') then
  270. CreateNameSpacedConfigFile(BD+'pas2js-namespaced.cfg');
  271. end;
  272. rmInstall,rmArchive,rmZipInstall:
  273. begin
  274. // UnitDir = some\path\units\i386-win32\..\..\..\pas2js\
  275. UnitDir:=ExcludeTrailingPathDelimiter(Defaults.UnitInstallDir);
  276. UnitDir:=ExcludeTrailingPathDelimiter(ExtractFilePath(UnitDir));
  277. UnitDir:=ExcludeTrailingPathDelimiter(ExtractFilePath(UnitDir));
  278. UnitDir:=ExtractFilePath(UnitDir);
  279. UnitDir:=UnitDir+'pas2js'+PathDelim;
  280. RTLJSFilename:=ExtractRelativePath(IncludeTrailingPathDelimiter(Defaults.BinInstallDir),
  281. UnitDir+'rtl'+PathDelim);
  282. // Config file
  283. // Create config file
  284. CreateConfigFile(TmpCfg,
  285. ExtractRelativePath(IncludeTrailingPathDelimiter(Defaults.BinInstallDir),
  286. UnitDir),RTLJSFilename);
  287. CreateNamespacedConfigFile(TmpCfg2);
  288. P.InstallFiles.Add(TmpCfg,Defaults.BinInstallDir);
  289. P.InstallFiles.Add(TmpCfg2,Defaults.BinInstallDir);
  290. P.InstallFiles.Add(FPCSrcDir+'utils/pas2js/dist/rtl.js',IncludeTrailingPathDelimiter(UnitDir)+'rtl');
  291. AddPackageFiles(P.InstallFiles,'chartjs',UnitDir);
  292. AddPackageFiles(P.InstallFiles,'dataabstract',UnitDir);
  293. AddPackageFiles(P.InstallFiles,'fcl-base',UnitDir);
  294. AddPackageFiles(P.InstallFiles,'fcl-db',UnitDir);
  295. AddPackageFiles(P.InstallFiles,'fcl-json',UnitDir);
  296. AddPackageFiles(P.InstallFiles,'fpcunit',UnitDir);
  297. AddPackageFiles(P.InstallFiles,'jspdf',UnitDir);
  298. AddPackageFiles(P.InstallFiles,'nodejs',UnitDir);
  299. AddPackageFiles(P.InstallFiles,'rtl',UnitDir);
  300. AddPackageFiles(P.InstallFiles,'atom',UnitDir);
  301. AddPackageFiles(P.InstallFiles,'job',UnitDir);
  302. AddPackageFiles(P.InstallFiles,'pushjs',UnitDir);
  303. AddPackageFiles(P.InstallFiles,'wasi',UnitDir);
  304. AddPackageFiles(P.InstallFiles,'bootstrap',UnitDir);
  305. AddPackageFiles(P.InstallFiles,'fullcalendar',UnitDir);
  306. AddPackageFiles(P.InstallFiles,'datatables',UnitDir);
  307. AddPackageFiles(P.InstallFiles,'pdfjs',UnitDir);
  308. AddPackageFiles(P.InstallFiles,'fcl-rpc',UnitDir);
  309. AddPackageFiles(P.InstallFiles,'bulma',UnitDir);
  310. AddPackageFiles(P.InstallFiles,'electron',UnitDir);
  311. AddPackageFiles(P.InstallFiles,'htmlfragment',UnitDir);
  312. AddPackageFiles(P.InstallFiles,'opentok',UnitDir);
  313. AddPackageFiles(P.InstallFiles,'tinyeditor',UnitDir);
  314. AddPackageFiles(P.InstallFiles,'xterm',UnitDir);
  315. AddPackageFiles(P.InstallFiles,'flatpickr',UnitDir);
  316. AddPackageFiles(P.InstallFiles,'jitsimeet',UnitDir);
  317. AddPackageFiles(P.InstallFiles,'kurento',UnitDir);
  318. AddPackageFiles(P.InstallFiles,'vscode',UnitDir);
  319. AddPackageFiles(P.InstallFiles,'webwidget',UnitDir);
  320. AddPackageFiles(P.InstallFiles,'zenfs',UnitDir);
  321. AddPackageFiles(P.InstallFiles,'wasm-utils',UnitDir);
  322. AddPackageFiles(P.InstallFiles,'wasm-oi',UnitDir);
  323. // Demo files
  324. DemoDir:=IncludeTrailingPathDelimiter(Defaults.ExamplesInstallDir);
  325. For aDemo in Demos do
  326. AddDemoFiles(P.InstallFiles,aDemo,DemoDir);
  327. end;
  328. rmClean:
  329. begin
  330. P.CleanFiles.Add(TmpCfg);
  331. // workaround for fpc bug 40602: delete pas2js.o in FPCDIR
  332. Pas2jsOFilename:=FPCSrcDir+SetDirSeparators('utils/pas2js/units/'+Defaults.Target+'/pas2js.o');
  333. if FileExists(Pas2jsOFilename) then
  334. if not DeleteFile(Pas2jsOFilename) then
  335. begin
  336. writeln('Unable to delete "'+Pas2jsOFilename+'"');
  337. Halt(3);
  338. end;
  339. end;
  340. rmDistClean:
  341. if FileExists(BD+'pas2js.cfg') then
  342. P.CleanFiles.Add(BD+'pas2js.cfg');
  343. end;
  344. Run;
  345. end;
  346. end.