fpcmake.pp 8.5 KB

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