fpcmake.pp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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. begin
  172. Show(V_Verbose,TitleDate);
  173. case ParaMode of
  174. m_None :
  175. Error('No operation specified, see -h for help');
  176. m_Makefile :
  177. ProcessFile_Makefile(fn,aOutputFile);
  178. m_PackageFpc :
  179. ProcessFile_PackageFpc(fn,aOutputFile);
  180. end;
  181. end;
  182. procedure UseMakefilefpc;
  183. var
  184. fn : string;
  185. begin
  186. if FileExists('Makefile.fpc') then
  187. fn:='Makefile.fpc'
  188. else
  189. fn:='makefile.fpc';
  190. ProcessFile(fn,ParaOutputFilename);
  191. end;
  192. procedure UseParameters;
  193. var
  194. i : integer;
  195. begin
  196. for i:=OptInd to ParamCount do
  197. ProcessFile(ParamStr(i),ParaOutputFilename);
  198. end;
  199. Procedure Usage;
  200. {
  201. Print usage and exit.
  202. }
  203. begin
  204. writeln(paramstr(0),': <-pw> [-vqh] [file] [file ...]');
  205. writeln('Operations:');
  206. writeln(' -p Generate Package.fpc');
  207. writeln(' -w Write Makefile');
  208. writeln(' -V Print fpcmake version and exit');
  209. writeln('');
  210. writeln('Options:');
  211. writeln(' -T<target>[,target] Support only specified targets. If "-Tall", all targets are');
  212. writeln(' supported. If omitted only default target is supported');
  213. writeln(' -r Recursively process target directories from Makefile.fpc');
  214. writeln(' -v Be more verbose');
  215. writeln(' -ooutputfile Use outputfile as filename instead of the default Makefile or Package.fpc');
  216. writeln(' -s Skip writing package name');
  217. writeln(' -q Be quiet');
  218. writeln(' -h This help screen');
  219. Halt(0);
  220. end;
  221. procedure printVersion;
  222. begin
  223. writeln (TitleDate);
  224. halt(0);
  225. end;
  226. Procedure ProcessOpts;
  227. {
  228. Process command line opions, and checks if command line options OK.
  229. }
  230. const
  231. ShortOpts = 'pwqrvh?VsT:o:';
  232. var
  233. C : char;
  234. begin
  235. { Reset }
  236. ParaSkipPackageInfo:=False;
  237. ParaMode:=m_Makefile;
  238. ParaVerboseLevel:=v_default;
  239. ParaTargets:=LowerCase({$I %FPCTARGETCPU})+'-'+LowerCase({$I %FPCTARGETOS});
  240. { Parse options }
  241. repeat
  242. c:=Getopt (ShortOpts);
  243. Case C of
  244. EndOfOptions : break;
  245. 'p' : ParaMode:=m_PackageFpc;
  246. 'w' : ParaMode:=m_Makefile;
  247. 'o' : ParaOutputFileName:=OptArg;
  248. 'q' : ParaVerboseLevel:=v_quiet;
  249. 'r' : ParaRecursive:=true;
  250. 's' : ParaSkipPackageInfo:=True;
  251. 'v' : ParaVerboseLevel:=v_verbose;
  252. 'T' : ParaTargets:=OptArg;
  253. '?' : Usage;
  254. 'h' : Usage;
  255. 'V' : printVersion;
  256. end;
  257. until false;
  258. end;
  259. begin
  260. ProcessOpts;
  261. if (OptInd>Paramcount) then
  262. UseMakefilefpc
  263. else
  264. UseParameters;
  265. end.