fpcmake.pp 42 KB

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