fpcmake.pp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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;
  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. ParaRecursive : boolean;
  32. {*****************************************************************************
  33. Helpers
  34. *****************************************************************************}
  35. procedure Show(lvl:TVerboseLevel;const s:string);
  36. begin
  37. if ParaVerboseLevel>=lvl then
  38. Writeln(s);
  39. end;
  40. procedure Error(const s:string);
  41. begin
  42. Writeln('Error: ',s);
  43. Halt(1);
  44. end;
  45. {*****************************************************************************
  46. TFPCMakeConsole
  47. *****************************************************************************}
  48. procedure TFPCMakeConsole.Verbose(lvl:TFPCMakeVerbose;const s:string);
  49. begin
  50. case lvl of
  51. FPCMakeInfo :
  52. Show(V_Default,' '+VerboseIdent+s);
  53. FPCMakeDebug :
  54. Show(V_Verbose,' '+VerboseIdent+s);
  55. FPCMakeError :
  56. Error(s);
  57. end;
  58. end;
  59. {*****************************************************************************
  60. Makefile output
  61. *****************************************************************************}
  62. procedure ProcessFile_Makefile(const fn:string);
  63. var
  64. CurrFPCMake : TFPCMakeConsole;
  65. CurrMakefile : TMakefileWriter;
  66. s,s2,Subdirs : string;
  67. c : tcpu;
  68. t : tos;
  69. begin
  70. Show(V_Default,'Processing '+fn);
  71. CurrFPCMake:=nil;
  72. {$ifndef NOEXCEPT}
  73. try
  74. {$endif NOEXCEPT}
  75. { Load Makefile.fpc }
  76. CurrFPCMake:=TFPCMakeConsole.Create(fn);
  77. if ParaTargets<>'' then
  78. CurrFPCMake.SetTargets(ParaTargets);
  79. CurrFPCMake.LoadMakefileFPC;
  80. // CurrFPCMake.Print;
  81. { Add the subdirs }
  82. subdirs:='';
  83. for c:=low(tcpu) to high(tcpu) do
  84. for t:=low(tos) to high(tos) do
  85. if CurrFPCMake.IncludeTargets[c,t] then
  86. begin
  87. s2:=CurrFPCMake.GetTargetVariable(c,t,'target_dirs',true);
  88. repeat
  89. s:=GetToken(s2,' ');
  90. if s='' then
  91. break;
  92. AddTokenNoDup(subdirs,s,' ');
  93. until false;
  94. end;
  95. for c:=low(tcpu) to high(tcpu) do
  96. for t:=low(tos) to high(tos) do
  97. if CurrFPCMake.IncludeTargets[c,t] then
  98. begin
  99. s2:=CurrFPCMake.GetTargetVariable(c,t,'target_exampledirs',true);
  100. repeat
  101. s:=GetToken(s2,' ');
  102. if s='' then
  103. break;
  104. AddTokenNoDup(subdirs,s,' ');
  105. until false;
  106. end;
  107. { Write Makefile }
  108. CurrMakefile:=TMakefileWriter.Create(CurrFPCMake,ExtractFilePath(fn)+'Makefile');
  109. CurrMakefile.WriteGenericMakefile;
  110. CurrMakefile.Free;
  111. {$ifndef NOEXCEPT}
  112. except
  113. on e : exception do
  114. begin
  115. Error(e.message);
  116. Subdirs:='';
  117. end;
  118. end;
  119. {$endif NOEXCEPT}
  120. CurrFPCMake.Free;
  121. { Process subdirs }
  122. if (Subdirs<>'') and
  123. ParaRecursive then
  124. begin
  125. Show(v_Verbose,'Subdirs found: '+subdirs);
  126. repeat
  127. s:=GetToken(subdirs,' ');
  128. if s='' then
  129. break;
  130. ProcessFile_Makefile(ExtractFilePath(fn)+s+'/Makefile.fpc');
  131. until false;
  132. end;
  133. end;
  134. {*****************************************************************************
  135. Package.fpc output
  136. *****************************************************************************}
  137. procedure ProcessFile_PackageFpc(const fn:string);
  138. var
  139. CurrFPCMake : TFPCMakeConsole;
  140. CurrPackageFpc : TPackageFpcWriter;
  141. begin
  142. Show(V_Default,'Processing '+fn);
  143. CurrFPCMake:=nil;
  144. {$ifndef NOEXCEPT}
  145. try
  146. {$endif NOEXCEPT}
  147. { Load Makefile.fpc }
  148. CurrFPCMake:=TFPCMakeConsole.Create(fn);
  149. if ParaTargets<>'' then
  150. CurrFPCMake.SetTargets(ParaTargets);
  151. CurrFPCMake.LoadMakefileFPC;
  152. // CurrFPCMake.Print;
  153. { Write Package.fpc }
  154. CurrPackageFpc:=TPackageFpcWriter.Create(CurrFPCMake,ExtractFilePath(fn)+'Package.fpc');
  155. CurrPackageFpc.WritePackageFpc;
  156. CurrPackageFpc.Free;
  157. {$ifndef NOEXCEPT}
  158. except
  159. on e : exception do
  160. begin
  161. Error(e.message);
  162. end;
  163. end;
  164. {$endif NOEXCEPT}
  165. CurrFPCMake.Free;
  166. end;
  167. procedure ProcessFile(const fn:string);
  168. begin
  169. Show(V_Verbose,TitleDate);
  170. case ParaMode of
  171. m_None :
  172. Error('No operation specified, see -h for help');
  173. m_Makefile :
  174. ProcessFile_Makefile(fn);
  175. m_PackageFpc :
  176. ProcessFile_PackageFpc(fn);
  177. end;
  178. end;
  179. procedure UseMakefilefpc;
  180. var
  181. fn : string;
  182. begin
  183. if FileExists('Makefile.fpc') then
  184. fn:='Makefile.fpc'
  185. else
  186. fn:='makefile.fpc';
  187. ProcessFile(fn);
  188. end;
  189. procedure UseParameters;
  190. var
  191. i : integer;
  192. begin
  193. for i:=OptInd to ParamCount do
  194. ProcessFile(ParamStr(i));
  195. end;
  196. Procedure Usage;
  197. {
  198. Print usage and exit.
  199. }
  200. begin
  201. writeln(paramstr(0),': <-pw> [-vqh] [file] [file ...]');
  202. writeln('Operations:');
  203. writeln(' -p Generate Package.fpc');
  204. writeln(' -w Write Makefile');
  205. writeln(' -V Print fpcmake version and exit');
  206. writeln('');
  207. writeln('Options:');
  208. writeln(' -T<target>[,target] Support only specified targets. If "-Tall", all targets are');
  209. writeln(' supported. If omitted only default target is supported');
  210. writeln(' -r Recursively process target directories from Makefile.fpc');
  211. writeln(' -v Be more verbose');
  212. writeln(' -q Be quiet');
  213. writeln(' -h This help screen');
  214. Halt(0);
  215. end;
  216. procedure printVersion;
  217. begin
  218. writeln (TitleDate);
  219. halt(0);
  220. end;
  221. Procedure ProcessOpts;
  222. {
  223. Process command line opions, and checks if command line options OK.
  224. }
  225. const
  226. ShortOpts = 'pwqrvh?VT:';
  227. var
  228. C : char;
  229. begin
  230. { Reset }
  231. ParaMode:=m_Makefile;
  232. ParaVerboseLevel:=v_default;
  233. ParaTargets:=LowerCase({$I %FPCTARGETCPU})+'-'+LowerCase({$I %FPCTARGETOS});
  234. { Parse options }
  235. repeat
  236. c:=Getopt (ShortOpts);
  237. Case C of
  238. EndOfOptions : break;
  239. 'p' : ParaMode:=m_PackageFpc;
  240. 'w' : ParaMode:=m_Makefile;
  241. 'q' : ParaVerboseLevel:=v_quiet;
  242. 'r' : ParaRecursive:=true;
  243. 'v' : ParaVerboseLevel:=v_verbose;
  244. 'T' : ParaTargets:=OptArg;
  245. '?' : Usage;
  246. 'h' : Usage;
  247. 'V' : printVersion;
  248. end;
  249. until false;
  250. end;
  251. begin
  252. ProcessOpts;
  253. if (OptInd>Paramcount) then
  254. UseMakefilefpc
  255. else
  256. UseParameters;
  257. end.