fpcmake.pp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. {
  2. Copyright (c) 2001 by Peter Vreman
  3. Convert Makefile.fpc to Makefile
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$ifdef fpc}{$mode objfpc}{$endif}
  11. {$H+}
  12. program fpcmake;
  13. { Define to not catch exceptions and output backtraces }
  14. { define NOEXCEPT}
  15. uses
  16. getopts,
  17. sysutils,
  18. fpcmmain,fpcmwr,fpcmpkg, fpcmdic;
  19. type
  20. { Verbosity Level }
  21. TVerboseLevel = (v_Quiet,v_Default,v_Verbose);
  22. { Operation mode }
  23. TMode = (m_None,m_PackageFpc,m_Makefile);
  24. TFPCMakeConsole=class(TFPCMake)
  25. procedure Verbose(lvl:TFPCMakeVerbose;const s:string);override;
  26. end;
  27. var
  28. ParaMode : TMode;
  29. ParaVerboseLevel : TVerboseLevel;
  30. ParaTargets : string;
  31. ParaOutputFileName : string;
  32. ParaRecursive : boolean;
  33. ParaSkipPackageInfo : Boolean;
  34. {*****************************************************************************
  35. Helpers
  36. *****************************************************************************}
  37. procedure Show(lvl:TVerboseLevel;const s:string);
  38. begin
  39. if ParaVerboseLevel>=lvl then
  40. Writeln(s);
  41. end;
  42. procedure Error(const s:string);
  43. begin
  44. Writeln('Error: ',s);
  45. Halt(1);
  46. end;
  47. {*****************************************************************************
  48. TFPCMakeConsole
  49. *****************************************************************************}
  50. procedure TFPCMakeConsole.Verbose(lvl:TFPCMakeVerbose;const s:string);
  51. begin
  52. case lvl of
  53. FPCMakeInfo :
  54. Show(V_Default,' '+VerboseIdent+s);
  55. FPCMakeDebug :
  56. Show(V_Verbose,' '+VerboseIdent+s);
  57. FPCMakeError :
  58. Error(s);
  59. end;
  60. end;
  61. {*****************************************************************************
  62. Makefile output
  63. *****************************************************************************}
  64. procedure ProcessFile_Makefile(const fn:string; const aOutputfile : string);
  65. var
  66. CurrFPCMake : TFPCMakeConsole;
  67. CurrMakefile : TMakefileWriter;
  68. s,s2,Subdirs : string;
  69. c : tcpu;
  70. t : tos;
  71. begin
  72. Show(V_Default,'Processing '+fn);
  73. CurrFPCMake:=nil;
  74. {$ifndef NOEXCEPT}
  75. try
  76. {$endif NOEXCEPT}
  77. { Load Makefile.fpc }
  78. CurrFPCMake:=TFPCMakeConsole.Create(fn);
  79. if ParaTargets<>'' then
  80. CurrFPCMake.SetTargets(ParaTargets);
  81. CurrFPCMake.LoadMakefileFPC;
  82. // CurrFPCMake.Print;
  83. { Add the subdirs }
  84. subdirs:='';
  85. for c:=low(tcpu) to high(tcpu) do
  86. for t:=low(tos) to high(tos) do
  87. if CurrFPCMake.IncludeTargets[c,t] then
  88. begin
  89. s2:=CurrFPCMake.GetTargetVariable(c,t,'target_dirs',true);
  90. repeat
  91. s:=GetToken(s2,' ');
  92. if s='' then
  93. break;
  94. AddTokenNoDup(subdirs,s,' ');
  95. until false;
  96. end;
  97. for c:=low(tcpu) to high(tcpu) do
  98. for t:=low(tos) to high(tos) do
  99. if CurrFPCMake.IncludeTargets[c,t] then
  100. begin
  101. s2:=CurrFPCMake.GetTargetVariable(c,t,'target_exampledirs',true);
  102. repeat
  103. s:=GetToken(s2,' ');
  104. if s='' then
  105. break;
  106. AddTokenNoDup(subdirs,s,' ');
  107. until false;
  108. end;
  109. { Write Makefile }
  110. CurrMakefile:=TMakefileWriter.Create(CurrFPCMake,ExtractFilePath(fn)+aOutputFile);
  111. CurrMakefile.SkipPackageInfo:=ParaSkipPackageInfo;
  112. CurrMakefile.WriteGenericMakefile;
  113. CurrMakefile.Free;
  114. {$ifndef NOEXCEPT}
  115. except
  116. on e : exception do
  117. begin
  118. Error(e.message);
  119. Subdirs:='';
  120. end;
  121. end;
  122. {$endif NOEXCEPT}
  123. CurrFPCMake.Free;
  124. { Process subdirs }
  125. if (Subdirs<>'') and
  126. ParaRecursive then
  127. begin
  128. Show(v_Verbose,'Subdirs found: '+subdirs);
  129. repeat
  130. s:=GetToken(subdirs,' ');
  131. if s='' then
  132. break;
  133. ProcessFile_Makefile(ExtractFilePath(fn)+s+'/Makefile.fpc',aOutputFile);
  134. until false;
  135. end;
  136. end;
  137. {*****************************************************************************
  138. Package.fpc output
  139. *****************************************************************************}
  140. procedure ProcessFile_PackageFpc(const fn:string; const aOutputFile : string);
  141. var
  142. CurrFPCMake : TFPCMakeConsole;
  143. CurrPackageFpc : TPackageFpcWriter;
  144. begin
  145. Show(V_Default,'Processing '+fn);
  146. CurrFPCMake:=nil;
  147. {$ifndef NOEXCEPT}
  148. try
  149. {$endif NOEXCEPT}
  150. { Load Makefile.fpc }
  151. CurrFPCMake:=TFPCMakeConsole.Create(fn);
  152. if ParaTargets<>'' then
  153. CurrFPCMake.SetTargets(ParaTargets);
  154. CurrFPCMake.LoadMakefileFPC;
  155. // CurrFPCMake.Print;
  156. { Write Package.fpc }
  157. CurrPackageFpc:=TPackageFpcWriter.Create(CurrFPCMake,ExtractFilePath(fn)+aOutputFile);
  158. CurrPackageFpc.WritePackageFpc;
  159. CurrPackageFpc.Free;
  160. {$ifndef NOEXCEPT}
  161. except
  162. on e : exception do
  163. begin
  164. Error(e.message);
  165. end;
  166. end;
  167. {$endif NOEXCEPT}
  168. CurrFPCMake.Free;
  169. end;
  170. procedure ProcessFile(const fn:string; const aOutputFile : string);
  171. var
  172. ofn : String;
  173. begin
  174. Show(V_Verbose,TitleDate);
  175. case ParaMode of
  176. m_None :
  177. Error('No operation specified, see -h for help');
  178. m_Makefile :
  179. begin
  180. ofn:=aOutputFile;
  181. if ofn='' then
  182. ofn:='Makefile';
  183. ProcessFile_Makefile(fn,ofn);
  184. end;
  185. m_PackageFpc :
  186. begin
  187. ofn:=aOutputFile;
  188. if ofn='' then
  189. ofn:='Package.fpc';
  190. ProcessFile_PackageFpc(fn,ofn);
  191. end;
  192. end;
  193. end;
  194. procedure UseMakefilefpc;
  195. var
  196. fn : string;
  197. begin
  198. if FileExists('Makefile.fpc') then
  199. fn:='Makefile.fpc'
  200. else
  201. fn:='makefile.fpc';
  202. ProcessFile(fn,ParaOutputFilename);
  203. end;
  204. procedure UseParameters;
  205. var
  206. i : integer;
  207. begin
  208. for i:=OptInd to ParamCount do
  209. ProcessFile(ParamStr(i),ParaOutputFilename);
  210. end;
  211. Procedure Usage;
  212. {
  213. Print usage and exit.
  214. }
  215. begin
  216. writeln(paramstr(0),': <-pw> [-vqh] [file] [file ...]');
  217. writeln('Operations:');
  218. writeln(' -p Generate Package.fpc');
  219. writeln(' -w Write Makefile');
  220. writeln(' -V Print fpcmake version and exit');
  221. writeln('');
  222. writeln('Options:');
  223. writeln(' -T<target>[,target] Support only specified targets. If "-Tall", all targets are');
  224. writeln(' supported. If omitted only default target is supported');
  225. writeln(' -r Recursively process target directories from Makefile.fpc');
  226. writeln(' -v Be more verbose');
  227. writeln(' -ooutputfile Use outputfile as filename instead of the default Makefile or Package.fpc');
  228. writeln(' -s Skip writing package name');
  229. writeln(' -q Be quiet');
  230. writeln(' -h This help screen');
  231. Halt(0);
  232. end;
  233. procedure printVersion;
  234. begin
  235. writeln (TitleDate);
  236. halt(0);
  237. end;
  238. Procedure ProcessOpts;
  239. {
  240. Process command line opions, and checks if command line options OK.
  241. }
  242. const
  243. ShortOpts = 'pwqrvh?VsT:o:';
  244. var
  245. C : char;
  246. begin
  247. { Reset }
  248. ParaSkipPackageInfo:=False;
  249. ParaMode:=m_Makefile;
  250. ParaVerboseLevel:=v_default;
  251. ParaTargets:=LowerCase({$I %FPCTARGETCPU})+'-'+LowerCase({$I %FPCTARGETOS});
  252. { Parse options }
  253. repeat
  254. c:=Getopt (ShortOpts);
  255. Case C of
  256. EndOfOptions : break;
  257. 'p' : ParaMode:=m_PackageFpc;
  258. 'w' : ParaMode:=m_Makefile;
  259. 'o' : ParaOutputFileName:=OptArg;
  260. 'q' : ParaVerboseLevel:=v_quiet;
  261. 'r' : ParaRecursive:=true;
  262. 's' : ParaSkipPackageInfo:=True;
  263. 'v' : ParaVerboseLevel:=v_verbose;
  264. 'T' : ParaTargets:=OptArg;
  265. '?' : Usage;
  266. 'h' : Usage;
  267. 'V' : printVersion;
  268. end;
  269. until false;
  270. end;
  271. begin
  272. ProcessOpts;
  273. if (OptInd>Paramcount) then
  274. UseMakefilefpc
  275. else
  276. UseParameters;
  277. end.