fpcmake.pp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380
  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 rulediralso[rule] then
  589. begin
  590. if userini.DefaultDir<>'' then
  591. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultdir+')'
  592. else
  593. if (userini.DefaultBuildDir<>'') and (rule2bic[rule]=bic_build) then
  594. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultbuilddir+')'
  595. else
  596. if (userini.DefaultInstallDir<>'') and (rule2bic[rule]=bic_install) then
  597. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultinstalldir+')'
  598. else
  599. if (userini.DefaultZipInstallDir<>'') and (rule2bic[rule]=bic_zipinstall) then
  600. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultzipinstalldir+')'
  601. else
  602. if (userini.DefaultCleanDir<>'') and (rule2bic[rule]=bic_clean) then
  603. hs:=hs+' $(addsuffix _'+rulestr[rule]+','+userini.defaultcleandir+')'
  604. else
  605. if (not TargetStringEmpty(userini.targetdirs)) then
  606. hs:=hs+' $(addsuffix _'+rulestr[rule]+',$(DIROBJECTS))';
  607. end;
  608. end;
  609. if hs<>'' then
  610. begin
  611. Phony:=Phony+' '+rulestr[rule];
  612. mf.Add(rulestr[rule]+':'+hs);
  613. mf.Add('');
  614. end;
  615. end;
  616. procedure AddTargets(const pre:string;var t:TTargetsString;wildcard:boolean);
  617. var
  618. i : integer;
  619. begin
  620. for i:=0 to targets do
  621. if (t[i]<>'') then
  622. begin
  623. if i<>0 then
  624. mf.Add('ifeq ($(OS_TARGET),'+targetstr[i]+')');
  625. if t[i]<>'' then
  626. begin
  627. if wildcard then
  628. mf.Add('override '+pre+'+=$(wildcard '+t[i]+')')
  629. else
  630. mf.Add('override '+pre+'+='+t[i]);
  631. end;
  632. if i<>0 then
  633. mf.Add('endif');
  634. end;
  635. end;
  636. procedure AddTargetDir(const s:string);
  637. var
  638. j : integer;
  639. hs : string;
  640. begin
  641. AddHead('Dir '+s);
  642. mf.Add('ifdef OBJECTDIR'+VarName(s));
  643. hs:='.PHONY: ';
  644. for j:=1to rules do
  645. hs:=hs+' '+s+'_'+rulestr[j];
  646. mf.Add(hs);
  647. mf.Add('');
  648. for j:=1to rules do
  649. begin
  650. mf.Add(s+'_'+rulestr[j]+':');
  651. mf.Add(#9+'$(MAKE) -C '+s+' '+rulestr[j]);
  652. if j<rules then
  653. mf.Add('');
  654. end;
  655. mf.Add('endif');
  656. end;
  657. function AddTargetDefines(const ts:TTargetsString;const prefix:string):string;
  658. var
  659. k1,k2,k3,j,i : integer;
  660. name,hs,hs2,hs3 : string;
  661. begin
  662. hs2:='';
  663. for j:=0 to targets do
  664. if (ts[j]<>'') then
  665. begin
  666. if j<>0 then
  667. mf.Add('ifeq ($(OS_TARGET),'+targetstr[j]+')');
  668. hs:=ts[j];
  669. repeat
  670. i:=pos(' ',hs);
  671. if i=0 then
  672. i:=length(hs)+1;
  673. name:=Copy(hs,1,i-1);
  674. k1:=pos('{',name);
  675. if k1>0 then
  676. begin
  677. k2:=PosIdx('}',name,k1);
  678. if k2=0 then
  679. begin
  680. Writeln('Error: missing closing } for "',name,'"');
  681. k2:=length(name)+1;
  682. end;
  683. hs3:=Copy(name,k1+1,k2-k1-1);
  684. for k3:=1to length(hs3) do
  685. if hs3[k3]=',' then
  686. hs3[k3]:=' ';
  687. name:=Copy(name,1,k1-1);
  688. mf.Add(prefix+VarName(name)+'='+hs3);
  689. end
  690. else
  691. mf.Add(prefix+VarName(name)+'=1');
  692. { add to the list of dirs without duplicates }
  693. AddStrNoDup(hs2,name);
  694. system.delete(hs,1,i);
  695. until hs='';
  696. if j<>0 then
  697. mf.Add('endif');
  698. end;
  699. AddTargetDefines:=hs2;
  700. end;
  701. procedure AddPackage(const path,pack:string);
  702. var
  703. k : integer;
  704. packdirvar,unitdirvar,unitdir,packdir : string;
  705. begin
  706. mf.Add('ifdef PACKAGE'+VarName(pack));
  707. { create needed variables }
  708. packdirvar:='PACKAGEDIR_'+VarName(pack);
  709. unitdirvar:='UNITDIR_'+VarName(pack);
  710. packdir:=path+'/'+pack;
  711. unitdir:='$(UNITSDIR)/'+pack;
  712. for k:=1to specialdirs do
  713. begin
  714. if specialdir[k].dir=pack then
  715. begin
  716. packdir:=specialdir[k].packdir;
  717. unitdir:=specialdir[k].unitdir;
  718. break;
  719. end;
  720. end;
  721. mf.Add('ifneq ($(wildcard '+packdir+'),)');
  722. { Use Package dir, add build rules }
  723. mf.Add('ifneq ($(wildcard '+packdir+'/$(OS_TARGET)),)');
  724. mf.Add(packdirvar+'='+packdir+'/$(OS_TARGET)');
  725. mf.Add('else');
  726. mf.Add(packdirvar+'='+packdir);
  727. mf.Add('endif');
  728. mf.Add('ifeq ($(wildcard $('+packdirvar+')/$(FPCMADE)),)');
  729. mf.Add('override COMPILEPACKAGES+=package_'+pack);
  730. Phony:=Phony+'package_'+pack;
  731. mf.Add('package_'+pack+':');
  732. mf.Add(#9'$(MAKE) -C $('+packdirvar+') all');
  733. mf.Add('endif');
  734. mf.Add(unitdirvar+'=$('+packdirvar+')');
  735. mf.Add('else');
  736. { Package dir doesn''t exists, create unit dir }
  737. mf.Add(packdirvar+'=');
  738. mf.Add('ifneq ($(wildcard '+unitdir+'),)');
  739. mf.Add('ifneq ($(wildcard '+unitdir+'/$(OS_TARGET)),)');
  740. mf.Add(unitdirvar+'='+unitdir+'/$(OS_TARGET)');
  741. mf.Add('else');
  742. mf.Add(unitdirvar+'='+unitdir);
  743. mf.Add('endif');
  744. mf.Add('else');
  745. mf.Add(unitdirvar+'=');
  746. mf.Add('endif');
  747. mf.Add('endif');
  748. { Add Unit dir to the command line -Fu }
  749. mf.Add('ifdef '+unitdirvar);
  750. mf.Add('override NEEDUNITDIR+=$('+unitdirvar+')');
  751. mf.Add('endif');
  752. mf.Add('endif');
  753. end;
  754. procedure AddTargetsPackages(const path:string;const ts:TTargetsString);
  755. var
  756. Phony,hs : string;
  757. i : integer;
  758. begin
  759. { Components }
  760. Phony:='';
  761. if not TargetStringEmpty(ts) then
  762. begin
  763. AddHead(VarName(path)+' packages');
  764. hs:=AddTargetDefines(ts,'PACKAGE');
  765. mf.Add('');
  766. repeat
  767. i:=pos(' ',hs);
  768. if i=0 then
  769. i:=length(hs)+1;
  770. AddPackage(path,Copy(hs,1,i-1));
  771. system.delete(hs,1,i);
  772. until hs='';
  773. mf.Add('');
  774. end;
  775. if Phony<>'' then
  776. begin
  777. mf.Add('.PHONY: '+Phony);
  778. mf.Add('');
  779. end;
  780. end;
  781. procedure AddPkg(const pack:string);
  782. var
  783. j : integer;
  784. packname,pkgdirsvar,hs : string;
  785. begin
  786. packname:=pack;
  787. AddHead('Pkg '+packname);
  788. mf.Add('ifdef PKG'+VarName(packname));
  789. hs:='.PHONY: ';
  790. for j:=1 to rules do
  791. hs:=hs+' pkg'+packname+'_'+rulestr[j];
  792. mf.Add(hs);
  793. mf.Add('');
  794. { pkgall is special which processes all directories }
  795. if pack='all' then
  796. pkgdirsvar:='DIROBJECTS'
  797. else
  798. begin
  799. mf.Add('override PKGOBJECTS+=pkg'+packname);
  800. pkgdirsvar:='PKG'+VarName(packname);
  801. end;
  802. for j:=1to rules do
  803. if rulediralso[j] then
  804. begin
  805. mf.Add('pkg'+packname+'_'+rulestr[j]+': $(addsuffix _'+rulestr[j]+',$('+pkgdirsvar+'))');
  806. if j<rules then
  807. mf.Add('');
  808. end
  809. else
  810. begin
  811. { zipinstall is special for pkgs }
  812. if (rulestr[j]='zipinstall') then
  813. begin
  814. mf.Add('pkg'+packname+'_'+rulestr[j]+':');
  815. mf.Add(#9'$(MAKE) fpc_zipinstall PACKAGENAME='+packname+
  816. ' ZIPTARGET=pkg'+packname+'_install');
  817. if j<rules then
  818. mf.Add('');
  819. end
  820. else
  821. if (rulestr[j]='zipsourceinstall') then
  822. begin
  823. mf.Add('pkg'+packname+'_'+rulestr[j]+':');
  824. mf.Add(#9'$(MAKE) fpc_zipinstall PACKAGENAME='+packname+
  825. ' PACKAGESUFFIX=src ZIPTARGET=pkg'+packname+'_sourceinstall');
  826. if j<rules then
  827. mf.Add('');
  828. end;
  829. end;
  830. mf.Add('endif');
  831. end;
  832. procedure AddTargetsPkgs(const ts:TTargetsString);
  833. var
  834. Phony,hs : string;
  835. i : integer;
  836. begin
  837. { Components }
  838. Phony:='';
  839. if not TargetStringEmpty(ts) then
  840. begin
  841. hs:=AddTargetDefines(ts,'PKG');
  842. mf.Add('');
  843. repeat
  844. i:=pos(' ',hs);
  845. if i=0 then
  846. i:=length(hs)+1;
  847. AddPkg(Copy(hs,1,i-1));
  848. system.delete(hs,1,i);
  849. until hs='';
  850. mf.Add('');
  851. end;
  852. if Phony<>'' then
  853. begin
  854. mf.Add('.PHONY: '+Phony);
  855. mf.Add('');
  856. end;
  857. end;
  858. var
  859. hs : string;
  860. i : integer;
  861. begin
  862. { Open the Makefile }
  863. mf:=TStringList.Create;
  864. { Buffer for reading and writing the sections }
  865. ss:=TStringList.Create;
  866. with mf do
  867. begin
  868. { write header & autodetection }
  869. Add('#');
  870. Add('# Makefile generated by '+titledate);
  871. Add('#');
  872. Add('');
  873. Add('defaultrule: '+userini.defaultrule);
  874. Add('');
  875. AddSection(true,'osdetect');
  876. { set the forced target os/cpu }
  877. if (userini.defaulttarget<>'') or (userini.defaultcpu<>'') then
  878. begin
  879. AddSection(true,'defaulttarget');
  880. if userini.defaulttarget<>'' then
  881. Add('override OS_TARGET:='+userini.defaulttarget);
  882. if userini.defaultcpu<>'' then
  883. Add('override CPU_TARGET:='+userini.defaultcpu);
  884. Add('');
  885. end;
  886. { fpc detection }
  887. AddSection(true,'fpcdetect');
  888. { Pre Settings }
  889. if userini.PreSettings.count>0 then
  890. begin
  891. AddSection(true,'presettings');
  892. AddStrings(userini.PreSettings);
  893. end;
  894. { fpc dir }
  895. AddSection(true,'fpcdircheckenv');
  896. if userini.dirfpc<>'' then
  897. begin
  898. Add('# Default FPCDIR');
  899. Add('ifeq ($(FPCDIR),wrong)');
  900. Add('override FPCDIR='+userini.dirfpc);
  901. Add('ifeq ($(wildcard $(FPCDIR)/rtl),)');
  902. Add('ifeq ($(wildcard $(FPCDIR)/units),)');
  903. Add('override FPCDIR=wrong');
  904. Add('endif');
  905. Add('endif');
  906. Add('endif');
  907. Add('');
  908. end;
  909. AddSection(true,'fpcdirdetect');
  910. { fpcdir subdirs }
  911. if userini.RequireRTL then
  912. begin
  913. Add('ifndef PACKAGESDIR');
  914. Add('PACKAGESDIR='+userini.dirpackage);
  915. Add('endif');
  916. Add('ifndef TOOLKITSDIR');
  917. Add('TOOLKITSDIR='+userini.dirtoolkit);
  918. Add('endif');
  919. Add('ifndef COMPONENTSDIR');
  920. Add('COMPONENTSDIR='+userini.dircomponent);
  921. Add('endif');
  922. Add('');
  923. AddSection(true,'fpcdirsubs');
  924. end;
  925. { write the default & user settings }
  926. AddSection(true,'usersettings');
  927. { Targets }
  928. AddHead('Targets');
  929. AddTargets('DIROBJECTS',userini.targetdirs,true);
  930. AddTargets('LOADEROBJECTS',userini.targetloaders,false);
  931. AddTargets('UNITOBJECTS',userini.targetunits,false);
  932. AddTargets('EXEOBJECTS',userini.targetprograms,false);
  933. AddTargets('EXAMPLEOBJECTS',userini.targetexamples,false);
  934. AddTargets('RSTOBJECTS',userini.targetrst,false);
  935. { Clean }
  936. AddHead('Clean');
  937. AddTargets('EXTRACLEANUNITS',userini.cleanunits,false);
  938. AddTargets('EXTRACLEANFILES',userini.cleanfiles,false);
  939. { Install }
  940. AddHead('Install');
  941. AddTargets('EXTRAINSTALLUNITS',userini.installunits,false);
  942. AddTargets('EXTRAINSTALLFILES',userini.installfiles,false);
  943. if userini.installprefixdir<>'' then
  944. Add('PREFIXINSTALLDIR='+userini.installprefixdir);
  945. if userini.installbasedir<>'' then
  946. Add('BASEINSTALLDIR='+userini.installbasedir);
  947. if userini.installdatadir<>'' then
  948. Add('DATAINSTALLDIR='+userini.installdatadir);
  949. if userini.InstallUnitSubDir<>'' then
  950. Add('UNITSUBDIR='+userini.InstallUnitSubDir);
  951. if userini.installpackagename<>'' then
  952. Add('PACKAGENAME='+userini.installpackagename);
  953. { Zip }
  954. if userini.zipname<>'' then
  955. Add('ZIPNAME='+userini.zipname);
  956. if userini.ziptarget<>'' then
  957. Add('ZIPTARGET='+userini.ziptarget);
  958. { Defaults }
  959. AddHead('Defaults');
  960. if userini.Requireoptions<>'' then
  961. Add('override NEEDOPT='+userini.Requireoptions);
  962. { Dirs }
  963. AddHead('Directories');
  964. if userini.dirsources<>'' then
  965. Add('vpath %$(PASEXT) '+userini.dirsources);
  966. if userini.dirunit<>'' then
  967. Add('override NEEDUNITDIR='+userini.dirunit);
  968. if userini.dirlib<>'' then
  969. Add('override NEEDLIBDIR='+userini.dirlib);
  970. if userini.dirobj<>'' then
  971. Add('override NEEDOBJDIR='+userini.dirobj);
  972. if userini.dirinc<>'' then
  973. Add('override NEEDINCDIR='+userini.dirinc);
  974. if userini.dirtarget<>'' then
  975. begin
  976. Add('ifndef TARGETDIR');
  977. Add('TARGETDIR='+userini.dirtarget);
  978. Add('endif');
  979. end;
  980. if userini.dirunittarget<>'' then
  981. begin
  982. Add('ifndef UNITTARGETDIR');
  983. Add('UNITTARGETDIR='+userini.dirunittarget);
  984. Add('endif');
  985. end;
  986. { Packages }
  987. AddHead('Packages');
  988. Phony:='';
  989. AddTargets('PACKAGES',userini.Requirepackages,false);
  990. AddTargets('TOOLKITS',userini.Requiretoolkits,false);
  991. AddTargets('COMPONENTS',userini.Requirecomponents,false);
  992. if Phony<>'' then
  993. begin
  994. Add('.PHONY: '+Phony);
  995. Add('');
  996. end;
  997. { Libs }
  998. AddHead('Libraries');
  999. if userini.libname<>'' then
  1000. Add('LIBNAME='+userini.libname);
  1001. if userini.libunits<>'' then
  1002. Add('SHAREDLIBUNITOBJECTS='+userini.libunits);
  1003. if userini.libgcc then
  1004. Add('override NEEDGCCLIB=1');
  1005. if userini.libother then
  1006. Add('override NEEDOTHERLIB=1');
  1007. { Info }
  1008. if userini.Section[sec_Info] then
  1009. begin
  1010. AddHead('Info');
  1011. hs:='';
  1012. if userini.infocfg then
  1013. hs:=hs+'fpc_infocfg ';
  1014. if userini.infodirs then
  1015. hs:=hs+'fpc_infodirs ';
  1016. if userini.infotools then
  1017. hs:=hs+'fpc_infotools ';
  1018. if userini.infoobjects then
  1019. hs:=hs+'fpc_infoobjects ';
  1020. if userini.infoinstall then
  1021. hs:=hs+'fpc_infoinstall ';
  1022. Add('INFOTARGET='+hs);
  1023. end;
  1024. Add('');
  1025. { Post Settings }
  1026. if userini.PostSettings.count>0 then
  1027. begin
  1028. AddSection(true,'postsettings');
  1029. AddStrings(userini.PostSettings);
  1030. Add('');
  1031. end;
  1032. { shell tools like copy,del,echo }
  1033. AddSection(userini.section[sec_command] or userini.section[sec_tools],'shelltools');
  1034. { write tools }
  1035. AddSection(userini.section[sec_tools],'tool_default');
  1036. AddSection(userini.toolsppdep,'tool_ppdep');
  1037. AddSection(userini.toolsppumove,'tool_ppumove');
  1038. AddSection(userini.toolsppufiles,'tool_ppufiles');
  1039. AddSection(userini.toolsdata2inc,'tool_data2inc');
  1040. AddSection(userini.toolsupx,'tool_upx');
  1041. AddSection(userini.toolssed,'tool_sed');
  1042. AddSection(userini.toolscmp,'tool_cmp');
  1043. AddSection(userini.toolsdiff,'tool_diff');
  1044. AddSection(userini.toolsdate,'tool_date');
  1045. AddSection(userini.toolszip,'tool_zip');
  1046. AddSection(userini.toolstar,'tool_tar');
  1047. { extensions }
  1048. if userini.section[sec_exts] then
  1049. AddSection(true,'extensions');
  1050. { package/component dirs }
  1051. AddSection(true,'packagerequirerules');
  1052. AddSection(userini.requirertl,'checkfpcdirsubs');
  1053. AddTargetsPackages('$(PACKAGESDIR)',userini.Requirepackages);
  1054. AddTargetsPackages('$(TOOLKITSDIR)',userini.Requiretoolkits);
  1055. AddTargetsPackages('$(COMPONENTSDIR)',userini.Requirecomponents);
  1056. Add('');
  1057. { Pkgs }
  1058. AddTargetsPkgs(userini.targetpkgs);
  1059. { write dirs }
  1060. AddSection(true,'dir_default');
  1061. if userini.section[sec_dirs] then
  1062. begin
  1063. AddSection(userini.libgcc,'dir_gcclib');
  1064. AddSection(userini.libother,'dir_otherlib');
  1065. AddSection(true,'dir_install');
  1066. end;
  1067. { redirection }
  1068. AddSection(true,'redir');
  1069. { commandline }
  1070. if userini.section[sec_command] then
  1071. begin
  1072. Add('');
  1073. AddSection(true,'command_begin');
  1074. AddSection((userini.Requireoptions<>''),'command_needopt');
  1075. AddSection((userini.dirunit<>'') or
  1076. (not TargetStringEmpty(userini.Requiretoolkits)) or
  1077. (not TargetStringEmpty(userini.Requirepackages)) or
  1078. (not TargetStringEmpty(userini.Requirecomponents))
  1079. ,'command_needunit');
  1080. AddSection(true,'command_unitsdir');
  1081. AddSection((userini.dirlib<>''),'command_needlib');
  1082. AddSection((userini.dirobj<>''),'command_needobj');
  1083. AddSection((userini.dirinc<>''),'command_needinc');
  1084. AddSection(userini.libgcc,'command_gcclib');
  1085. AddSection(userini.libother,'command_otherlib');
  1086. AddSection((userini.dirinc<>''),'command_inc');
  1087. AddSection((userini.dirtarget<>''),'command_target');
  1088. AddSection((userini.dirunittarget<>''),'command_unittarget');
  1089. AddSection(true,'command_end');
  1090. AddSection(true,'command_win32env');
  1091. AddSection(true,'command_compiler');
  1092. end;
  1093. { add default rules }
  1094. AddSection(true,'standardrules');
  1095. Phony:='';
  1096. for i:=1 to rules do
  1097. AddRule(i);
  1098. if Phony<>'' then
  1099. begin
  1100. Add('.PHONY: '+Phony);
  1101. Add('');
  1102. end;
  1103. { compile rules for making loaders/units/exes/examples }
  1104. AddSection(not TargetStringEmpty(userini.targetloaders),'loaderrules');
  1105. AddSection(not TargetStringEmpty(userini.targetunits),'unitrules');
  1106. AddSection(not TargetStringEmpty(userini.targetprograms),'exerules');
  1107. AddSection(not TargetStringEmpty(userini.targetexamples),'examplerules');
  1108. AddSection(not TargetStringEmpty(userini.targetrst),'rstrules');
  1109. { default fpc_ rules }
  1110. AddSection(userini.Section[sec_Compile],'compilerules');
  1111. AddSection(userini.Section[sec_Libs],'libraryrules');
  1112. AddSection(userini.Section[sec_Install],'installrules');
  1113. AddSection(userini.Section[sec_SourceInstall],'sourceinstallrules');
  1114. AddSection(userini.Section[sec_ZipInstall],'zipinstallrules');
  1115. AddSection(userini.Section[sec_ZipSourceInstall],'zipsourceinstallrules');
  1116. AddSection(userini.Section[sec_Clean],'cleanrules');
  1117. AddSection(userini.Section[sec_require],'requirerules');
  1118. if userini.Section[sec_Info] then
  1119. begin
  1120. AddSection(true,'inforules');
  1121. AddSection(userini.infocfg,'info_cfg');
  1122. AddSection(userini.infodirs,'info_dirs');
  1123. AddSection(userini.infotools,'info_tools');
  1124. AddSection(userini.infoobjects,'info_objects');
  1125. AddSection(userini.infoinstall,'info_install');
  1126. end;
  1127. { Target dirs }
  1128. if not TargetStringEmpty(userini.targetdirs) then
  1129. begin
  1130. AddSection(true,'directorytargets');
  1131. hs:=AddTargetDefines(userini.targetdirs,'OBJECTDIR');
  1132. repeat
  1133. i:=pos(' ',hs);
  1134. if i=0 then
  1135. i:=length(hs)+1;
  1136. AddTargetDir(Copy(hs,1,i-1));
  1137. system.delete(hs,1,i);
  1138. until hs='';
  1139. Add('');
  1140. end;
  1141. { local makefile }
  1142. AddSection(true,'localmakefile');
  1143. { insert users rules }
  1144. if userini.rules.count>0 then
  1145. begin
  1146. AddSection(true,'userrules');
  1147. AddStrings(userini.rules);
  1148. end;
  1149. end;
  1150. { Write the Makefile and cleanup }
  1151. Verbose('Writing '+fn);
  1152. FixTab(mf);
  1153. mf.SaveToFile(fn);
  1154. mf.Destroy;
  1155. ss.Destroy;
  1156. WriteMakefile:=true;
  1157. end;
  1158. procedure UseMakefilefpc;
  1159. var
  1160. fn : string;
  1161. begin
  1162. if FileExists('Makefile.fpc') then
  1163. fn:='Makefile.fpc'
  1164. else
  1165. fn:='makefile.fpc';
  1166. { Open Makefile.fpc }
  1167. if not ReadMakefilefpc(fn) then
  1168. Error('Can''t read '+fn);
  1169. { Write Makefile }
  1170. if not WriteMakefile('Makefile') then
  1171. Error('Can''t write Makefile');
  1172. end;
  1173. procedure UseParameters;
  1174. var
  1175. i : integer;
  1176. fn : string;
  1177. begin
  1178. for i:=1 to ParamCount do
  1179. begin
  1180. fn:=ParamStr(i);
  1181. { Open Makefile.fpc }
  1182. if not ReadMakefilefpc(fn) then
  1183. Error('Can''t read '+fn);
  1184. { Write Makefile }
  1185. if not WriteMakefile(ExtractFilePath(fn)+'Makefile') then
  1186. Error('Can''t write '+ExtractFilePath(fn)+'Makefile');
  1187. end;
  1188. end;
  1189. begin
  1190. { Open userini.ini }
  1191. fpcini:=ReadFpcMakeIni;
  1192. if not assigned(fpcini) then
  1193. Error('Can''t read fpcmake.ini');
  1194. if ParamCount=0 then
  1195. UseMakefilefpc
  1196. else
  1197. UseParameters;
  1198. fpcini.destroy;
  1199. end.
  1200. {
  1201. $Log$
  1202. Revision 1.32 2000-02-09 16:44:14 peter
  1203. * log truncated
  1204. Revision 1.31 2000/02/08 00:03:35 peter
  1205. * fixed zipinstall with defaultdir
  1206. Revision 1.30 2000/02/02 11:30:00 peter
  1207. * fixed sharedlibunitobjects typo
  1208. Revision 1.29 2000/01/28 12:10:46 peter
  1209. * reinserted lost diff of rev 1.30
  1210. * distclean target
  1211. Revision 1.28 2000/01/26 21:16:26 peter
  1212. * SMARTLINK=1 split into CREATESMART=1 and LINKSMART=1
  1213. * FPCDIR checks enhanced
  1214. Revision 1.27 2000/01/16 22:26:47 peter
  1215. * use environment variable again for win32, the file writing gives to
  1216. much trouble
  1217. Revision 1.26 2000/01/14 12:14:41 peter
  1218. * sourceinstall updates
  1219. Revision 1.25 2000/01/13 21:08:46 peter
  1220. * zipsourcesinstall
  1221. * zip fixes, bzip2 support with USETAR=bz2
  1222. * multi pkg's support to include several dirs
  1223. Revision 1.24 2000/01/13 11:34:26 peter
  1224. * better package dep creation
  1225. Revision 1.23 2000/01/12 23:20:37 peter
  1226. * gecho support
  1227. * use foreach to write fpcext.cmd
  1228. * add fpcext.cmd to clean targets
  1229. Revision 1.22 2000/01/10 22:55:49 peter
  1230. * zipname creation from packagename
  1231. Revision 1.21 2000/01/08 16:31:04 peter
  1232. * support variable in packagenames
  1233. * fpcmake.loc support
  1234. * fixed place of presettings which must be before FPCDIR is set
  1235. Revision 1.20 2000/01/07 16:46:02 daniel
  1236. * copyright 2000
  1237. Revision 1.19 2000/01/06 15:49:23 peter
  1238. * rtldir removed, it's now handled like any other package
  1239. Revision 1.18 2000/01/06 01:29:59 peter
  1240. * FPCDIR setting/detect
  1241. * lot of other updates to create .deb files correctly
  1242. Revision 1.17 2000/01/04 00:00:23 peter
  1243. * Makefile updates again
  1244. Revision 1.16 2000/01/03 19:42:41 peter
  1245. * regenerated
  1246. Revision 1.15 1999/12/23 19:32:28 peter
  1247. * automatic support for package/target dir structure
  1248. Revision 1.14 1999/12/23 13:52:23 peter
  1249. + default[install,build,clean]dir
  1250. Revision 1.13 1999/12/21 16:06:47 peter
  1251. * don't call dirobjects for zipisntall,info
  1252. Revision 1.12 1999/12/19 15:15:04 peter
  1253. * fpcmade.<TARGET> added
  1254. * parameter support. So it can be using with "find -name 'Makefile.fpc'"
  1255. }