fpcmake.pp 39 KB

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