fpcmake.pp 42 KB

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