2
0

fpcmake.pp 8.9 KB

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