fpcmake.pp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. {
  2. $Id$
  3. Copyright (c) 1999 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. sysutils,classes,inifiles;
  19. const
  20. Version='v0.99.13';
  21. Title='fpcmake '+Version;
  22. const
  23. sec_dirs='dirs';
  24. sec_libs='libs';
  25. sec_targets='targets';
  26. sec_info='info';
  27. sec_misc='misc';
  28. sec_rules='rules';
  29. type
  30. TFpcMake=record
  31. DefaultUnits : boolean;
  32. TargetUnits,
  33. TargetPrograms : string;
  34. DirUnit,
  35. DirLib,
  36. DirObj,
  37. DirTarget,
  38. DirUnitTarget,
  39. DirInc,
  40. DirProcInc,
  41. DirOSInc : string;
  42. LibGCC,
  43. LibOther : boolean;
  44. InfoCfg,
  45. InfoDir,
  46. InfoTools,
  47. InfoInstall,
  48. InfoObjects,
  49. InfoFiles : boolean;
  50. Rules : TStringList;
  51. end;
  52. var
  53. userini : TFpcMake;
  54. fpcini : TIniFile;
  55. {*****************************************************************************
  56. Helpers
  57. *****************************************************************************}
  58. procedure Verbose(s:string);
  59. begin
  60. writeln(s);
  61. end;
  62. procedure Error(s:string);
  63. begin
  64. Writeln(s);
  65. Halt(1);
  66. end;
  67. {*****************************************************************************
  68. Makefile.fpc reading
  69. *****************************************************************************}
  70. function ReadMakefilefpc:boolean;
  71. var
  72. fn : string;
  73. ini : TIniFile;
  74. begin
  75. ReadMakefilefpc:=false;
  76. if FileExists('Makefile.fpc') then
  77. fn:='Makefile.fpc'
  78. else
  79. if FileExists('makefile.fpc') then
  80. fn:='makefile.fpc'
  81. else
  82. exit;
  83. Verbose('Reading '+fn);
  84. ini:=TIniFile.Create(fn);
  85. with userini,ini do
  86. begin
  87. { targets }
  88. DefaultUnits:=ReadBool(sec_targets,'defaultunits',false);
  89. TargetUnits:=ReadString(sec_targets,'units','');
  90. TargetPrograms:=ReadString(sec_targets,'programs','');
  91. { dirs }
  92. DirUnit:=ReadString(sec_dirs,'unit','');
  93. DirLib:=ReadString(sec_dirs,'lib','');
  94. DirObj:=ReadString(sec_dirs,'obj','');
  95. DirTarget:=ReadString(sec_dirs,'target','');
  96. DirUnitTarget:=ReadString(sec_dirs,'unittarget','');
  97. DirInc:=ReadString(sec_dirs,'inc','');
  98. DirProcInc:=ReadString(sec_dirs,'procinc','');
  99. DirOSInc:=ReadString(sec_dirs,'osinc','');
  100. { libs }
  101. LibGcc:=ReadBool(sec_libs,'gcc',false);
  102. LibOther:=ReadBool(sec_libs,'other',false);
  103. { info }
  104. InfoCfg:=ReadBool(sec_info,'config',true);
  105. InfoDir:=ReadBool(sec_info,'dir',false);
  106. InfoTools:=ReadBool(sec_info,'tools',false);
  107. InfoInstall:=ReadBool(sec_info,'install',true);
  108. InfoObjects:=ReadBool(sec_info,'objects',true);
  109. InfoFiles:=ReadBool(sec_info,'files',false);
  110. { rules }
  111. rules:=TStringList.Create;
  112. ReadSectionRaw(sec_rules,rules);
  113. end;
  114. ini.Destroy;
  115. ReadMakefilefpc:=true;
  116. end;
  117. {*****************************************************************************
  118. userini.ini loading
  119. *****************************************************************************}
  120. function ReadFpcMakeIni:TIniFile;
  121. var
  122. fn : string;
  123. begin
  124. ReadFpcMakeIni:=nil;
  125. if FileExists('userini.ini') then
  126. fn:='userini.ini'
  127. else
  128. {$ifdef linux}
  129. if FileExists('/usr/lib/fpc/userini.ini') then
  130. fn:='/usr/lib/fpc/userini.ini'
  131. {$else}
  132. if FileExists(paramstr(0)+'/userini.ini') then
  133. fn:=paramstr(0)+'/userini.ini'
  134. {$endif}
  135. else
  136. exit;
  137. Verbose('Opening '+fn);
  138. result:=TIniFile.Create(fn);
  139. end;
  140. {*****************************************************************************
  141. Makefile writing
  142. *****************************************************************************}
  143. function WriteMakefile:boolean;
  144. var
  145. mf : TStringList;
  146. ss : TStringList;
  147. procedure FixTab(sl:TStringList);
  148. var
  149. i,j,k : integer;
  150. s,s2 : string;
  151. begin
  152. i:=0;
  153. while (i<sl.Count) do
  154. begin
  155. if sl[i][1] in [' ',#9] then
  156. begin
  157. s:=sl[i];
  158. k:=0;
  159. j:=0;
  160. repeat
  161. inc(j);
  162. case s[j] of
  163. ' ' :
  164. inc(k);
  165. #9 :
  166. k:=(k+7) and not(7);
  167. else
  168. break;
  169. end;
  170. until (j=length(s));
  171. if k>7 then
  172. begin
  173. s2:='';
  174. Delete(s,1,j-1);
  175. while (k>7) do
  176. begin
  177. s2:=s2+#9;
  178. dec(k,8);
  179. end;
  180. while (k>0) do
  181. begin
  182. s2:=s2+' ';
  183. dec(k);
  184. end;
  185. sl[i]:=s2+s;
  186. end;
  187. end;
  188. inc(i);
  189. end;
  190. end;
  191. procedure AddSection(b:boolean;s:string);
  192. begin
  193. if b then
  194. begin
  195. ss.Clear;
  196. fpcini.ReadSectionRaw(s,ss);
  197. mf.AddStrings(ss);
  198. mf.Add('');
  199. end;
  200. end;
  201. procedure AddRule(s:string);
  202. var
  203. i : integer;
  204. begin
  205. i:=0;
  206. while (i<userini.rules.Count) do
  207. begin
  208. if (userini.rules[i][1]=s[1]) and
  209. (Copy(userini.rules[i],1,length(s))=s) then
  210. exit;
  211. inc(i);
  212. end;
  213. mf.Add(s+': fpc_'+s);
  214. mf.Add('');
  215. end;
  216. var
  217. hs : string;
  218. begin
  219. { Open the Makefile }
  220. Verbose('Creating Makefile');
  221. mf:=TStringList.Create;
  222. { Buffer for reading and writing the sections }
  223. ss:=TStringList.Create;
  224. with mf do
  225. begin
  226. { write header & autodetection }
  227. Add('#');
  228. Add('# Makefile generated from Makefile.fpc by '+Title);
  229. Add('#');
  230. Add('');
  231. AddSection(true,'osdetect');
  232. AddSection(true,'fpcdetect');
  233. { write the default & user settings }
  234. AddSection(true,'defaultsettings');
  235. AddSection(true,'usersettings');
  236. { Targets }
  237. if userini.defaultunits then
  238. Add('DEFAULTUNITS=1');
  239. Add('UNITOBJECTS='+userini.targetunits);
  240. Add('EXEOBJECTS='+userini.targetprograms);
  241. { Dirs }
  242. if userini.dirunit<>'' then
  243. Add('NEEDUNITDIR='+userini.dirunit);
  244. if userini.dirlib<>'' then
  245. Add('NEEDLIBDIR='+userini.dirlib);
  246. if userini.dirobj<>'' then
  247. Add('NEEDOBJDIR='+userini.dirobj);
  248. if userini.dirinc<>'' then
  249. Add('INC='+userini.dirinc);
  250. if userini.dirprocinc<>'' then
  251. Add('PROCINC='+userini.dirprocinc);
  252. if userini.dirosinc<>'' then
  253. Add('OSINC='+userini.dirosinc);
  254. if userini.dirtarget<>'' then
  255. Add('TARGETDIR='+userini.dirtarget);
  256. if userini.dirunittarget<>'' then
  257. Add('UNITTARGETDIR='+userini.dirunittarget);
  258. { Libs }
  259. if userini.libgcc then
  260. Add('NEEDGCCLIB=1');
  261. if userini.libother then
  262. Add('NEEDOTHERLIB=1');
  263. { Info }
  264. Add('');
  265. hs:='';
  266. if userini.infocfg then
  267. hs:=hs+'fpc_infocfg ';
  268. if userini.infodir then
  269. hs:=hs+'fpc_infodir ';
  270. if userini.infotools then
  271. hs:=hs+'fpc_infotools ';
  272. if userini.infoinstall then
  273. hs:=hs+'fpc_infoinstall ';
  274. if userini.infofiles then
  275. hs:=hs+'fpc_infofiles ';
  276. Add('FPCINFO='+hs);
  277. { commandline }
  278. Add('');
  279. AddSection(true,'command_begin');
  280. AddSection(true,'command_rtl');
  281. AddSection(true,'command_needopt');
  282. AddSection((userini.dirunit<>''),'command_needunit');
  283. AddSection((userini.dirlib<>''),'command_needlib');
  284. AddSection((userini.dirobj<>''),'command_needobj');
  285. AddSection(userini.libgcc,'command_gcclib');
  286. AddSection(userini.libother,'command_otherlib');
  287. AddSection((userini.dirinc<>''),'command_inc');
  288. AddSection((userini.dirprocinc<>''),'command_procinc');
  289. AddSection((userini.dirosinc<>''),'command_osinc');
  290. AddSection((userini.dirtarget<>''),'command_target');
  291. AddSection((userini.dirunittarget<>''),'command_unittarget');
  292. AddSection(true,'command_smartlink');
  293. AddSection(true,'command_end');
  294. { write tools }
  295. AddSection(true,'shelltools');
  296. AddSection(true,'tool_default');
  297. AddSection(true,'tool_upx');
  298. AddSection(true,'tool_sed');
  299. AddSection(true,'tool_date');
  300. AddSection(true,'tool_zip');
  301. AddSection(true,'tool_cmp');
  302. AddSection(true,'tool_diff');
  303. { write dirs }
  304. AddSection(true,'dir_default');
  305. AddSection(true,'dir_rtl');
  306. AddSection(true,'dir_units');
  307. AddSection(true,'dir_gcclib');
  308. AddSection(true,'dir_otherlib');
  309. AddSection(true,'dir_install');
  310. { extensions }
  311. AddSection(true,'extensions');
  312. { add default rules }
  313. AddSection(true,'defaultrules');
  314. AddRule('all');
  315. AddRule('staticlib');
  316. AddRule('sharedlib');
  317. AddRule('install');
  318. AddRule('staticinstall');
  319. AddRule('sharedinstall');
  320. AddRule('libinstall');
  321. AddRule('zipinstall');
  322. AddRule('zipinstalladd');
  323. AddRule('clean');
  324. AddRule('depend');
  325. AddRule('info');
  326. { default fpc_ rules }
  327. AddSection(true,'compilerules');
  328. AddSection(true,'libraryrules');
  329. AddSection(true,'installrules');
  330. AddSection(true,'zipinstallrules');
  331. AddSection(true,'cleanrules');
  332. AddSection(true,'dependrules');
  333. AddSection(true,'inforules');
  334. AddSection(userini.infocfg,'info_cfg');
  335. AddSection(userini.infodir,'info_dir');
  336. AddSection(userini.infotools,'info_tools');
  337. AddSection(userini.infoobjects,'info_object');
  338. AddSection(userini.infoinstall,'info_install');
  339. AddSection(userini.infofiles,'info_files');
  340. { insert users rules }
  341. if userini.rules.count>0 then
  342. begin
  343. AddSection(true,'userrules');
  344. AddStrings(userini.rules);
  345. end;
  346. end;
  347. { Write the Makefile and cleanup }
  348. Verbose('Writing Makefile');
  349. FixTab(mf);
  350. mf.SaveToFile('Makefile');
  351. mf.Destroy;
  352. ss.Destroy;
  353. WriteMakefile:=true;
  354. end;
  355. begin
  356. { Open userini.ini }
  357. fpcini:=ReadFpcMakeIni;
  358. if not assigned(fpcini) then
  359. Error('Can''t read userini.ini');
  360. { Open Makefile.fpc }
  361. if not ReadMakefilefpc then
  362. Error('Can''t read Makefile.fpc');
  363. { Write Makefile }
  364. if not WriteMakefile then
  365. Error('Can''t write Makefile');
  366. fpcini.destroy;
  367. end.
  368. {
  369. $Log$
  370. Revision 1.1 1999-11-02 23:57:40 peter
  371. * initial version
  372. }