fpcmake.pp 39 KB

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