fpcmake.pp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. t : ttarget;
  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:=CurrFPCMake.GetVariable('target_dirs',true);
  83. for t:=low(ttarget) to high(ttarget) do
  84. if t in CurrFPCMake.IncludeTargets then
  85. begin
  86. s2:=CurrFPCMake.GetVariable('target_dirs'+targetsuffix[t],true);
  87. repeat
  88. s:=GetToken(s2,' ');
  89. if s='' then
  90. break;
  91. AddTokenNoDup(subdirs,s,' ');
  92. until false;
  93. end;
  94. AddToken(subdirs,CurrFPCMake.GetVariable('target_exampledirs',true),' ');
  95. for t:=low(ttarget) to high(ttarget) do
  96. if t in CurrFPCMake.IncludeTargets then
  97. begin
  98. s2:=CurrFPCMake.GetVariable('target_exampledirs'+targetsuffix[t],true);
  99. repeat
  100. s:=GetToken(s2,' ');
  101. if s='' then
  102. break;
  103. AddTokenNoDup(subdirs,s,' ');
  104. until false;
  105. end;
  106. { Write Makefile }
  107. CurrMakefile:=TMakefileWriter.Create(CurrFPCMake,ExtractFilePath(fn)+'Makefile');
  108. CurrMakefile.WriteGenericMakefile;
  109. CurrMakefile.Free;
  110. {$ifndef NOEXCEPT}
  111. except
  112. on e : exception do
  113. begin
  114. Error(e.message);
  115. Subdirs:='';
  116. end;
  117. end;
  118. {$endif NOEXCEPT}
  119. CurrFPCMake.Free;
  120. { Process subdirs }
  121. if (Subdirs<>'') and
  122. ParaRecursive then
  123. begin
  124. Show(v_Verbose,'Subdirs found: '+subdirs);
  125. repeat
  126. s:=GetToken(subdirs,' ');
  127. if s='' then
  128. break;
  129. ProcessFile_Makefile(ExtractFilePath(fn)+s+'/Makefile.fpc');
  130. until false;
  131. end;
  132. end;
  133. {*****************************************************************************
  134. Package.fpc output
  135. *****************************************************************************}
  136. procedure ProcessFile_PackageFpc(const fn:string);
  137. var
  138. CurrFPCMake : TFPCMakeConsole;
  139. CurrPackageFpc : TPackageFpcWriter;
  140. begin
  141. Show(V_Default,'Processing '+fn);
  142. CurrFPCMake:=nil;
  143. {$ifndef NOEXCEPT}
  144. try
  145. {$endif NOEXCEPT}
  146. { Load Makefile.fpc }
  147. CurrFPCMake:=TFPCMakeConsole.Create(fn);
  148. if ParaTargets<>'' then
  149. CurrFPCMake.SetTargets(ParaTargets);
  150. CurrFPCMake.LoadMakefileFPC;
  151. // CurrFPCMake.Print;
  152. { Write Package.fpc }
  153. CurrPackageFpc:=TPackageFpcWriter.Create(CurrFPCMake,ExtractFilePath(fn)+'Package.fpc');
  154. CurrPackageFpc.WritePackageFpc;
  155. CurrPackageFpc.Free;
  156. {$ifndef NOEXCEPT}
  157. except
  158. on e : exception do
  159. begin
  160. Error(e.message);
  161. end;
  162. end;
  163. {$endif NOEXCEPT}
  164. CurrFPCMake.Free;
  165. end;
  166. procedure ProcessFile(const fn:string);
  167. begin
  168. case ParaMode of
  169. m_None :
  170. Error('No operation specified, see -h for help');
  171. m_Makefile :
  172. ProcessFile_Makefile(fn);
  173. m_PackageFpc :
  174. ProcessFile_PackageFpc(fn);
  175. end;
  176. end;
  177. procedure UseMakefilefpc;
  178. var
  179. fn : string;
  180. begin
  181. if FileExists('Makefile.fpc') then
  182. fn:='Makefile.fpc'
  183. else
  184. fn:='makefile.fpc';
  185. ProcessFile(fn);
  186. end;
  187. procedure UseParameters;
  188. var
  189. i : integer;
  190. begin
  191. for i:=OptInd to ParamCount do
  192. ProcessFile(ParamStr(i));
  193. end;
  194. Procedure Usage;
  195. {
  196. Print usage and exit.
  197. }
  198. begin
  199. writeln(paramstr(0),': <-pw> [-vqh] [file] [file ...]');
  200. writeln('Operations:');
  201. writeln(' -p Generate Package.fpc');
  202. writeln(' -w Write Makefile');
  203. writeln('');
  204. writeln('Options:');
  205. writeln(' -T<target>[,target] Support only specified targets');
  206. writeln(' -r Recursively process target directories from Makefile.fpc');
  207. writeln(' -v Be more verbose');
  208. writeln(' -q Be quiet');
  209. writeln(' -h This help screen');
  210. Halt(0);
  211. end;
  212. Procedure ProcessOpts;
  213. {
  214. Process command line opions, and checks if command line options OK.
  215. }
  216. const
  217. ShortOpts = 'pwqrvhT:';
  218. var
  219. C : char;
  220. begin
  221. { Reset }
  222. ParaMode:=m_Makefile;
  223. ParaVerboseLevel:=v_default;
  224. ParaTargets:=LowerCase({$I %FPCTARGETOS});
  225. { Parse options }
  226. repeat
  227. c:=Getopt (ShortOpts);
  228. Case C of
  229. EndOfOptions : break;
  230. 'p' : ParaMode:=m_PackageFpc;
  231. 'w' : ParaMode:=m_Makefile;
  232. 'q' : ParaVerboseLevel:=v_quiet;
  233. 'r' : ParaRecursive:=true;
  234. 'v' : ParaVerboseLevel:=v_verbose;
  235. 'T' : ParaTargets:=OptArg;
  236. '?' : Usage;
  237. 'h' : Usage;
  238. end;
  239. until false;
  240. end;
  241. begin
  242. ProcessOpts;
  243. if (OptInd>Paramcount) then
  244. UseMakefilefpc
  245. else
  246. UseParameters;
  247. end.
  248. {
  249. $Log$
  250. Revision 1.7 2002-01-27 21:42:35 peter
  251. * -r option to process target dirs also
  252. * default changed to build only for current target
  253. * removed auto building of required packages
  254. * removed makefile target because it causes problems with
  255. an internal rule of make
  256. Revision 1.6 2001/08/02 20:50:29 peter
  257. * -T<target> support
  258. * better error reporting for not found dirs
  259. * some cleanups and nicer strings
  260. Revision 1.5 2001/07/13 21:01:59 peter
  261. * cygdrive support
  262. * fixed cygwin detection
  263. * fixed some duplicate and extraeous spaces
  264. Revision 1.4 2001/06/04 21:42:57 peter
  265. * Arguments added
  266. * Start of Package.fpc creation
  267. Revision 1.3 2001/02/22 21:11:24 peter
  268. * fpcdir detection added
  269. * fixed loading of variables in fpcmake itself
  270. Revision 1.2 2001/01/29 21:49:10 peter
  271. * lot of updates
  272. Revision 1.1 2001/01/24 21:59:36 peter
  273. * first commit of new fpcmake
  274. }