fpmake.pp 7.1 KB

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