fpmake.pp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. {$IFDEF MORPHOS}
  2. {$DEFINE NO_UNIT_PROCESS}
  3. {$DEFINE NO_THREADING}
  4. {$ENDIF}
  5. {$IFDEF AROS}
  6. {$DEFINE NO_UNIT_PROCESS}
  7. {$DEFINE NO_THREADING}
  8. {$ENDIF}
  9. {$IFDEF AMIGA}
  10. {$DEFINE NO_UNIT_PROCESS}
  11. {$DEFINE NO_THREADING}
  12. {$ENDIF}
  13. {$IFDEF OS2}
  14. {$DEFINE NO_UNIT_PROCESS}
  15. {$ENDIF OS2}
  16. {$IFDEF GO32V2}
  17. {$DEFINE NO_UNIT_PROCESS}
  18. {$ENDIF GO32V2}
  19. {$ifndef NO_UNIT_PROCESS}
  20. {$define HAS_UNIT_PROCESS}
  21. {$endif NO_UNIT_PROCESS}
  22. {$ifndef ALLPACKAGES}
  23. {$mode objfpc}{$H+}
  24. program fpmake;
  25. uses
  26. fpmkunit,
  27. {$IFDEF HAS_UNIT_PROCESS}
  28. process,
  29. {$ENDIF HAS_UNIT_PROCESS}
  30. sysutils;
  31. {$endif ALLPACKAGES}
  32. {$ifdef HAS_UNIT_PROCESS}
  33. procedure fpcm_update_revision_info(Sender: TObject);
  34. function ReadSVNLine(AProcess: TProcess; var ALine: string): boolean;
  35. var
  36. b,i: byte;
  37. begin
  38. result := true;
  39. ALine := '';
  40. i := 1;
  41. repeat
  42. if i = 0 then
  43. sleep(100);
  44. i := AProcess.Output.Read(b,1);
  45. if i > 0 then
  46. begin
  47. if b = 13 then
  48. continue;
  49. if b = 10 then
  50. exit;
  51. ALine := ALine + chr(b);
  52. end;
  53. until not AProcess.Running and (i=0);
  54. result := (ALine <> '');
  55. end;
  56. var
  57. P : TPackage;
  58. SVNBin : String;
  59. SVNProcess: TProcess;
  60. f: text;
  61. fileurl, line, date, lastdate,
  62. revision, oldrevstring, olddate : string;
  63. i, io : longint;
  64. rev, lastrev, oldrev : longint;
  65. begin
  66. // If revision.inc does exist, try to update the file with the latest
  67. // revision from svn. And include this information in the fpcmake
  68. // executable.
  69. With installer do
  70. begin
  71. if not FileExists(BuildEngine.AddPathPrefix(P,'revision.inc')) then
  72. begin
  73. BuildEngine.Log(vlWarning, 'File revision.inc not found. Svn-revision will not be included in fpcmake executable.');
  74. Exit;
  75. end;
  76. // Run svn info, and catch output.
  77. P := sender as TPackage;
  78. P.Options.Add('-dREVINC');
  79. SVNBin := ExeSearch(AddProgramExtension('svn', Defaults.BuildOS), GetEnvironmentvariable('PATH'));
  80. if SVNBin<>'' then
  81. begin
  82. SVNProcess := TProcess.create(nil);
  83. try
  84. SVNProcess.Executable := SVNBin;
  85. SVNProcess.Parameters.Add('info');
  86. SVNProcess.Parameters.Add('-R');
  87. SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmpkg.pp'));
  88. SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmake.pp'));
  89. SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmwr.pp'));
  90. SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmmain.pp'));
  91. SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmdic.pp'));
  92. SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmake.ini'));
  93. SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'Makefile.fpc'));
  94. SVNProcess.Options:=[poUsePipes];
  95. SVNProcess.Execute;
  96. // Search for latest revision in output:
  97. lastrev:=0;
  98. lastdate:='0';
  99. while ReadSVNLine(SVNProcess, Line) do
  100. begin
  101. i:=pos('URL: ',line);
  102. if i>0 then
  103. begin
  104. fileurl:=copy(line,i+length('URL: '),length(line));
  105. BuildEngine.Log(vlCommand,'fileurl='+fileurl);
  106. end;
  107. i:=pos('Last Changed Date: ',line);
  108. if i>0 then
  109. begin
  110. date:=copy(line,i+length('Last Changed Date: '),length(line));
  111. i:=pos(' ',date);
  112. if i>0 then
  113. date:=copy(date,1,i-1);
  114. BuildEngine.Log(vlCommand,'date='+date);
  115. if date>lastdate then
  116. lastdate:=date;
  117. end;
  118. i:=pos('Last Changed Rev: ',line);
  119. if i>0 then
  120. begin
  121. revision:=copy(line,i+length('Last Changed Rev: '),length(line));
  122. BuildEngine.Log(vlCommand,'rev='+revision);
  123. val(revision,rev);
  124. if rev>lastrev then
  125. lastrev:=rev;
  126. end;
  127. end;
  128. finally
  129. SVNProcess.Free;
  130. end;
  131. // Write the latest change-date and revision to file revision.inc
  132. system.assign(f,BuildEngine.AddPathPrefix(P,'revision.inc'));
  133. io:=ioresult;
  134. reset(f);
  135. io:=ioresult;
  136. if io<>0 then
  137. begin
  138. BuildEngine.Log(vlWarning,'revision.inc reset failed, io='+IntToStr(io));
  139. end
  140. else
  141. begin
  142. readln(f,oldrevstring);
  143. close(f);
  144. BuildEngine.Log(vlCommand, 'oldrevstring '+oldrevstring);
  145. if oldrevstring[1]='''' then
  146. oldrevstring:=copy(oldrevstring,2,length(oldrevstring));
  147. i:=length(oldrevstring);
  148. if oldrevstring[i]='''' then
  149. oldrevstring:=copy(oldrevstring,1,i-1);
  150. i:=pos(' rev ',oldrevstring);
  151. if i>0 then
  152. begin
  153. val(copy(oldrevstring,i+5,length(oldrevstring)),oldrev);
  154. olddate:=copy(oldrevstring,1,i-1);
  155. BuildEngine.Log(vlCommand,'Old values '+olddate+' '+IntToStr(oldrev));
  156. if (olddate >= lastdate) and (oldrev >= lastrev) then
  157. begin
  158. BuildEngine.Log(vlCommand,'New values '+lastdate+' '+IntToStr(lastrev));
  159. BuildEngine.Log(vlCommand,'Keeping old values');
  160. lastrev:=oldrev;
  161. lastdate:=olddate;
  162. end;
  163. end;
  164. end;
  165. BuildEngine.Log(vlCommand,'revision.inc set to '''+lastdate+' rev '+IntToStr(lastrev)+'''');
  166. system.assign(f,BuildEngine.AddPathPrefix(P,'revision.inc'));
  167. rewrite(f);
  168. io:=ioresult;
  169. if io <> 0 then
  170. begin
  171. BuildEngine.Log(vlError, 'Error opening revision.inc for writing');
  172. halt(3);
  173. end;
  174. Writeln(f,'''',lastdate,' rev ',lastrev,'''');
  175. close(f);
  176. end
  177. else
  178. BuildEngine.Log(vlWarning,'Subversion executable (svn) not found. Svn-revision in fpcmake executable might be out of date.');
  179. end;
  180. end;
  181. {$endif HAS_UNIT_PROCESS}
  182. procedure add_fpcm(const ADirectory: string);
  183. Var
  184. P : TPackage;
  185. T : TTarget;
  186. Data2IncBin : String;
  187. begin
  188. With Installer do
  189. begin
  190. P:=AddPackage('utils-fpcm');
  191. P.ShortName:='fpcm';
  192. P.OSes:=AllOSes-[embedded,msdos,nativent,win16,macos,atari,palmos];
  193. if Defaults.CPU=jvm then
  194. P.OSes := P.OSes - [java,android];
  195. P.Author := '<various>';
  196. P.License := 'LGPL with modification';
  197. P.HomepageURL := 'www.freepascal.org';
  198. P.Email := '';
  199. P.Description := 'Tool to generate Makefile''s out of Makefile.fpc files';
  200. P.NeedLibC:= false;
  201. {$ifdef ALLPACKAGES}
  202. P.Directory:=ADirectory;
  203. {$endif ALLPACKAGES}
  204. P.Version:='3.3.1';
  205. P.Dependencies.Add('fcl-base');
  206. T:=P.Targets.AddProgram('fpcmake.pp');
  207. {$ifdef HAS_UNIT_PROCESS}
  208. P.BeforeCompileProc:=@fpcm_update_revision_info;
  209. {$else HAS_UNIT_PROCESS}
  210. writeln('Process-unit not available. Svn-revision in fpmake executable might be out-of-date.');
  211. {$endif HAS_UNIT_PROCESS}
  212. Data2IncBin := AddProgramExtension('data2inc',Defaults.BuildOS);
  213. p.Commands.AddCommand(caBeforeCompile, Data2IncBin, '-b -s ' + P.Directory + 'fpcmake.ini ' + P.Directory + 'fpcmake.inc fpcmakeini','fpcmake.inc','fpcmake.ini');
  214. T:=P.Targets.AddUnit('fpcmmain.pp');
  215. T.install:=false;
  216. T.ResourceStrings:=true;
  217. P.Targets.AddUnit('fpcmdic.pp').install:=false;
  218. P.Targets.AddUnit('fpcmwr.pp').install:=false;
  219. P.Targets.AddUnit('fpcmpkg.pp').install:=false;
  220. // P.Sources.AddSrc('fpcmake.ini');
  221. P.Sources.AddSrc('fpcmake.inc');
  222. end;
  223. end;
  224. {$ifndef ALLPACKAGES}
  225. begin
  226. add_fpcm('');
  227. Installer.Run;
  228. end.
  229. {$endif ALLPACKAGES}