fpmake.pp 7.2 KB

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