fpcmake.pp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. paraExtra : string;
  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, aextra: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. CurrFPCMake.ExtraTargetsFile:=aExtra;
  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)+'Makefile');
  111. CurrMakefile.WriteGenericMakefile;
  112. CurrMakefile.Free;
  113. {$ifndef NOEXCEPT}
  114. except
  115. on e : exception do
  116. begin
  117. Error(e.message);
  118. Subdirs:='';
  119. end;
  120. end;
  121. {$endif NOEXCEPT}
  122. CurrFPCMake.Free;
  123. { Process subdirs }
  124. if (Subdirs<>'') and
  125. ParaRecursive then
  126. begin
  127. Show(v_Verbose,'Subdirs found: '+subdirs);
  128. repeat
  129. s:=GetToken(subdirs,' ');
  130. if s='' then
  131. break;
  132. ProcessFile_Makefile(ExtractFilePath(fn)+s+'/Makefile.fpc',paraExtra);
  133. until false;
  134. end;
  135. end;
  136. {*****************************************************************************
  137. Package.fpc output
  138. *****************************************************************************}
  139. procedure ProcessFile_PackageFpc(const fn,aExtra :string);
  140. var
  141. CurrFPCMake : TFPCMakeConsole;
  142. CurrPackageFpc : TPackageFpcWriter;
  143. begin
  144. Show(V_Default,'Processing '+fn);
  145. CurrFPCMake:=nil;
  146. {$ifndef NOEXCEPT}
  147. try
  148. {$endif NOEXCEPT}
  149. { Load Makefile.fpc }
  150. CurrFPCMake:=TFPCMakeConsole.Create(fn);
  151. if ParaTargets<>'' then
  152. CurrFPCMake.SetTargets(ParaTargets);
  153. CurrFPCMake.ExtraTargetsFile:=aExtra;
  154. CurrFPCMake.LoadMakefileFPC;
  155. // CurrFPCMake.Print;
  156. { Write Package.fpc }
  157. CurrPackageFpc:=TPackageFpcWriter.Create(CurrFPCMake,ExtractFilePath(fn)+'Package.fpc');
  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,aExtra: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,aExtra);
  178. m_PackageFpc :
  179. ProcessFile_PackageFpc(fn,aExtra);
  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,paraExtra);
  191. end;
  192. procedure UseParameters;
  193. var
  194. i : integer;
  195. begin
  196. for i:=OptInd to ParamCount do
  197. ProcessFile(ParamStr(i),ParaExtra);
  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(' -q Be quiet');
  216. writeln(' -h This help screen');
  217. writeln(' -x file Read extra target definitions from file.');
  218. Halt(0);
  219. end;
  220. procedure printVersion;
  221. begin
  222. writeln (TitleDate);
  223. halt(0);
  224. end;
  225. Procedure ProcessOpts;
  226. {
  227. Process command line opions, and checks if command line options OK.
  228. }
  229. const
  230. ShortOpts = 'pwqrvh?VT:x:';
  231. var
  232. C : char;
  233. begin
  234. { Reset }
  235. ParaMode:=m_Makefile;
  236. ParaVerboseLevel:=v_default;
  237. ParaTargets:=LowerCase({$I %FPCTARGETCPU})+'-'+LowerCase({$I %FPCTARGETOS});
  238. { Parse options }
  239. repeat
  240. c:=Getopt (ShortOpts);
  241. Case C of
  242. EndOfOptions : break;
  243. 'p' : ParaMode:=m_PackageFpc;
  244. 'w' : ParaMode:=m_Makefile;
  245. 'q' : ParaVerboseLevel:=v_quiet;
  246. 'r' : ParaRecursive:=true;
  247. 'v' : ParaVerboseLevel:=v_verbose;
  248. 'T' : ParaTargets:=OptArg;
  249. 'x' : ParaExtra:=OptArg;
  250. '?' : Usage;
  251. 'h' : Usage;
  252. 'V' : printVersion;
  253. end;
  254. until false;
  255. end;
  256. begin
  257. ProcessOpts;
  258. if (OptInd>Paramcount) then
  259. UseMakefilefpc
  260. else
  261. UseParameters;
  262. end.