From 95972cabbc2ea8819a720a67782043b3e8bb2da2 Mon Sep 17 00:00:00 2001 From: joost Date: Mon, 20 May 2013 17:00:25 +0000 Subject: [PATCH] * Let fpmake update the revision.inc file for fpcmake git-svn-id: trunk@24538 - --- utils/fpcm/fpmake.pp | 182 ++++++++++++++++++++++++++++++++++++++++++- utils/fpmake.pp | 19 ++++- 2 files changed, 199 insertions(+), 2 deletions(-) diff --git a/utils/fpcm/fpmake.pp b/utils/fpcm/fpmake.pp index 1957e08d38..cec6069b3f 100644 --- a/utils/fpcm/fpmake.pp +++ b/utils/fpcm/fpmake.pp @@ -1,10 +1,184 @@ +{$IFDEF OS2} + {$DEFINE NO_UNIT_PROCESS} +{$ENDIF OS2} + +{$IFDEF GO32V2} + {$DEFINE NO_UNIT_PROCESS} +{$ENDIF GO32V2} + +{$ifndef NO_UNIT_PROCESS} + {$define HAS_UNIT_PROCESS} +{$endif NO_UNIT_PROCESS} + {$ifndef ALLPACKAGES} {$mode objfpc}{$H+} program fpmake; -uses fpmkunit; +uses + fpmkunit, +{$IFDEF HAS_UNIT_PROCESS} + process, +{$ENDIF HAS_UNIT_PROCESS} + sysutils; {$endif ALLPACKAGES} +{$ifdef HAS_UNIT_PROCESS} +procedure fpcm_update_revision_info(Sender: TObject); + + function ReadSVNLine(AProcess: TProcess; var ALine: string): boolean; + var + b,i: byte; + begin + result := true; + ALine := ''; + i := 1; + repeat + if i = 0 then + sleep(100); + i := AProcess.Output.Read(b,1); + if b = 10 then + exit; + if i > 0 then + ALine := ALine + chr(b); + until not AProcess.Running and (i=0); + + result := (ALine <> ''); + end; + +var + P : TPackage; + SVNBin : String; + SVNProcess: TProcess; + f: text; + fileurl, line, date, lastdate, + revision, oldrevstring, olddate : string; + i, io : longint; + rev, lastrev, oldrev : longint; + +begin + // If revision.inc does exist, try to update the file with the latest + // revision from svn. And include this information in the fpcmake + // executable. + With installer do + begin + if not FileExists(BuildEngine.AddPathPrefix(P,'revision.inc')) then + begin + BuildEngine.Log(vlWarning, 'File revision.inc not found. Svn-revision will not be included in fpcmake executable.'); + Exit; + end; + + // Run svn info, and catch output. + P := sender as TPackage; + P.Options.Add('-dREVINC'); + SVNBin := ExeSearch('svn', GetEnvironmentvariable('PATH')); + if SVNBin<>'' then + begin + SVNProcess := TProcess.create(nil); + try + SVNProcess.Executable := SVNBin; + SVNProcess.Parameters.Add('info'); + SVNProcess.Parameters.Add('-R'); + SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmpkg.pp')); + SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmake.pp')); + SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmwr.pp')); + SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmmain.pp')); + SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmdic.pp')); + SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'fpcmake.ini')); + SVNProcess.Parameters.Add(BuildEngine.AddPathPrefix(P,'Makefile.fpc')); + SVNProcess.Options:=[poUsePipes]; + SVNProcess.Execute; + + // Search for latest revision in output: + lastrev:=0; + lastdate:='0'; + while ReadSVNLine(SVNProcess, Line) do + begin + i:=pos('URL: ',line); + if i>0 then + begin + fileurl:=copy(line,i+length('URL: '),length(line)); + BuildEngine.Log(vlCommand,'fileurl='+fileurl); + end; + i:=pos('Last Changed Date: ',line); + if i>0 then + begin + date:=copy(line,i+length('Last Changed Date: '),length(line)); + i:=pos(' ',date); + if i>0 then + date:=copy(date,1,i-1); + BuildEngine.Log(vlCommand,'date='+date); + if date>lastdate then + lastdate:=date; + end; + i:=pos('Last Changed Rev: ',line); + if i>0 then + begin + revision:=copy(line,i+length('Last Changed Rev: '),length(line)); + BuildEngine.Log(vlCommand,'rev='+revision); + val(revision,rev); + if rev>lastrev then + lastrev:=rev; + end; + end; + finally + SVNProcess.Free; + end; + + // Write the latest change-date and revision to file revision.inc + system.assign(f,BuildEngine.AddPathPrefix(P,'revision.inc')); + io:=ioresult; + reset(f); + io:=ioresult; + if io<>0 then + begin + BuildEngine.Log(vlWarning,'revision.inc reset failed, io='+IntToStr(io)); + end + else + begin + readln(f,oldrevstring); + close(f); + BuildEngine.Log(vlCommand, 'oldrevstring '+oldrevstring); + if oldrevstring[1]='''' then + oldrevstring:=copy(oldrevstring,2,length(oldrevstring)); + i:=length(oldrevstring); + if oldrevstring[i]='''' then + oldrevstring:=copy(oldrevstring,1,i-1); + i:=pos(' rev ',oldrevstring); + if i>0 then + begin + val(copy(oldrevstring,i+5,length(oldrevstring)),oldrev); + olddate:=copy(oldrevstring,1,i-1); + BuildEngine.Log(vlCommand,'Old values '+olddate+' '+IntToStr(oldrev)); + if (olddate >= lastdate) and (oldrev >= lastrev) then + begin + BuildEngine.Log(vlCommand,'New values '+lastdate+' '+IntToStr(lastrev)); + BuildEngine.Log(vlCommand,'Keeping old values'); + lastrev:=oldrev; + lastdate:=olddate; + end; + end; + + end; + + BuildEngine.Log(vlCommand,'revision.inc set to '''+lastdate+' rev '+IntToStr(lastrev)+''''); + + system.assign(f,BuildEngine.AddPathPrefix(P,'revision.inc')); + rewrite(f); + io:=ioresult; + if io <> 0 then + begin + BuildEngine.Log(vlError, 'Error opening revision.inc for writing'); + halt(3); + end; + Writeln(f,'''',lastdate,' rev ',lastrev,''''); + close(f); + end + else + BuildEngine.Log(vlWarning,'Subversion executable (svn) not found. Svn-revision in fpcmake executable might be out of date.'); + end; +end; +{$endif HAS_UNIT_PROCESS} + procedure add_fpcm; Var @@ -32,6 +206,12 @@ begin T:=P.Targets.AddProgram('fpcmake.pp'); +{$ifdef HAS_UNIT_PROCESS} + P.BeforeCompileProc:=@fpcm_update_revision_info; +{$else HAS_UNIT_PROCESS} + writeln('Process-unit not available. Svn-revision in fpmake executable might be out-of-date.'); +{$endif HAS_UNIT_PROCESS} + T:=P.Targets.AddUnit('fpcmmain.pp'); T.install:=false; T.ResourceStrings:=true; diff --git a/utils/fpmake.pp b/utils/fpmake.pp index 523c01669f..7ddb95589c 100644 --- a/utils/fpmake.pp +++ b/utils/fpmake.pp @@ -2,7 +2,24 @@ {$define allpackages} program fpmake; -uses fpmkunit, sysutils; +{$IFDEF OS2} + {$DEFINE NO_UNIT_PROCESS} +{$ENDIF OS2} + +{$IFDEF GO32V2} + {$DEFINE NO_UNIT_PROCESS} +{$ENDIF GO32V2} + +{$ifndef NO_UNIT_PROCESS} + {$define HAS_UNIT_PROCESS} +{$endif NO_UNIT_PROCESS} + +uses + fpmkunit, +{$IFDEF HAS_UNIT_PROCESS} + process, +{$ENDIF HAS_UNIT_PROCESS} + sysutils; procedure add_utils;