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