fpcmake.pp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404
  1. {
  2. $Id$
  3. Copyright (c) 1999-2000 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. uses
  15. {$ifdef go32v2}
  16. dpmiexcp,
  17. {$endif}
  18. dos,
  19. sysutils,classes,inifiles;
  20. const
  21. Version='v0.99.13';
  22. Title='fpcmake '+Version;
  23. TitleDate=Title+' ['+{$i %DATE}+']';
  24. { Include default fpcmake.ini }
  25. {$i fpcmake.inc}
  26. type
  27. tsections=(sec_none,
  28. sec_units,sec_exes,sec_loaders,sec_examples,sec_package,
  29. sec_compile,sec_require,sec_install,sec_sourceinstall,sec_zipinstall,sec_zipsourceinstall,
  30. sec_clean,sec_libs,sec_command,sec_exts,sec_dirs,sec_tools,sec_info
  31. );
  32. tbic=(bic_none,bic_build,bic_install,bic_zipinstall,bic_clean);
  33. tspecialdir=record
  34. dir,unitdir,packdir : string;
  35. end;
  36. const
  37. EnvVar='FPCMAKEINI';
  38. sectionstr : array[tsections] of string=('none',
  39. 'units','exes','loaders','examples','package',
  40. 'compile','require','install','sourceinstall','zipinstall','zipsourceinstall',
  41. 'clean','libs','command','exts','dirs','tools','info'
  42. );
  43. sectiondef : array[tsections] of boolean=(false,
  44. true,true,false,false,false,
  45. true,false,true,true,true,true,
  46. true,true,true,true,true,true,true
  47. );
  48. targets=4;
  49. targetstr : array[1..targets] of string=(
  50. 'linux','go32v2','win32','os2'
  51. );
  52. rules=16;
  53. rulestr : array[1..rules] of string=(
  54. 'all','debug',
  55. 'examples','test',
  56. 'smart','shared',
  57. 'showinstall','install','sourceinstall','zipinstall','zipsourceinstall',
  58. 'clean','distclean','cleanall',
  59. 'require','info'
  60. );
  61. rule2sec : array[1..rules] of tsections=(
  62. sec_compile,sec_compile,
  63. sec_examples,sec_examples,
  64. sec_libs,sec_libs,
  65. sec_install,sec_install,sec_sourceinstall,sec_zipinstall,sec_zipinstall,
  66. sec_clean,sec_clean,sec_clean,
  67. sec_require,sec_info
  68. );
  69. rule2bic : array[1..rules] of tbic=(
  70. bic_build,bic_build,
  71. bic_build,bic_build,
  72. bic_build,bic_build,
  73. bic_install,bic_install,bic_install,bic_zipinstall,bic_zipinstall,
  74. bic_clean,bic_clean,bic_clean,
  75. bic_none,bic_none
  76. );
  77. rulediralso : array[1..rules] of boolean=(
  78. true,true,
  79. true,true,
  80. true,true,
  81. true,true,true,false,false,
  82. true,true,true,
  83. true,false
  84. );
  85. specialdirs = 4;
  86. specialdir : array[1..specialdirs] of tspecialdir=(
  87. (dir: 'rtl'; unitdir: '$(UNITSDIR)/rtl'; packdir: '$(FPCDIR)/rtl'),
  88. (dir: 'fcl'; unitdir: '$(UNITSDIR)/fcl'; packdir: '$(FPCDIR)/fcl'),
  89. (dir: 'api'; unitdir: '$(UNITSDIR)/api'; packdir: '$(FPCDIR)/api'),
  90. (dir: 'fv'; unitdir: '$(UNITSDIR)/fv'; packdir: '$(FPCDIR)/fv')
  91. );
  92. { Sections in Makefile.fpc }
  93. ini_sections='sections';
  94. ini_install='install';
  95. ini_zip='zip';
  96. ini_clean='clean';
  97. ini_dirs='dirs';
  98. ini_require='require';
  99. ini_libs='libs';
  100. ini_targets='targets';
  101. ini_info='info';
  102. ini_defaults='defaults';
  103. ini_tools='tools';
  104. type
  105. TTargetsString=array[0..targets] of string;
  106. TFpcMake=record
  107. TargetDirs,
  108. TargetLoaders,
  109. TargetUnits,
  110. TargetPrograms,
  111. TargetExamples,
  112. TargetPkgs,
  113. TargetRST : TTargetsString;
  114. InstallSourceSubdirs : boolean;
  115. InstallPackageName,
  116. InstallUnitSubDir,
  117. InstallPrefixDir,
  118. InstallDataDir,
  119. InstallBaseDir : string;
  120. InstallUnits,
  121. InstallFiles : TTargetsString;
  122. CleanUnits,
  123. CleanFiles : TTargetsString;
  124. ZipName,
  125. ZipTarget : string;
  126. DefaultRule,
  127. DefaultBuildDir,
  128. DefaultInstallDir,
  129. DefaultZipInstallDir,
  130. DefaultCleanDir,
  131. DefaultDir,
  132. DefaultTarget,
  133. DefaultCPU : string;
  134. DirFpc,
  135. DirPackage,
  136. DirToolkit,
  137. DirComponent,
  138. DirUnit,
  139. DirLib,
  140. DirObj,
  141. DirTarget,
  142. DirUnitTarget,
  143. DirSources,
  144. DirInc : string;
  145. RequireRTL : boolean;
  146. RequireOptions : string;
  147. RequireToolkits,
  148. RequirePackages,
  149. RequireComponents : TTargetsString;
  150. LibName,
  151. LibUnits : string;
  152. LibGCC,
  153. LibOther : boolean;
  154. InfoCfg,
  155. InfoDirs,
  156. InfoTools,
  157. InfoInstall,
  158. InfoObjects : boolean;
  159. Section : array[tsections] of boolean;
  160. ToolsPPDep,
  161. ToolsPPUMove,
  162. ToolsPPUFiles,
  163. ToolsData2Inc,
  164. ToolsSed,
  165. ToolsDiff,
  166. ToolsCmp,
  167. ToolsUpx,
  168. ToolsDate,
  169. ToolsZip,
  170. ToolsTar : boolean;
  171. MultiPacks,
  172. PreSettings,
  173. PostSettings,
  174. Rules : TStringList;
  175. end;
  176. TMyMemoryStream=class(TMemoryStream)
  177. public
  178. constructor Create(p:pointer;mysize:integer);
  179. end;
  180. var
  181. userini : TFpcMake;
  182. fpcini : TIniFile;
  183. IniStream : TMyMemoryStream;
  184. {*****************************************************************************
  185. Helpers
  186. *****************************************************************************}
  187. procedure Verbose(s:string);
  188. begin
  189. writeln(s);
  190. end;
  191. procedure Error(s:string);
  192. begin
  193. Writeln(s);
  194. Halt(1);
  195. end;
  196. function posidx(const substr,s : string;idx:integer):integer;
  197. var
  198. i,j : integer;
  199. e : boolean;
  200. begin
  201. i := idx;
  202. j := 0;
  203. e:=(length(SubStr)>0);
  204. while e and (i<=Length(s)-Length(SubStr)) do
  205. begin
  206. inc(i);
  207. if (SubStr[1]=s[i]) and (Substr=Copy(s,i,Length(SubStr))) then
  208. begin
  209. j:=i;
  210. e:=false;
  211. end;
  212. end;
  213. PosIdx:=j;
  214. end;
  215. function TargetStringEmpty(const t:TTargetsString):boolean;
  216. var
  217. i : integer;
  218. begin
  219. for i:=0 to targets do
  220. if t[i]<>'' then
  221. begin
  222. TargetStringEmpty:=false;
  223. exit;
  224. end;
  225. TargetStringEmpty:=true;
  226. end;
  227. procedure AddStrNoDup(var s:string;const s2:string);
  228. var
  229. i,idx : longint;
  230. again,add : boolean;
  231. begin
  232. add:=false;
  233. idx:=0;
  234. repeat
  235. again:=false;
  236. i:=posidx(s2,s,idx);
  237. if (i=0) then
  238. add:=true
  239. else
  240. if (i=1) then
  241. begin
  242. if (length(s)>length(s2)) and
  243. (s[length(s2)+1]<>' ') then
  244. add:=true;
  245. end
  246. else
  247. if (i>1) and
  248. ((s[i-1]<>' ') or
  249. ((length(s)>=i+length(s2)) and (s[i+length(s2)]<>' '))) then
  250. begin
  251. idx:=i+length(s2);
  252. again:=true;
  253. end;
  254. until not again;
  255. if add then
  256. begin
  257. if s='' then
  258. s:=s2
  259. else
  260. s:=s+' '+s2;
  261. end;
  262. end;
  263. {*****************************************************************************
  264. TMyMemoryStream
  265. *****************************************************************************}
  266. constructor TMyMemoryStream.Create(p:pointer;mysize:integer);
  267. begin
  268. inherited Create;
  269. SetPointer(p,mysize);
  270. end;
  271. {*****************************************************************************
  272. Makefile.fpc reading
  273. *****************************************************************************}
  274. function ReadMakefilefpc(const fn:string):boolean;
  275. var
  276. ini : TIniFile;
  277. procedure ReadTargetsString(var t:Ttargetsstring;const sec,name,def:string);
  278. var
  279. i : integer;
  280. begin
  281. t[0]:=ini.ReadString(sec,name,def);
  282. for i:=1 to targets do
  283. t[i]:=ini.ReadString(sec,name+'_'+targetstr[i],'');
  284. end;
  285. var
  286. sec : tsections;
  287. b : boolean;
  288. begin
  289. ReadMakefilefpc:=false;
  290. Verbose('Reading '+fn);
  291. ini:=TIniFile.Create(fn);
  292. with userini,ini do
  293. begin
  294. { targets }
  295. ReadTargetsString(TargetDirs,ini_targets,'dirs','');
  296. ReadTargetsString(TargetLoaders,ini_targets,'loaders','');
  297. ReadTargetsString(TargetUnits,ini_targets,'units','');
  298. ReadTargetsString(TargetPrograms,ini_targets,'programs','');
  299. ReadTargetsString(TargetExamples,ini_targets,'examples','');
  300. ReadTargetsString(TargetRST,ini_targets,'rst','');
  301. ReadTargetsString(TargetPkgs,ini_targets,'pkgs','');
  302. if not TargetStringEmpty(TargetPkgs) then
  303. TargetPkgs[0]:='all '+TargetPkgs[0];
  304. { clean }
  305. ReadTargetsString(CleanUnits,ini_clean,'units','');
  306. ReadTargetsString(CleanFiles,ini_clean,'files','');
  307. { install }
  308. InstallPackageName:=ReadString(ini_install,'packagename','');
  309. InstallPrefixDir:=ReadString(ini_install,'dirprefix','');
  310. InstallBaseDir:=ReadString(ini_install,'basedir','');
  311. InstallDataDir:=ReadString(ini_install,'datadir','');
  312. InstallUnitSubDir:=ReadString(ini_install,'unitsubdir','');
  313. InstallSourceSubdirs:=ReadBool(ini_install,'sourcesubdirs',true);
  314. ReadTargetsString(InstallUnits,ini_install,'units','');
  315. ReadTargetsString(InstallFiles,ini_install,'files','');
  316. { zip }
  317. ZipName:=ReadString(ini_zip,'zipname','');
  318. ZipTarget:=ReadString(ini_zip,'ziptarget','install');
  319. { defaults }
  320. DefaultDir:=ReadString(ini_defaults,'defaultdir','');
  321. DefaultBuildDir:=ReadString(ini_defaults,'defaultbuilddir','');
  322. DefaultInstallDir:=ReadString(ini_defaults,'defaultinstalldir','');
  323. DefaultZipInstallDir:=ReadString(ini_defaults,'defaultzipinstalldir','');
  324. DefaultCleanDir:=ReadString(ini_defaults,'defaultcleandir','');
  325. DefaultRule:=ReadString(ini_defaults,'defaultrule','all');
  326. DefaultTarget:=ReadString(ini_defaults,'defaulttarget','');
  327. DefaultCPU:=ReadString(ini_defaults,'defaultcpu','');
  328. { require }
  329. b:=not(TargetStringEmpty(targetunits) and TargetStringEmpty(targetprograms) and TargetStringEmpty(targetexamples));
  330. RequireRTL:=ReadBool(ini_require,'rtl',b);
  331. RequireOptions:=ReadString(ini_require,'options','');
  332. ReadTargetsString(requireToolkits,ini_require,'toolkit','');
  333. ReadTargetsString(requirePackages,ini_require,'packages','');
  334. ReadTargetsString(requireComponents,ini_require,'components','');
  335. if userini.RequireRTL then
  336. begin
  337. if userini.Requirepackages[0]<>'' then
  338. userini.Requirepackages[0]:='rtl '+userini.Requirepackages[0]
  339. else
  340. userini.Requirepackages[0]:='rtl';
  341. end;
  342. { sections, but allow overriding the 'none' option to include a few sects only }
  343. for sec:=low(tsections) to high(tsections) do
  344. Section[sec]:=sectiondef[sec];
  345. Section[sec_None]:=ReadBool(ini_sections,sectionstr[sec_none],sectiondef[sec_none]);
  346. if Section[sec_None] then
  347. FillChar(Section,sizeof(Section),0);
  348. for sec:=low(tsections) to high(tsections) do
  349. Section[sec]:=ReadBool(ini_sections,sectionstr[sec],section[sec]);
  350. { turn on needed sections }
  351. if not TargetStringEmpty(TargetLoaders) then
  352. section[sec_loaders]:=true;
  353. if not TargetStringEmpty(TargetUnits) then
  354. section[sec_units]:=true;
  355. if not TargetStringEmpty(TargetPrograms) then
  356. section[sec_exes]:=true;
  357. if not TargetStringEmpty(TargetExamples) then
  358. section[sec_examples]:=true;
  359. { dependencies }
  360. if section[sec_zipsourceinstall] then
  361. begin
  362. section[sec_zipinstall]:=true;
  363. section[sec_sourceinstall]:=true;
  364. end;
  365. if section[sec_sourceinstall] then
  366. begin
  367. section[sec_tools]:=true;
  368. section[sec_dirs]:=true;
  369. end;
  370. { dirs }
  371. DirFpc:=ReadString(ini_dirs,'fpcdir','');
  372. DirPackage:=ReadString(ini_dirs,'packagedir','$(FPCDIR)/packages');
  373. DirToolkit:=ReadString(ini_dirs,'toolkitdir','');
  374. DirComponent:=ReadString(ini_dirs,'componentdir','');
  375. DirUnit:=ReadString(ini_dirs,'unitdir','');
  376. DirLib:=ReadString(ini_dirs,'libdir','');
  377. DirObj:=ReadString(ini_dirs,'objdir','');
  378. DirTarget:=ReadString(ini_dirs,'targetdir','');
  379. DirSources:=ReadString(ini_dirs,'sourcesdir','');
  380. DirUnitTarget:=ReadString(ini_dirs,'unittargetdir','');
  381. DirInc:=ReadString(ini_dirs,'incdir','');
  382. { libs }
  383. LibName:=ReadString(ini_libs,'libname','');
  384. LibUnits:=ReadString(ini_libs,'libunits','');
  385. LibGcc:=ReadBool(ini_libs,'libgcc',false);
  386. LibOther:=ReadBool(ini_libs,'libother',false);
  387. { tools }
  388. ToolsPPUMove:=ReadBool(ini_tools,'toolppumove',section[sec_compile]);
  389. ToolsPPUFiles:=ReadBool(ini_tools,'toolppufiles',section[sec_install] or section[sec_clean]);
  390. ToolsUpx:=ReadBool(ini_tools,'toolupx',section[sec_install]);
  391. ToolsZip:=ReadBool(ini_tools,'toolzip',section[sec_zipinstall]);
  392. ToolsTar:=ReadBool(ini_tools,'tooltar',section[sec_zipinstall]);
  393. ToolsPPDep:=ReadBool(ini_tools,'toolppdep',false);
  394. ToolsSed:=ReadBool(ini_tools,'toolsed',false);
  395. ToolsData2Inc:=ReadBool(ini_tools,'tooldata2inc',false);
  396. ToolsDiff:=ReadBool(ini_tools,'tooldiff',false);
  397. ToolsCmp:=ReadBool(ini_tools,'toolcmp',false);
  398. ToolsDate:=ReadBool(ini_tools,'tooldate',false);
  399. { info }
  400. InfoCfg:=ReadBool(ini_info,'infoconfig',true);
  401. InfoDirs:=ReadBool(ini_info,'infodirs',false);
  402. InfoTools:=ReadBool(ini_info,'infotools',false);
  403. InfoInstall:=ReadBool(ini_info,'infoinstall',true);
  404. InfoObjects:=ReadBool(ini_info,'infoobjects',true);
  405. { multipacks }
  406. MultiPacks:=TStringList.Create;
  407. ReadSectionRaw('multipack',MultiPacks);
  408. { rules }
  409. PreSettings:=TStringList.Create;
  410. ReadSectionRaw('presettings',PreSettings);
  411. { rules }
  412. PostSettings:=TStringList.Create;
  413. ReadSectionRaw('postsettings',PostSettings);
  414. { rules }
  415. rules:=TStringList.Create;
  416. ReadSectionRaw('rules',rules);
  417. end;
  418. ini.Destroy;
  419. ReadMakefilefpc:=true;
  420. end;
  421. {*****************************************************************************
  422. userini.ini loading
  423. *****************************************************************************}
  424. function ReadFpcMakeIni:TIniFile;
  425. var
  426. fn : string;
  427. begin
  428. ReadFpcMakeIni:=nil;
  429. if FileExists('fpcmake.ini') then
  430. fn:='fpcmake.ini'
  431. else
  432. if (FileExists(GetEnv(envvar))) then
  433. fn:=GetEnv(envvar)
  434. else
  435. {$ifdef linux}
  436. if FileExists('/usr/lib/fpc/fpcmake.ini') then
  437. fn:='/usr/lib/fpc/fpcmake.ini'
  438. {$else}
  439. if FileExists(ChangeFileExt(paramstr(0),'.ini')) then
  440. fn:=ChangeFileExt(paramstr(0),'.ini')
  441. {$endif}
  442. else
  443. fn:='';
  444. if fn='' then
  445. begin
  446. Verbose('Opening internal ini');
  447. IniStream:=TMyMemoryStream.Create(@fpcmakeini,sizeof(fpcmakeini));
  448. result:=TIniFile.Create(IniStream);
  449. end
  450. else
  451. begin
  452. Verbose('Opening '+fn);
  453. result:=TIniFile.Create(fn);
  454. end;
  455. end;
  456. {*****************************************************************************
  457. Makefile writing
  458. *****************************************************************************}
  459. function VarName(const s:string):string;
  460. var
  461. i,j : longint;
  462. begin
  463. i:=0;
  464. result:=s;
  465. while i<length(result) do
  466. begin
  467. inc(i);
  468. case result[i] of
  469. '{' :
  470. begin
  471. { this are pkgs which are hold the dirs between the accolades }
  472. j:=PosIdx('}',result,i);
  473. if j>0 then
  474. Delete(result,i,j-i+1)
  475. else
  476. Delete(result,i,1);
  477. dec(i);
  478. end;
  479. '$','(',')' :
  480. begin
  481. Delete(result,i,1);
  482. dec(i);
  483. end;
  484. 'a'..'z' :
  485. result[i]:=chr(ord(result[i])-32);
  486. end;
  487. end;
  488. end;
  489. function WriteMakefile(const fn:string):boolean;
  490. var
  491. mf : TStringList;
  492. ss : TStringList;
  493. Phony : string;
  494. procedure FixTab(sl:TStringList);
  495. var
  496. i,j,k : integer;
  497. s,s2 : string;
  498. begin
  499. i:=0;
  500. while (i<sl.Count) do
  501. begin
  502. if (sl[i]<>'') and (sl[i][1] in [' ',#9]) then
  503. begin
  504. s:=sl[i];
  505. k:=0;
  506. j:=0;
  507. repeat
  508. inc(j);
  509. case s[j] of
  510. ' ' :
  511. inc(k);
  512. #9 :
  513. k:=(k+7) and not(7);
  514. else
  515. break;
  516. end;
  517. until (j=length(s));
  518. if k>7 then
  519. begin
  520. s2:='';
  521. Delete(s,1,j-1);
  522. while (k>7) do
  523. begin
  524. s2:=s2+#9;
  525. dec(k,8);
  526. end;
  527. while (k>0) do
  528. begin
  529. s2:=s2+' ';
  530. dec(k);
  531. end;
  532. sl[i]:=s2+s;
  533. end;
  534. end;
  535. inc(i);
  536. end;
  537. end;
  538. procedure AddHead(const s:string);
  539. begin
  540. mf.Add('');
  541. mf.Add('# '+s);
  542. mf.Add('');
  543. end;
  544. procedure AddSection(b:boolean;s:string);
  545. begin
  546. if b then
  547. begin
  548. ss.Clear;
  549. fpcini.ReadSectionRaw(s,ss);
  550. mf.AddStrings(ss);
  551. mf.Add('');
  552. end;
  553. end;
  554. procedure AddRule(rule:integer);
  555. var
  556. i : integer;
  557. hs : string;
  558. begin
  559. i:=0;
  560. while (i<userini.rules.Count) do
  561. begin
  562. if (length(userini.rules[i])>length(rulestr[rule])) and
  563. (userini.rules[i][1]=rulestr[rule][1]) and
  564. ((userini.rules[i][length(rulestr[rule])+1]=':') or
  565. ((length(userini.rules[i])>length(rulestr[rule])+1) and
  566. (userini.rules[i][length(rulestr[rule])+2]=':'))) and
  567. (Copy(userini.rules[i],1,length(rulestr[rule]))=rulestr[rule]) then
  568. exit;
  569. inc(i);
  570. end;
  571. hs:='';
  572. { zipinstall is special, it allows packages }
  573. if (not userini.installsourcesubdirs) and
  574. ((rulestr[rule]='zipsourceinstall') or (rulestr[rule]='sourceinstall')) then
  575. begin
  576. if userini.section[rule2sec[rule]] then
  577. hs:=hs+' fpc_'+rulestr[rule];
  578. end
  579. else
  580. if ((rulestr[rule]='zipinstall') or
  581. (rulestr[rule]='zipsourceinstall')) and
  582. (not TargetStringEmpty(userini.targetpkgs)) then
  583. hs:=hs+' $(addsuffix _'+rulestr[rule]+',$(PKGOBJECTS))'
  584. else
  585. begin
  586. if userini.section[rule2sec[rule]] then
  587. hs:=hs+' fpc_'+rulestr[rule];
  588. if userini.DefaultDir<>'' then
  589. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultdir+')'
  590. else
  591. if (userini.DefaultBuildDir<>'') and (rule2bic[rule]=bic_build) then
  592. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultbuilddir+')'
  593. else
  594. if (userini.DefaultInstallDir<>'') and (rule2bic[rule]=bic_install) then
  595. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultinstalldir+')'
  596. else
  597. if (userini.DefaultZipInstallDir<>'') and (rule2bic[rule]=bic_zipinstall) then
  598. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultzipinstalldir+')'
  599. else
  600. if (userini.DefaultCleanDir<>'') and (rule2bic[rule]=bic_clean) then
  601. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultcleandir+')'
  602. else
  603. if rulediralso[rule] and (not TargetStringEmpty(userini.targetdirs)) then
  604. hs:=hs+' $(addsuffix _'+rulestr[rule]+',$(DIROBJECTS))';
  605. end;
  606. if hs<>'' then
  607. begin
  608. Phony:=Phony+' '+rulestr[rule];
  609. mf.Add(rulestr[rule]+':'+hs);
  610. mf.Add('');
  611. end;
  612. end;
  613. procedure AddTargets(const pre:string;var t:TTargetsString;wildcard:boolean);
  614. var
  615. i : integer;
  616. begin
  617. for i:=0 to targets do
  618. if (t[i]<>'') then
  619. begin
  620. if i<>0 then
  621. mf.Add('ifeq ($(OS_TARGET),'+targetstr[i]+')');
  622. if t[i]<>'' then
  623. begin
  624. if wildcard then
  625. mf.Add('override '+pre+'+=$(wildcard '+t[i]+')')
  626. else
  627. mf.Add('override '+pre+'+='+t[i]);
  628. end;
  629. if i<>0 then
  630. mf.Add('endif');
  631. end;
  632. end;
  633. procedure AddTargetDir(const s:string);
  634. var
  635. j : integer;
  636. hs : string;
  637. begin
  638. AddHead('Dir '+s);
  639. mf.Add('ifdef OBJECTDIR'+VarName(s));
  640. hs:='.PHONY: ';
  641. for j:=1to rules do
  642. hs:=hs+' '+s+'_'+rulestr[j];
  643. mf.Add(hs);
  644. mf.Add('');
  645. for j:=1to rules do
  646. begin
  647. mf.Add(s+'_'+rulestr[j]+':');
  648. mf.Add(#9+'$(MAKE) -C '+s+' '+rulestr[j]);
  649. if j<rules then
  650. mf.Add('');
  651. end;
  652. mf.Add('endif');
  653. end;
  654. function AddTargetDefines(const ts:TTargetsString;const prefix:string):string;
  655. var
  656. k1,k2,k3,j,i : integer;
  657. name,hs,hs2,hs3 : string;
  658. begin
  659. hs2:='';
  660. for j:=0 to targets do
  661. if (ts[j]<>'') then
  662. begin
  663. if j<>0 then
  664. mf.Add('ifeq ($(OS_TARGET),'+targetstr[j]+')');
  665. hs:=ts[j];
  666. repeat
  667. i:=pos(' ',hs);
  668. if i=0 then
  669. i:=length(hs)+1;
  670. name:=Copy(hs,1,i-1);
  671. k1:=pos('{',name);
  672. if k1>0 then
  673. begin
  674. k2:=PosIdx('}',name,k1);
  675. if k2=0 then
  676. begin
  677. Writeln('Error: missing closing } for "',name,'"');
  678. k2:=length(name)+1;
  679. end;
  680. hs3:=Copy(name,k1+1,k2-k1-1);
  681. for k3:=1to length(hs3) do
  682. if hs3[k3]=',' then
  683. hs3[k3]:=' ';
  684. name:=Copy(name,1,k1-1);
  685. mf.Add(prefix+VarName(name)+'='+hs3);
  686. end
  687. else
  688. mf.Add(prefix+VarName(name)+'=1');
  689. { add to the list of dirs without duplicates }
  690. AddStrNoDup(hs2,name);
  691. system.delete(hs,1,i);
  692. until hs='';
  693. if j<>0 then
  694. mf.Add('endif');
  695. end;
  696. AddTargetDefines:=hs2;
  697. end;
  698. procedure AddPackage(const path,pack:string);
  699. var
  700. k : integer;
  701. packdirvar,unitdirvar,unitdir,packdir : string;
  702. begin
  703. mf.Add('ifdef PACKAGE'+VarName(pack));
  704. { create needed variables }
  705. packdirvar:='PACKAGEDIR_'+VarName(pack);
  706. unitdirvar:='UNITDIR_'+VarName(pack);
  707. packdir:=path+'/'+pack;
  708. unitdir:='$(UNITSDIR)/'+pack;
  709. for k:=1to specialdirs do
  710. begin
  711. if specialdir[k].dir=pack then
  712. begin
  713. packdir:=specialdir[k].packdir;
  714. unitdir:=specialdir[k].unitdir;
  715. break;
  716. end;
  717. end;
  718. mf.Add('ifneq ($(wildcard '+packdir+'),)');
  719. { Use Package dir, add build rules }
  720. mf.Add('ifneq ($(wildcard '+packdir+'/$(OS_TARGET)),)');
  721. mf.Add(packdirvar+'='+packdir+'/$(OS_TARGET)');
  722. mf.Add('else');
  723. mf.Add(packdirvar+'='+packdir);
  724. mf.Add('endif');
  725. mf.Add('ifeq ($(wildcard $('+packdirvar+')/$(FPCMADE)),)');
  726. mf.Add('override COMPILEPACKAGES+=package_'+pack);
  727. Phony:=Phony+'package_'+pack;
  728. mf.Add('package_'+pack+':');
  729. mf.Add(#9'$(MAKE) -C $('+packdirvar+') all');
  730. mf.Add('endif');
  731. mf.Add(unitdirvar+'=$('+packdirvar+')');
  732. mf.Add('else');
  733. { Package dir doesn''t exists, create unit dir }
  734. mf.Add(packdirvar+'=');
  735. mf.Add('ifneq ($(wildcard '+unitdir+'),)');
  736. mf.Add('ifneq ($(wildcard '+unitdir+'/$(OS_TARGET)),)');
  737. mf.Add(unitdirvar+'='+unitdir+'/$(OS_TARGET)');
  738. mf.Add('else');
  739. mf.Add(unitdirvar+'='+unitdir);
  740. mf.Add('endif');
  741. mf.Add('else');
  742. mf.Add(unitdirvar+'=');
  743. mf.Add('endif');
  744. mf.Add('endif');
  745. { Add Unit dir to the command line -Fu }
  746. mf.Add('ifdef '+unitdirvar);
  747. mf.Add('override NEEDUNITDIR+=$('+unitdirvar+')');
  748. mf.Add('endif');
  749. mf.Add('endif');
  750. end;
  751. procedure AddTargetsPackages(const path:string;const ts:TTargetsString);
  752. var
  753. Phony,hs : string;
  754. i : integer;
  755. begin
  756. { Components }
  757. Phony:='';
  758. if not TargetStringEmpty(ts) then
  759. begin
  760. AddHead(VarName(path)+' packages');
  761. hs:=AddTargetDefines(ts,'PACKAGE');
  762. mf.Add('');
  763. repeat
  764. i:=pos(' ',hs);
  765. if i=0 then
  766. i:=length(hs)+1;
  767. AddPackage(path,Copy(hs,1,i-1));
  768. system.delete(hs,1,i);
  769. until hs='';
  770. mf.Add('');
  771. end;
  772. if Phony<>'' then
  773. begin
  774. mf.Add('.PHONY: '+Phony);
  775. mf.Add('');
  776. end;
  777. end;
  778. procedure AddPkg(const pack:string);
  779. var
  780. j : integer;
  781. packname,pkgdirsvar,hs : string;
  782. begin
  783. packname:=pack;
  784. AddHead('Pkg '+packname);
  785. mf.Add('ifdef PKG'+VarName(packname));
  786. hs:='.PHONY: ';
  787. for j:=1 to rules do
  788. hs:=hs+' pkg'+packname+'_'+rulestr[j];
  789. mf.Add(hs);
  790. mf.Add('');
  791. { pkgall is special which processes all directories }
  792. if pack='all' then
  793. pkgdirsvar:='DIROBJECTS'
  794. else
  795. begin
  796. mf.Add('override PKGOBJECTS+=pkg'+packname);
  797. pkgdirsvar:='PKG'+VarName(packname);
  798. end;
  799. for j:=1to rules do
  800. if rulediralso[j] then
  801. begin
  802. mf.Add('pkg'+packname+'_'+rulestr[j]+': $(addsuffix _'+rulestr[j]+',$('+pkgdirsvar+'))');
  803. if j<rules then
  804. mf.Add('');
  805. end
  806. else
  807. begin
  808. { zipinstall is special for pkgs }
  809. if (rulestr[j]='zipinstall') then
  810. begin
  811. mf.Add('pkg'+packname+'_'+rulestr[j]+':');
  812. mf.Add(#9'$(MAKE) fpc_zipinstall PACKAGENAME='+packname+
  813. ' ZIPTARGET=pkg'+packname+'_install');
  814. if j<rules then
  815. mf.Add('');
  816. end
  817. else
  818. if (rulestr[j]='zipsourceinstall') then
  819. begin
  820. mf.Add('pkg'+packname+'_'+rulestr[j]+':');
  821. mf.Add(#9'$(MAKE) fpc_zipinstall PACKAGENAME='+packname+
  822. ' PACKAGESUFFIX=src ZIPTARGET=pkg'+packname+'_sourceinstall');
  823. if j<rules then
  824. mf.Add('');
  825. end;
  826. end;
  827. mf.Add('endif');
  828. end;
  829. procedure AddTargetsPkgs(const ts:TTargetsString);
  830. var
  831. Phony,hs : string;
  832. i : integer;
  833. begin
  834. { Components }
  835. Phony:='';
  836. if not TargetStringEmpty(ts) then
  837. begin
  838. hs:=AddTargetDefines(ts,'PKG');
  839. mf.Add('');
  840. repeat
  841. i:=pos(' ',hs);
  842. if i=0 then
  843. i:=length(hs)+1;
  844. AddPkg(Copy(hs,1,i-1));
  845. system.delete(hs,1,i);
  846. until hs='';
  847. mf.Add('');
  848. end;
  849. if Phony<>'' then
  850. begin
  851. mf.Add('.PHONY: '+Phony);
  852. mf.Add('');
  853. end;
  854. end;
  855. var
  856. hs : string;
  857. i : integer;
  858. begin
  859. { Open the Makefile }
  860. mf:=TStringList.Create;
  861. { Buffer for reading and writing the sections }
  862. ss:=TStringList.Create;
  863. with mf do
  864. begin
  865. { write header & autodetection }
  866. Add('#');
  867. Add('# Makefile generated by '+titledate);
  868. Add('#');
  869. Add('');
  870. Add('defaultrule: '+userini.defaultrule);
  871. Add('');
  872. AddSection(true,'osdetect');
  873. { set the forced target os/cpu }
  874. if (userini.defaulttarget<>'') or (userini.defaultcpu<>'') then
  875. begin
  876. AddSection(true,'defaulttarget');
  877. if userini.defaulttarget<>'' then
  878. Add('override OS_TARGET:='+userini.defaulttarget);
  879. if userini.defaultcpu<>'' then
  880. Add('override CPU_TARGET:='+userini.defaultcpu);
  881. Add('');
  882. end;
  883. { fpc detection }
  884. AddSection(true,'fpcdetect');
  885. { Pre Settings }
  886. if userini.PreSettings.count>0 then
  887. begin
  888. AddSection(true,'presettings');
  889. AddStrings(userini.PreSettings);
  890. end;
  891. { fpc dir }
  892. AddSection(true,'fpcdircheckenv');
  893. if userini.dirfpc<>'' then
  894. begin
  895. Add('# Default FPCDIR');
  896. Add('ifeq ($(FPCDIR),wrong)');
  897. Add('override FPCDIR='+userini.dirfpc);
  898. Add('ifeq ($(wildcard $(FPCDIR)/rtl),)');
  899. Add('ifeq ($(wildcard $(FPCDIR)/units),)');
  900. Add('override FPCDIR=wrong');
  901. Add('endif');
  902. Add('endif');
  903. Add('endif');
  904. Add('');
  905. end;
  906. AddSection(true,'fpcdirdetect');
  907. { fpcdir subdirs }
  908. if userini.RequireRTL then
  909. begin
  910. Add('ifndef PACKAGESDIR');
  911. Add('PACKAGESDIR='+userini.dirpackage);
  912. Add('endif');
  913. Add('ifndef TOOLKITSDIR');
  914. Add('TOOLKITSDIR='+userini.dirtoolkit);
  915. Add('endif');
  916. Add('ifndef COMPONENTSDIR');
  917. Add('COMPONENTSDIR='+userini.dircomponent);
  918. Add('endif');
  919. Add('');
  920. AddSection(true,'fpcdirsubs');
  921. end;
  922. { write the default & user settings }
  923. AddSection(true,'usersettings');
  924. { Targets }
  925. AddHead('Targets');
  926. AddTargets('DIROBJECTS',userini.targetdirs,true);
  927. AddTargets('LOADEROBJECTS',userini.targetloaders,false);
  928. AddTargets('UNITOBJECTS',userini.targetunits,false);
  929. AddTargets('EXEOBJECTS',userini.targetprograms,false);
  930. AddTargets('EXAMPLEOBJECTS',userini.targetexamples,false);
  931. AddTargets('RSTOBJECTS',userini.targetrst,false);
  932. { Clean }
  933. AddHead('Clean');
  934. AddTargets('EXTRACLEANUNITS',userini.cleanunits,false);
  935. AddTargets('EXTRACLEANFILES',userini.cleanfiles,false);
  936. { Install }
  937. AddHead('Install');
  938. AddTargets('EXTRAINSTALLUNITS',userini.installunits,false);
  939. AddTargets('EXTRAINSTALLFILES',userini.installfiles,false);
  940. if userini.installprefixdir<>'' then
  941. Add('PREFIXINSTALLDIR='+userini.installprefixdir);
  942. if userini.installbasedir<>'' then
  943. Add('BASEINSTALLDIR='+userini.installbasedir);
  944. if userini.installdatadir<>'' then
  945. Add('DATAINSTALLDIR='+userini.installdatadir);
  946. if userini.InstallUnitSubDir<>'' then
  947. Add('UNITSUBDIR='+userini.InstallUnitSubDir);
  948. if userini.installpackagename<>'' then
  949. Add('PACKAGENAME='+userini.installpackagename);
  950. { Zip }
  951. if userini.zipname<>'' then
  952. Add('ZIPNAME='+userini.zipname);
  953. if userini.ziptarget<>'' then
  954. Add('ZIPTARGET='+userini.ziptarget);
  955. { Defaults }
  956. AddHead('Defaults');
  957. if userini.Requireoptions<>'' then
  958. Add('override NEEDOPT='+userini.Requireoptions);
  959. { Dirs }
  960. AddHead('Directories');
  961. if userini.dirsources<>'' then
  962. Add('vpath %$(PASEXT) '+userini.dirsources);
  963. if userini.dirunit<>'' then
  964. Add('override NEEDUNITDIR='+userini.dirunit);
  965. if userini.dirlib<>'' then
  966. Add('override NEEDLIBDIR='+userini.dirlib);
  967. if userini.dirobj<>'' then
  968. Add('override NEEDOBJDIR='+userini.dirobj);
  969. if userini.dirinc<>'' then
  970. Add('override NEEDINCDIR='+userini.dirinc);
  971. if userini.dirtarget<>'' then
  972. begin
  973. Add('ifndef TARGETDIR');
  974. Add('TARGETDIR='+userini.dirtarget);
  975. Add('endif');
  976. end;
  977. if userini.dirunittarget<>'' then
  978. begin
  979. Add('ifndef UNITTARGETDIR');
  980. Add('UNITTARGETDIR='+userini.dirunittarget);
  981. Add('endif');
  982. end;
  983. { Packages }
  984. AddHead('Packages');
  985. Phony:='';
  986. AddTargets('PACKAGES',userini.Requirepackages,false);
  987. AddTargets('TOOLKITS',userini.Requiretoolkits,false);
  988. AddTargets('COMPONENTS',userini.Requirecomponents,false);
  989. if Phony<>'' then
  990. begin
  991. Add('.PHONY: '+Phony);
  992. Add('');
  993. end;
  994. { Libs }
  995. AddHead('Libraries');
  996. if userini.libname<>'' then
  997. Add('LIBNAME='+userini.libname);
  998. if userini.libunits<>'' then
  999. Add('SHAREDLIBOBJECTUNITS='+userini.libunits);
  1000. if userini.libgcc then
  1001. Add('override NEEDGCCLIB=1');
  1002. if userini.libother then
  1003. Add('override NEEDOTHERLIB=1');
  1004. { Info }
  1005. if userini.Section[sec_Info] then
  1006. begin
  1007. AddHead('Info');
  1008. hs:='';
  1009. if userini.infocfg then
  1010. hs:=hs+'fpc_infocfg ';
  1011. if userini.infodirs then
  1012. hs:=hs+'fpc_infodirs ';
  1013. if userini.infotools then
  1014. hs:=hs+'fpc_infotools ';
  1015. if userini.infoobjects then
  1016. hs:=hs+'fpc_infoobjects ';
  1017. if userini.infoinstall then
  1018. hs:=hs+'fpc_infoinstall ';
  1019. Add('INFOTARGET='+hs);
  1020. end;
  1021. Add('');
  1022. { Post Settings }
  1023. if userini.PostSettings.count>0 then
  1024. begin
  1025. AddSection(true,'postsettings');
  1026. AddStrings(userini.PostSettings);
  1027. Add('');
  1028. end;
  1029. { shell tools like copy,del,echo }
  1030. AddSection(userini.section[sec_command] or userini.section[sec_tools],'shelltools');
  1031. { write tools }
  1032. AddSection(userini.section[sec_tools],'tool_default');
  1033. AddSection(userini.toolsppdep,'tool_ppdep');
  1034. AddSection(userini.toolsppumove,'tool_ppumove');
  1035. AddSection(userini.toolsppufiles,'tool_ppufiles');
  1036. AddSection(userini.toolsdata2inc,'tool_data2inc');
  1037. AddSection(userini.toolsupx,'tool_upx');
  1038. AddSection(userini.toolssed,'tool_sed');
  1039. AddSection(userini.toolscmp,'tool_cmp');
  1040. AddSection(userini.toolsdiff,'tool_diff');
  1041. AddSection(userini.toolsdate,'tool_date');
  1042. AddSection(userini.toolszip,'tool_zip');
  1043. AddSection(userini.toolstar,'tool_tar');
  1044. { extensions }
  1045. if userini.section[sec_exts] then
  1046. AddSection(true,'extensions');
  1047. { package/component dirs }
  1048. AddSection(true,'packagerequirerules');
  1049. AddSection(userini.requirertl,'checkfpcdirsubs');
  1050. AddTargetsPackages('$(PACKAGESDIR)',userini.Requirepackages);
  1051. AddTargetsPackages('$(TOOLKITSDIR)',userini.Requiretoolkits);
  1052. AddTargetsPackages('$(COMPONENTSDIR)',userini.Requirecomponents);
  1053. Add('');
  1054. { Pkgs }
  1055. AddTargetsPkgs(userini.targetpkgs);
  1056. { write dirs }
  1057. AddSection(true,'dir_default');
  1058. if userini.section[sec_dirs] then
  1059. begin
  1060. AddSection(userini.libgcc,'dir_gcclib');
  1061. AddSection(userini.libother,'dir_otherlib');
  1062. AddSection(true,'dir_install');
  1063. end;
  1064. { redirection }
  1065. AddSection(true,'redir');
  1066. { commandline }
  1067. if userini.section[sec_command] then
  1068. begin
  1069. Add('');
  1070. AddSection(true,'command_begin');
  1071. AddSection((userini.Requireoptions<>''),'command_needopt');
  1072. AddSection((userini.dirunit<>'') or
  1073. (not TargetStringEmpty(userini.Requiretoolkits)) or
  1074. (not TargetStringEmpty(userini.Requirepackages)) or
  1075. (not TargetStringEmpty(userini.Requirecomponents))
  1076. ,'command_needunit');
  1077. AddSection(true,'command_unitsdir');
  1078. AddSection((userini.dirlib<>''),'command_needlib');
  1079. AddSection((userini.dirobj<>''),'command_needobj');
  1080. AddSection((userini.dirinc<>''),'command_needinc');
  1081. AddSection(userini.libgcc,'command_gcclib');
  1082. AddSection(userini.libother,'command_otherlib');
  1083. AddSection((userini.dirinc<>''),'command_inc');
  1084. AddSection((userini.dirtarget<>''),'command_target');
  1085. AddSection((userini.dirunittarget<>''),'command_unittarget');
  1086. AddSection(true,'command_end');
  1087. AddSection(true,'command_win32env');
  1088. AddSection(true,'command_compiler');
  1089. end;
  1090. { add default rules }
  1091. AddSection(true,'standardrules');
  1092. Phony:='';
  1093. for i:=1 to rules do
  1094. AddRule(i);
  1095. if Phony<>'' then
  1096. begin
  1097. Add('.PHONY: '+Phony);
  1098. Add('');
  1099. end;
  1100. { compile rules for making loaders/units/exes/examples }
  1101. AddSection(not TargetStringEmpty(userini.targetloaders),'loaderrules');
  1102. AddSection(not TargetStringEmpty(userini.targetunits),'unitrules');
  1103. AddSection(not TargetStringEmpty(userini.targetprograms),'exerules');
  1104. AddSection(not TargetStringEmpty(userini.targetexamples),'examplerules');
  1105. AddSection(not TargetStringEmpty(userini.targetrst),'rstrules');
  1106. { default fpc_ rules }
  1107. AddSection(userini.Section[sec_Compile],'compilerules');
  1108. AddSection(userini.Section[sec_Libs],'libraryrules');
  1109. AddSection(userini.Section[sec_Install],'installrules');
  1110. AddSection(userini.Section[sec_SourceInstall],'sourceinstallrules');
  1111. AddSection(userini.Section[sec_ZipInstall],'zipinstallrules');
  1112. AddSection(userini.Section[sec_ZipSourceInstall],'zipsourceinstallrules');
  1113. AddSection(userini.Section[sec_Clean],'cleanrules');
  1114. AddSection(userini.Section[sec_require],'requirerules');
  1115. if userini.Section[sec_Info] then
  1116. begin
  1117. AddSection(true,'inforules');
  1118. AddSection(userini.infocfg,'info_cfg');
  1119. AddSection(userini.infodirs,'info_dirs');
  1120. AddSection(userini.infotools,'info_tools');
  1121. AddSection(userini.infoobjects,'info_objects');
  1122. AddSection(userini.infoinstall,'info_install');
  1123. end;
  1124. { Target dirs }
  1125. if not TargetStringEmpty(userini.targetdirs) then
  1126. begin
  1127. AddSection(true,'directorytargets');
  1128. hs:=AddTargetDefines(userini.targetdirs,'OBJECTDIR');
  1129. repeat
  1130. i:=pos(' ',hs);
  1131. if i=0 then
  1132. i:=length(hs)+1;
  1133. AddTargetDir(Copy(hs,1,i-1));
  1134. system.delete(hs,1,i);
  1135. until hs='';
  1136. Add('');
  1137. end;
  1138. { local makefile }
  1139. AddSection(true,'localmakefile');
  1140. { insert users rules }
  1141. if userini.rules.count>0 then
  1142. begin
  1143. AddSection(true,'userrules');
  1144. AddStrings(userini.rules);
  1145. end;
  1146. end;
  1147. { Write the Makefile and cleanup }
  1148. Verbose('Writing '+fn);
  1149. FixTab(mf);
  1150. mf.SaveToFile(fn);
  1151. mf.Destroy;
  1152. ss.Destroy;
  1153. WriteMakefile:=true;
  1154. end;
  1155. procedure UseMakefilefpc;
  1156. var
  1157. fn : string;
  1158. begin
  1159. if FileExists('Makefile.fpc') then
  1160. fn:='Makefile.fpc'
  1161. else
  1162. fn:='makefile.fpc';
  1163. { Open Makefile.fpc }
  1164. if not ReadMakefilefpc(fn) then
  1165. Error('Can''t read '+fn);
  1166. { Write Makefile }
  1167. if not WriteMakefile('Makefile') then
  1168. Error('Can''t write Makefile');
  1169. end;
  1170. procedure UseParameters;
  1171. var
  1172. i : integer;
  1173. fn : string;
  1174. begin
  1175. for i:=1 to ParamCount do
  1176. begin
  1177. fn:=ParamStr(i);
  1178. { Open Makefile.fpc }
  1179. if not ReadMakefilefpc(fn) then
  1180. Error('Can''t read '+fn);
  1181. { Write Makefile }
  1182. if not WriteMakefile(ExtractFilePath(fn)+'Makefile') then
  1183. Error('Can''t write '+ExtractFilePath(fn)+'Makefile');
  1184. end;
  1185. end;
  1186. begin
  1187. { Open userini.ini }
  1188. fpcini:=ReadFpcMakeIni;
  1189. if not assigned(fpcini) then
  1190. Error('Can''t read fpcmake.ini');
  1191. if ParamCount=0 then
  1192. UseMakefilefpc
  1193. else
  1194. UseParameters;
  1195. fpcini.destroy;
  1196. end.
  1197. {
  1198. $Log$
  1199. Revision 1.29 2000-01-28 12:10:46 peter
  1200. * reinserted lost diff of rev 1.30
  1201. * distclean target
  1202. Revision 1.28 2000/01/26 21:16:26 peter
  1203. * SMARTLINK=1 split into CREATESMART=1 and LINKSMART=1
  1204. * FPCDIR checks enhanced
  1205. Revision 1.27 2000/01/16 22:26:47 peter
  1206. * use environment variable again for win32, the file writing gives to
  1207. much trouble
  1208. Revision 1.26 2000/01/14 12:14:41 peter
  1209. * sourceinstall updates
  1210. Revision 1.25 2000/01/13 21:08:46 peter
  1211. * zipsourcesinstall
  1212. * zip fixes, bzip2 support with USETAR=bz2
  1213. * multi pkg's support to include several dirs
  1214. Revision 1.24 2000/01/13 11:34:26 peter
  1215. * better package dep creation
  1216. Revision 1.23 2000/01/12 23:20:37 peter
  1217. * gecho support
  1218. * use foreach to write fpcext.cmd
  1219. * add fpcext.cmd to clean targets
  1220. Revision 1.22 2000/01/10 22:55:49 peter
  1221. * zipname creation from packagename
  1222. Revision 1.21 2000/01/08 16:31:04 peter
  1223. * support variable in packagenames
  1224. * fpcmake.loc support
  1225. * fixed place of presettings which must be before FPCDIR is set
  1226. Revision 1.20 2000/01/07 16:46:02 daniel
  1227. * copyright 2000
  1228. Revision 1.19 2000/01/06 15:49:23 peter
  1229. * rtldir removed, it's now handled like any other package
  1230. Revision 1.18 2000/01/06 01:29:59 peter
  1231. * FPCDIR setting/detect
  1232. * lot of other updates to create .deb files correctly
  1233. Revision 1.17 2000/01/04 00:00:23 peter
  1234. * Makefile updates again
  1235. Revision 1.16 2000/01/03 19:42:41 peter
  1236. * regenerated
  1237. Revision 1.15 1999/12/23 19:32:28 peter
  1238. * automatic support for package/target dir structure
  1239. Revision 1.14 1999/12/23 13:52:23 peter
  1240. + default[install,build,clean]dir
  1241. Revision 1.13 1999/12/21 16:06:47 peter
  1242. * don't call dirobjects for zipisntall,info
  1243. Revision 1.12 1999/12/19 15:15:04 peter
  1244. * fpcmade.<TARGET> added
  1245. * parameter support. So it can be using with "find -name 'Makefile.fpc'"
  1246. Revision 1.11 1999/12/02 11:30:24 peter
  1247. * better dup checking
  1248. Revision 1.10 1999/11/26 00:20:15 peter
  1249. * fpcmake updated
  1250. Revision 1.9 1999/11/25 20:23:01 peter
  1251. * package requireencies
  1252. Revision 1.8 1999/11/24 23:53:00 peter
  1253. * packages
  1254. * lot of other changes
  1255. Revision 1.7 1999/11/23 09:43:35 peter
  1256. + internal .ini file
  1257. + packages support
  1258. * ppufiles,data2inc support
  1259. Revision 1.6 1999/11/10 22:10:49 peter
  1260. * fpcmake updated
  1261. Revision 1.5 1999/11/09 14:38:32 peter
  1262. * sections section to leave out whole info/tools
  1263. Revision 1.4 1999/11/08 15:01:39 peter
  1264. * fpcmake support
  1265. Revision 1.3 1999/11/04 12:07:13 michael
  1266. + Now envvar is used
  1267. Revision 1.2 1999/11/03 23:39:53 peter
  1268. * lot of updates
  1269. Revision 1.1 1999/11/02 23:57:40 peter
  1270. * initial version
  1271. }