fpcmake.pp 39 KB

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