fpcmwr.pp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. {
  2. $Id$
  3. Copyright (c) 2001 by Peter Vreman
  4. FPCMake - Makefile writer
  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. unit fpcmwr;
  14. interface
  15. uses
  16. sysutils,classes,
  17. fpcmmain;
  18. type
  19. tsections=(sec_none,
  20. sec_units,sec_exes,sec_loaders,sec_examples,sec_rsts,
  21. sec_compile,sec_install,
  22. sec_distinstall,sec_zipinstall,sec_clean,sec_libs,
  23. sec_command,sec_exts,sec_dirs,sec_tools,sec_info,sec_makefile
  24. );
  25. trules=(
  26. r_all,r_debug,r_smart,r_release,
  27. r_examples,
  28. r_shared,
  29. r_install,r_sourceinstall,r_exampleinstall,r_distinstall,
  30. r_zipinstall,r_zipsourceinstall,r_zipexampleinstall,r_zipdistinstall,
  31. r_clean,r_distclean,r_cleanall,
  32. r_info,r_makefiles
  33. );
  34. const
  35. rule2str : array[trules] of string=(
  36. 'all','debug','smart','release',
  37. 'examples',
  38. 'shared',
  39. 'install','sourceinstall','exampleinstall','distinstall',
  40. 'zipinstall','zipsourceinstall','zipexampleinstall','zipdistinstall',
  41. 'clean','distclean','cleanall',
  42. 'info','makefiles'
  43. );
  44. rule2sec : array[trules] of tsections=(
  45. sec_compile,sec_compile,sec_compile,sec_compile,
  46. sec_examples,
  47. sec_libs,
  48. sec_install,sec_install,sec_install,sec_distinstall,
  49. sec_zipinstall,sec_zipinstall,sec_zipinstall,sec_zipinstall,
  50. sec_clean,sec_clean,sec_clean,
  51. sec_info,sec_makefile
  52. );
  53. type
  54. TMakefileWriter=class
  55. private
  56. FFileName : string;
  57. FIni : TFPCMake;
  58. FInput : TFPCMake;
  59. FOutput : TStringList;
  60. FPhony : string;
  61. FHasSection : array[tsections] of boolean;
  62. procedure LoadFPCMakeIni;
  63. procedure AddIniSection(const s:string);
  64. procedure AddCustomSection(const s:string);
  65. procedure AddTargetVariable(const inivar:string);
  66. procedure AddVariable(const inivar:string);
  67. function AddTargetDefines(const inivar,prefix:string):string;
  68. procedure AddRequiredPackages;
  69. procedure AddTool(const varname,exename,altexename:string);
  70. procedure AddTools(const inivar:string);
  71. procedure AddRules;
  72. procedure AddPhony(const s:string);
  73. procedure WritePhony;
  74. procedure AddTargetDirs(const inivar:string);
  75. function CheckTargetVariable(const inivar:string):boolean;
  76. function CheckVariable(const inivar:string):boolean;
  77. procedure AddDefaultTools;
  78. procedure AddMakefileTargets;
  79. procedure OptimizeSections;
  80. public
  81. constructor Create(AFPCMake:TFPCMake;const AFileName:string);
  82. destructor Destroy;override;
  83. procedure WriteGenericMakefile;
  84. end;
  85. implementation
  86. {$i fpcmake.inc}
  87. type
  88. TMyMemoryStream=class(TMemoryStream)
  89. public
  90. constructor Create(p:pointer;mysize:integer);
  91. end;
  92. {*****************************************************************************
  93. Helpers
  94. *****************************************************************************}
  95. function FixVariable(s:string):string;
  96. var
  97. i : integer;
  98. begin
  99. Result:=UpperCase(s);
  100. i:=pos('.',Result);
  101. if i>0 then
  102. Result[i]:='_';
  103. end;
  104. function VarName(const s:string):string;
  105. var
  106. i,j : longint;
  107. begin
  108. i:=0;
  109. result:=s;
  110. while i<length(result) do
  111. begin
  112. inc(i);
  113. case result[i] of
  114. '{' :
  115. begin
  116. { this are pkgs which are hold the dirs between the accolades }
  117. j:=PosIdx('}',result,i);
  118. if j>0 then
  119. Delete(result,i,j-i+1)
  120. else
  121. Delete(result,i,1);
  122. dec(i);
  123. end;
  124. '$','(',')' :
  125. begin
  126. Delete(result,i,1);
  127. dec(i);
  128. end;
  129. 'a'..'z' :
  130. result[i]:=chr(ord(result[i])-32);
  131. end;
  132. end;
  133. end;
  134. procedure FixTab(sl:TStringList);
  135. var
  136. i,j,k : integer;
  137. s,s2 : string;
  138. begin
  139. i:=0;
  140. while (i<sl.Count) do
  141. begin
  142. if (sl[i]<>'') and (sl[i][1] in [' ',#9]) then
  143. begin
  144. s:=sl[i];
  145. k:=0;
  146. j:=0;
  147. repeat
  148. inc(j);
  149. case s[j] of
  150. ' ' :
  151. inc(k);
  152. #9 :
  153. k:=(k+7) and not(7);
  154. else
  155. break;
  156. end;
  157. until (j=length(s));
  158. if k>7 then
  159. begin
  160. s2:='';
  161. Delete(s,1,j-1);
  162. while (k>7) do
  163. begin
  164. s2:=s2+#9;
  165. dec(k,8);
  166. end;
  167. while (k>0) do
  168. begin
  169. s2:=s2+' ';
  170. dec(k);
  171. end;
  172. sl[i]:=s2+s;
  173. end;
  174. end;
  175. inc(i);
  176. end;
  177. end;
  178. {*****************************************************************************
  179. TMyMemoryStream
  180. *****************************************************************************}
  181. constructor TMyMemoryStream.Create(p:pointer;mysize:integer);
  182. begin
  183. inherited Create;
  184. SetPointer(p,mysize);
  185. end;
  186. {*****************************************************************************
  187. TMakefileWriter
  188. *****************************************************************************}
  189. constructor TMakefileWriter.Create(AFPCMake:TFPCMake;const AFileName:string);
  190. begin
  191. FInput:=AFPCMake;
  192. FFileName:=AFileName;
  193. FOutput:=TStringList.Create;
  194. FPhony:='';
  195. FillChar(FHasSection,sizeof(FHasSection),1);
  196. LoadFPCMakeIni;
  197. end;
  198. destructor TMakefileWriter.Destroy;
  199. begin
  200. FOutput.Free;
  201. FIni.Free;
  202. end;
  203. procedure TMakefileWriter.LoadFPCMakeIni;
  204. var
  205. IniStream : TStream;
  206. begin
  207. try
  208. IniStream:=TMyMemoryStream.Create(@fpcmakeini,sizeof(fpcmakeini));
  209. FIni:=TFPCMake.CreateFromStream(IniStream,'fpcmake.ini');
  210. { Leave the '#' comments in the output }
  211. // FIni.CommentChars:=[';'];
  212. FIni.LoadSections;
  213. finally
  214. IniStream.Destroy;
  215. end;
  216. end;
  217. procedure TMakefileWriter.AddIniSection(const s:string);
  218. var
  219. Sec : TFPCMakeSection;
  220. begin
  221. Sec:=TFPCMakeSection(FIni[s]);
  222. if assigned(Sec) then
  223. FOutput.AddStrings(Sec.List)
  224. else
  225. Raise Exception.Create(Format('Section "%s" doesn''t exists in fpcmake.ini',[s]));
  226. end;
  227. procedure TMakefileWriter.AddCustomSection(const s:string);
  228. var
  229. Sec : TFPCMakeSection;
  230. begin
  231. Sec:=TFPCMakeSection(FInput[s]);
  232. if assigned(Sec) then
  233. begin
  234. Sec.BuildMakefile;
  235. FOutput.AddStrings(Sec.List);
  236. end;
  237. end;
  238. function TMakefileWriter.CheckTargetVariable(const inivar:string):boolean;
  239. var
  240. t : TTarget;
  241. begin
  242. result:=false;
  243. if FInput.GetVariable(IniVar,false)<>'' then
  244. begin
  245. result:=true;
  246. exit;
  247. end;
  248. for t:=low(TTarget) to high(TTarget) do
  249. if (t in FInput.IncludeTargets) and
  250. (FInput.GetVariable(IniVar+TargetSuffix[t],false)<>'') then
  251. begin
  252. result:=true;
  253. exit;
  254. end;
  255. end;
  256. function TMakefileWriter.CheckVariable(const inivar:string):boolean;
  257. begin
  258. Result:=(FInput.GetVariable(IniVar,false)<>'');
  259. end;
  260. procedure TMakefileWriter.AddTargetVariable(const inivar:string);
  261. var
  262. s : string;
  263. T : TTarget;
  264. begin
  265. s:=FInput.GetVariable(IniVar,false);
  266. if s<>'' then
  267. FOutput.Add('override '+FixVariable(IniVar)+'+='+s);
  268. for t:=low(TTarget) to high(TTarget) do
  269. if t in FInput.IncludeTargets then
  270. begin
  271. s:=FInput.GetVariable(IniVar+TargetSuffix[t],false);
  272. if s<>'' then
  273. begin
  274. FOutput.Add('ifeq ($(OS_TARGET),'+TargetStr[t]+')');
  275. FOutput.Add('override '+FixVariable(IniVar)+'+='+s);
  276. FOutput.Add('endif');
  277. end;
  278. end;
  279. end;
  280. procedure TMakefileWriter.AddVariable(const inivar:string);
  281. var
  282. s : string;
  283. begin
  284. s:=FInput.GetVariable(IniVar,false);
  285. if s<>'' then
  286. FOutput.Add('override '+FixVariable(IniVar)+'='+s)
  287. end;
  288. function TMakefileWriter.AddTargetDefines(const inivar,prefix:string):string;
  289. var
  290. s : string;
  291. T : TTarget;
  292. name : string;
  293. k1,k2 : integer;
  294. begin
  295. result:='';
  296. s:=FInput.GetVariable(IniVar,false);
  297. repeat
  298. name:=GetToken(s,' ');
  299. if Name='' then
  300. break;
  301. { Remove (..) }
  302. k1:=pos('(',name);
  303. if k1>0 then
  304. begin
  305. k2:=PosIdx(')',name,k1);
  306. if k2=0 then
  307. k2:=length(name)+1;
  308. Delete(Name,k1,k2);
  309. end;
  310. FOutput.Add(prefix+VarName(name)+'=1');
  311. { add to the list of dirs without duplicates }
  312. AddTokenNoDup(result,name,' ');
  313. until false;
  314. for t:=low(TTarget) to high(TTarget) do
  315. if t in FInput.IncludeTargets then
  316. begin
  317. s:=FInput.GetVariable(IniVar+TargetSuffix[t],false);
  318. if s<>'' then
  319. begin
  320. FOutput.Add('ifeq ($(OS_TARGET),'+TargetStr[t]+')');
  321. repeat
  322. Name:=GetToken(s,' ');
  323. if Name='' then
  324. break;
  325. { Remove (..) }
  326. k1:=pos('(',name);
  327. if k1>0 then
  328. begin
  329. k2:=PosIdx(')',name,k1);
  330. if k2=0 then
  331. k2:=length(name)+1;
  332. Delete(Name,k1,k2);
  333. end;
  334. FOutput.Add(prefix+VarName(name)+'=1');
  335. { add to the list of dirs without duplicates }
  336. AddTokenNoDup(result,name,' ');
  337. until false;
  338. FOutput.Add('endif');
  339. end;
  340. end;
  341. end;
  342. procedure TMakefileWriter.AddTool(const varname,exename,altexename:string);
  343. begin
  344. with FOutput do
  345. begin
  346. Add('ifndef '+varname);
  347. Add(varname+':=$(strip $(wildcard $(addsuffix /'+exename+'$(SRCEXEEXT),$(SEARCHPATH))))');
  348. if altexename<>'' then
  349. begin
  350. Add('ifeq ($('+varname+'),)');
  351. Add(varname+':=$(strip $(wildcard $(addsuffix /'+altexename+'$(SRCEXEEXT),$(SEARCHPATH))))');
  352. end;
  353. Add('ifeq ($('+varname+'),)');
  354. Add(varname+'=');
  355. Add('else');
  356. Add(varname+':=$(firstword $('+varname+'))');
  357. Add('endif');
  358. if altexename<>'' then
  359. begin
  360. Add('else');
  361. Add(varname+':=$(firstword $('+varname+'))');
  362. Add('endif');
  363. end;
  364. Add('endif');
  365. Add('export '+varname);
  366. end;
  367. end;
  368. procedure TMakefileWriter.AddTools(const inivar:string);
  369. var
  370. hs,tool : string;
  371. begin
  372. hs:=FInput.GetVariable(inivar,false);
  373. repeat
  374. Tool:=GetToken(hs,' ');
  375. if Tool='' then
  376. break;
  377. AddTool(FixVariable(Tool),Tool,'');
  378. until false;
  379. end;
  380. procedure TMakefileWriter.AddRules;
  381. procedure AddRule(rule:trules);
  382. var
  383. i : integer;
  384. hs : string;
  385. Sec : TFPCMakeSection;
  386. Rules : TStringList;
  387. begin
  388. Sec:=TFPCMakeSection(FInput['rules']);
  389. if assigned(Sec) then
  390. begin
  391. Rules:=Sec.List;
  392. for i:=0 to Rules.Count-1 do
  393. begin
  394. if (length(rules[i])>length(rule2str[rule])) and
  395. (rules[i][1]=rule2str[rule][1]) and
  396. ((rules[i][length(rule2str[rule])+1]=':') or
  397. ((length(rules[i])>length(rule2str[rule])+1) and
  398. (rules[i][length(rule2str[rule])+2]=':'))) and
  399. (Copy(rules[i],1,length(rule2str[rule]))=rule2str[rule]) then
  400. exit;
  401. end;
  402. end;
  403. hs:='';
  404. if FHasSection[Rule2Sec[rule]] then
  405. hs:=hs+' fpc_'+rule2str[rule];
  406. { include target dirs, but not for info and targets that
  407. call other targets with a only extra settings, if the
  408. section was not included, then still process the targets }
  409. if CheckTargetVariable('target_dirs') and
  410. (not(rule in [r_info,r_shared,r_smart,r_debug,r_release,r_distinstall]) or
  411. not FHasSection[Rule2Sec[rule]]) then
  412. begin
  413. if CheckVariable('default_dir') then
  414. hs:=hs+' $(addsuffix _'+rule2str[rule]+',$(DEFAULT_DIR))'
  415. else
  416. if not(rule in [r_sourceinstall,r_zipinstall,r_zipsourceinstall,
  417. r_makefiles]) or
  418. not(CheckVariable('package_name')) then
  419. hs:=hs+' $(addsuffix _'+rule2str[rule]+',$(TARGET_DIRS))';
  420. end;
  421. { include cleaning of example dirs }
  422. if (rule=r_clean) and
  423. CheckTargetVariable('target_exampledirs') then
  424. hs:=hs+' $(addsuffix _'+rule2str[rule]+',$(TARGET_EXAMPLEDIRS))';
  425. { Add the rule }
  426. AddPhony(Rule2Str[Rule]);
  427. FOutput.Add(rule2str[rule]+':'+hs);
  428. end;
  429. var
  430. rule : trules;
  431. begin
  432. for rule:=low(trules) to high(trules) do
  433. AddRule(rule);
  434. WritePhony;
  435. end;
  436. procedure TMakefileWriter.AddPhony(const s:string);
  437. begin
  438. FPhony:=FPhony+' '+s;
  439. end;
  440. procedure TMakefileWriter.WritePhony;
  441. begin
  442. if FPhony<>'' then
  443. begin
  444. FOutput.Add('.PHONY:'+FPhony);
  445. FPhony:='';
  446. end;
  447. end;
  448. procedure TMakefileWriter.AddTargetDirs(const inivar:string);
  449. procedure AddTargetDir(const s,defpref:string);
  450. var
  451. j : trules;
  452. begin
  453. FOutput.Add('ifdef '+defpref+VarName(s));
  454. for j:=low(trules) to high(trules) do
  455. begin
  456. FOutput.Add(s+'_'+rule2str[j]+':');
  457. FOutput.Add(#9+'$(MAKE) -C '+s+' '+rule2str[j]);
  458. AddPhony(s+'_'+rule2str[j]);
  459. end;
  460. FOutput.Add(s+':');
  461. FOutput.Add(#9+'$(MAKE) -C '+s+' all');
  462. AddPhony(s);
  463. WritePhony;
  464. FOutput.Add('endif');
  465. end;
  466. var
  467. hs,dir : string;
  468. prefix : string;
  469. begin
  470. prefix:=FixVariable(inivar)+'_';
  471. hs:=AddTargetDefines(inivar,prefix);
  472. repeat
  473. Dir:=GetToken(hs,' ');
  474. if Dir='' then
  475. break;
  476. AddTargetDir(Dir,prefix);
  477. until false;
  478. end;
  479. procedure TMakefileWriter.AddRequiredPackages;
  480. procedure AddPackage(const pack,prefix:string);
  481. var
  482. packdirvar,unitdirvar : string;
  483. begin
  484. FOutput.Add('ifdef '+Prefix+VarName(pack));
  485. { create needed variables }
  486. packdirvar:='PACKAGEDIR_'+VarName(pack);
  487. unitdirvar:='UNITDIR_'+VarName(pack);
  488. { Search packagedir by looking for Makefile.fpc, for the RTL look
  489. direct in the corresponding target directory }
  490. if pack='rtl' then
  491. FOutput.Add(packdirvar+':=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /'+pack+'/$(OS_TARGET)/Makefile.fpc,$(PACKAGESDIR))))))')
  492. else
  493. FOutput.Add(packdirvar+':=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /'+pack+'/Makefile.fpc,$(PACKAGESDIR))))))');
  494. FOutput.Add('ifneq ($('+packdirvar+'),)');
  495. { Create unit dir, check if os dependent dir exists }
  496. FOutput.Add('ifneq ($(wildcard $('+packdirvar+')/$(OS_TARGET)),)');
  497. FOutput.Add(unitdirvar+'=$('+packdirvar+')/$(OS_TARGET)');
  498. FOutput.Add('else');
  499. FOutput.Add(unitdirvar+'=$('+packdirvar+')');
  500. FOutput.Add('endif');
  501. FOutput.Add('ifdef CHECKDEPEND');
  502. FOutput.Add('$('+packdirvar+')/$(FPCMADE):');
  503. FOutput.Add(#9'$(MAKE) -C $('+packdirvar+') $(FPCMADE)');
  504. FOutput.Add('override ALLDEPENDENCIES+=$('+packdirvar+')/$(FPCMADE)');
  505. FOutput.Add('endif');
  506. { Package dir doesn't exists, check unit dir }
  507. FOutput.Add('else');
  508. FOutput.Add(packdirvar+'=');
  509. FOutput.Add(unitdirvar+':=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /'+pack+'/Package.fpc,$(UNITSDIR)))))');
  510. FOutput.Add('ifneq ($('+unitdirvar+'),)');
  511. FOutput.Add(unitdirvar+':=$(firstword $('+unitdirvar+'))');
  512. FOutput.Add('else');
  513. FOutput.Add(unitdirvar+'=');
  514. FOutput.Add('endif');
  515. FOutput.Add('endif');
  516. { Add Unit dir to the command line -Fu }
  517. FOutput.Add('ifdef '+unitdirvar);
  518. FOutput.Add('override COMPILER_UNITDIR+=$('+unitdirvar+')');
  519. FOutput.Add('endif');
  520. { endif for package }
  521. FOutput.Add('endif');
  522. end;
  523. var
  524. i : integer;
  525. reqs,req,prefix : string;
  526. t : Ttarget;
  527. sl : TStringList;
  528. begin
  529. prefix:='REQUIRE_PACKAGES_';
  530. reqs:='';
  531. { Add target defines }
  532. for t:=low(ttarget) to high(ttarget) do
  533. if t in FInput.IncludeTargets then
  534. begin
  535. sl:=FInput.GetTargetRequires(t);
  536. { show info }
  537. FInput.Verbose(FPCMakeInfo,TargetStr[t]+' requires: '+sl.CommaText);
  538. if sl.count>0 then
  539. begin
  540. FOutput.Add('ifeq ($(OS_TARGET),'+TargetStr[t]+')');
  541. for i:=0 to sl.count-1 do
  542. begin
  543. FOutput.Add(prefix+VarName(sl[i])+'=1');
  544. AddTokenNoDup(reqs,sl[i],' ');
  545. end;
  546. FOutput.Add('endif');
  547. end;
  548. sl.Free;
  549. end;
  550. { Add all require packages }
  551. repeat
  552. req:=GetToken(reqs,' ');
  553. if Req='' then
  554. break;
  555. AddPackage(req,prefix);
  556. until false;
  557. WritePhony;
  558. end;
  559. procedure TMakefileWriter.AddDefaultTools;
  560. begin
  561. AddTool('ECHO','gecho','echo');
  562. AddTool('DATE','gdate','date');
  563. AddTool('GINSTALL','ginstall','install');
  564. AddTool('CPPROG','cp','');
  565. AddTool('RMPROG','rm','');
  566. AddTool('MVPROG','mv','');
  567. AddIniSection('shelltools');
  568. AddTool('PPUMOVE','ppumove','');
  569. AddTool('FPCMAKE','fpcmake','');
  570. AddTool('ZIPPROG','zip','');
  571. AddTool('TARPROG','tar','');
  572. AddIniSection('defaulttools');
  573. end;
  574. procedure TMakefileWriter.AddMakefileTargets;
  575. var
  576. s : string;
  577. t : Ttarget;
  578. begin
  579. s:='';
  580. for t:=low(ttarget) to high(ttarget) do
  581. if t in FInput.IncludeTargets then
  582. begin
  583. AddToken(s,TargetStr[t],' ');
  584. end;
  585. FOutput.Add('MAKEFILETARGETS='+s);
  586. end;
  587. procedure TMakefileWriter.OptimizeSections;
  588. var
  589. SkippedSecs :integer;
  590. begin
  591. { Turn some sections off, depending if files are
  592. provided }
  593. if not FInput.IsPackage then
  594. begin
  595. FHasSection[sec_zipinstall]:=false;
  596. FHasSection[sec_distinstall]:=false;
  597. end;
  598. FHasSection[sec_libs]:=CheckVariable('lib_name');
  599. { Remove unused sections for targets }
  600. SkippedSecs:=0;
  601. if (not CheckTargetVariable('target_units')) then
  602. begin
  603. inc(SkippedSecs);
  604. FHasSection[sec_units]:=false;
  605. end;
  606. if (not CheckTargetVariable('target_programs')) then
  607. begin
  608. inc(SkippedSecs);
  609. FHasSection[sec_exes]:=false;
  610. end;
  611. if (not CheckTargetVariable('target_examples')) then
  612. begin
  613. inc(SkippedSecs);
  614. { example dirs also requires the fpc_examples target, because
  615. it also depends on the all target }
  616. if (not CheckTargetVariable('target_exampledirs')) then
  617. FHasSection[sec_examples]:=false;
  618. end;
  619. if (not CheckTargetVariable('target_loaders')) then
  620. begin
  621. inc(SkippedSecs);
  622. FHasSection[sec_loaders]:=false;
  623. end;
  624. { if all 4 sections are not available we can skip also the
  625. generic compile rules }
  626. if SkippedSecs=4 then
  627. begin
  628. FHasSection[sec_compile]:=false;
  629. if (not CheckTargetVariable('package_name')) and
  630. (not CheckTargetVariable('install_units')) and
  631. (not CheckTargetVariable('install_files')) and
  632. (not CheckTargetVariable('install_createpackagefpc')) then
  633. FHasSection[sec_install]:=false;
  634. { Package.fpc also needs to be cleaned }
  635. if (not CheckTargetVariable('clean_units')) and
  636. (not CheckTargetVariable('clean_files')) and
  637. (not CheckTargetVariable('install_createpackagefpc')) then
  638. FHasSection[sec_clean]:=false;
  639. end;
  640. end;
  641. procedure TMakefileWriter.WriteGenericMakefile;
  642. begin
  643. { Remove unused sections }
  644. OptimizeSections;
  645. { Generate Output }
  646. with FOutput do
  647. begin
  648. { Header }
  649. Add('#');
  650. Add('# Don''t edit, this file is generated by '+TitleDate);
  651. Add('#');
  652. if CheckVariable('default_rule') then
  653. Add('default: '+FInput.GetVariable('default_rule',false))
  654. else
  655. Add('default: all');
  656. { Supported targets by this Makefile }
  657. AddMakefileTargets;
  658. { Add automatic detect sections }
  659. AddIniSection('osdetect');
  660. { Forced target }
  661. if CheckVariable('require_target') then
  662. Add('override OS_TARGET='+FInput.GetVariable('require_target',false))
  663. else if CheckVariable('default_target') then
  664. Add('override OS_TARGET_DEFAULT='+FInput.GetVariable('default_target',false));
  665. if CheckVariable('require_cpu') then
  666. Add('override CPU_TARGET='+FInput.GetVariable('require_cpu',false))
  667. else if CheckVariable('default_cpu') then
  668. Add('override CPU_TARGET_DEFAULT='+FInput.GetVariable('default_cpu',false));
  669. { FPC Detection }
  670. AddVariable('default_fpcdir');
  671. AddIniSection('fpcdetect');
  672. AddIniSection('fpcdircheckenv');
  673. AddIniSection('fpcdirdetect');
  674. { Package }
  675. AddVariable('package_name');
  676. AddVariable('package_version');
  677. AddVariable('package_targets');
  678. { LCL rules }
  679. if FInput.UsesLCL then
  680. begin
  681. AddVariable('default_lcldir');
  682. AddVariable('lcl_platform');
  683. AddIniSection('lclrules');
  684. end;
  685. { First add the required packages sections }
  686. // for i:=0 to FInput.RequireList.Count-1 do
  687. // AddCustomSection(FInput.Requirelist[i]);
  688. { prerules section }
  689. if assigned(FInput['prerules']) then
  690. AddStrings(TFPCMakeSection(FInput['prerules']).List);
  691. { Default }
  692. AddVariable('default_dir');
  693. { Targets }
  694. AddTargetVariable('target_dirs');
  695. AddTargetVariable('target_programs');
  696. AddTargetVariable('target_units');
  697. AddTargetVariable('target_implicitunits');
  698. AddTargetVariable('target_loaders');
  699. AddTargetVariable('target_rsts');
  700. AddTargetVariable('target_examples');
  701. AddTargetVariable('target_exampledirs');
  702. { Clean }
  703. AddTargetVariable('clean_units');
  704. AddTargetVariable('clean_files');
  705. { Install }
  706. AddTargetVariable('install_units');
  707. AddTargetVariable('install_files');
  708. AddVariable('install_buildunit');
  709. AddVariable('install_prefix');
  710. AddVariable('install_basedir');
  711. AddVariable('install_datadir');
  712. AddVariable('install_fpcpackage');
  713. AddVariable('install_fpcsubdir');
  714. AddVariable('install_createpackagefpc');
  715. { Dist }
  716. AddVariable('dist_destdir');
  717. AddVariable('dist_zipname');
  718. AddVariable('dist_ziptarget');
  719. { Compiler }
  720. AddTargetVariable('compiler_options');
  721. AddTargetVariable('compiler_version');
  722. AddTargetVariable('compiler_includedir');
  723. AddTargetVariable('compiler_unitdir');
  724. AddTargetVariable('compiler_sourcedir');
  725. AddTargetVariable('compiler_objectdir');
  726. AddTargetVariable('compiler_librarydir');
  727. AddTargetVariable('compiler_targetdir');
  728. AddTargetVariable('compiler_unittargetdir');
  729. { default Dirs and extensions }
  730. AddIniSection('defaultdirs');
  731. if FInput.CheckLibcRequire then
  732. AddIniSection('dirlibc');
  733. AddIniSection('extensions');
  734. { Add default tools }
  735. AddDefaultTools;
  736. { Required packages }
  737. AddVariable('require_packages');
  738. AddRequiredPackages;
  739. { commandline }
  740. AddIniSection('command_begin');
  741. if FInput.CheckLibcRequire then
  742. AddIniSection('command_libc');
  743. AddIniSection('command_end');
  744. { compile }
  745. if FHasSection[sec_loaders] then
  746. AddIniSection('loaderrules');
  747. if FHasSection[sec_units] then
  748. AddIniSection('unitrules');
  749. if FHasSection[sec_exes] then
  750. AddIniSection('exerules');
  751. if FHasSection[sec_rsts] then
  752. AddIniSection('rstrules');
  753. if FHasSection[sec_examples] then
  754. AddIniSection('examplerules');
  755. if FHasSection[sec_compile] then
  756. AddIniSection('compilerules');
  757. if FHasSection[sec_libs] then
  758. AddIniSection('libraryrules');
  759. { install }
  760. if FHasSection[sec_install] then
  761. AddIniSection('installrules');
  762. if FHasSection[sec_distinstall] then
  763. AddIniSection('distinstallrules');
  764. if FHasSection[sec_zipinstall] then
  765. AddIniSection('zipinstallrules');
  766. { clean }
  767. AddIniSection('cleanrules');
  768. { info }
  769. AddIniSection('baseinforules');
  770. if FInput.UsesLCL then
  771. AddIniSection('lclinforules');
  772. AddIniSection('inforules');
  773. { info }
  774. AddIniSection('makefilerules');
  775. { Subdirs }
  776. AddTargetDirs('target_dirs');
  777. AddTargetDirs('target_exampledirs');
  778. { Tools }
  779. AddTools('require_tools');
  780. { Rules }
  781. AddRules;
  782. { Users own rules }
  783. AddIniSection('localmakefile');
  784. AddIniSection('userrules');
  785. if assigned(FInput['rules']) then
  786. AddStrings(TFPCMakeSection(FInput['rules']).List);
  787. end;
  788. { write to disk }
  789. FInput.Verbose(FPCMakeInfo,'Writing Makefile');
  790. Fixtab(FOutput);
  791. FOutput.SaveToFile(FFileName);
  792. end;
  793. end.
  794. {
  795. $Log$
  796. Revision 1.25 2002-09-27 06:54:54 pierre
  797. * translate default_cpu/os into CPU/OS_TARGET_DEFAULT
  798. Revision 1.24 2002/09/07 15:40:32 peter
  799. * old logs removed and tabs fixed
  800. Revision 1.23 2002/03/19 19:37:09 peter
  801. * fix source location in zips for packages and demos
  802. Revision 1.22 2002/03/11 19:10:36 peter
  803. * Regenerated with updated fpcmake
  804. Revision 1.21 2002/02/28 17:03:47 pierre
  805. + CHECKDEPEND var to check if packages are up to date
  806. Revision 1.20 2002/01/27 21:42:35 peter
  807. * -r option to process target dirs also
  808. * default changed to build only for current target
  809. * removed auto building of required packages
  810. * removed makefile target because it causes problems with
  811. an internal rule of make
  812. Revision 1.19 2002/01/06 21:50:05 peter
  813. * lcl updates
  814. * small optimizes for package check
  815. }