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