At 14:17 -0500 14/11/05, Pascal Viandier wrote:
First: There are some objects from c sources not found at link time. I put {$L my_c_extern.c} in a Pascal source but gp says "my_c_extern.c must be compiled" and stops instead of compiling it (I think since is knows that the source must be compiled, it should do it, no?). Then I tried {$L my_c_extern.o} instead and gp says " My_c_extern.c:999: undefined reference to 'symbol' where 'symbol' is defined in a third party library for which I put a -l directive on gp command-line.
I believe this is due to a bug I fixed in my copy of gp. It stems from the comment:
{ Just make sure the file is added to Deps. We don't need any dependency relations because files linked with linker directives can be compiled at any time. }
which I believe is erroneous. A patch (based on my subversion history) is attached below, but I do not know if it interacts with any of the other patches I've done.
Second: The link command. I put gp in verbose mode and made a copy of the link command which fails to find out what is going wrong.
I see that the list of my external (third party) libraries comes before any object in the link command. (-llib1 -llib2...)
By putting this list of libraries at the end of the link command, it worked. But since I have no control on this at the gp command-line level I cannot make it work.
I saw something like this with libpcre and libxml2 - reordering the libraries fixed the problem without any changes to gp.
Also, I noticed that objects are written in the same directory as gpi files despite the option --object-destination-path=obj on the gp command-line.
I can't help you much with that, as I don't use it. But for {$L}, gp stores a gpd file, so it would need to go somewhere.
gp patch follows. This is definitely not any sort of official patch. My gp has wandered far from the track. Peter.
Index: gp.pas =================================================================== --- gp.pas (revision 331) +++ gp.pas (revision 332) @@ -164,6 +164,7 @@ TUnitList = record Next: PUnitList; FileName, InterfaceName: TString; + IsUnit: Boolean; MD5: TMD5; Dep: PDep end; @@ -365,6 +366,17 @@ ErrorFile (FileName, 'no directory or not writable') end;
+function NewUsesElement (const InterfaceName, FileName: String; Next: PUnitList) = p: PUnitList; +begin + New (p); + p^.InterfaceName := LoCaseStr (InterfaceName); + p^.FileName := FileName; + MD5Clear (p^.MD5); + p^.Dep := nil; + p^.IsUnit := True; + p^.Next := Next +end; + { GPD file handling }
function ReadGPD (var Dep: TDep): TGPD; @@ -430,7 +442,9 @@ end;
function AddUnitList (var p: PPUnitList): Boolean; - var i, j: Integer; + var + i, j: Integer; + MD5: TMD5; begin AddUnitList := False; if not PascalFlag then @@ -438,17 +452,15 @@ ReadGPDError ('invalid unit dependency for C file'); Exit end; - New (p^); i := PosFrom (' ', Line, 3); j := LastPos (' ', Line); - if (i >= j) or not MD5Val (Copy (Line, j + 1), p^^.MD5) then + if (i >= j) or not MD5Val (Copy (Line, j + 1), MD5) then begin ReadGPDError ('invalid unit entry'); Exit end; - p^^.InterfaceName := Copy (Line, 3, i - 3); - p^^.FileName := Copy (Line, i + 1, j - i - 1); - p^^.Dep := nil; + p^ := NewUsesElement( Copy (Line, 3, i - 3), Copy (Line, i + 1, j - i - 1), nil ); + p^^.MD5 := MD5; p := @p^^.Next; AddUnitList := True end; @@ -568,7 +580,9 @@ begin while p <> nil do begin - WriteLn (f, Prefix, p^.InterfaceName, ' ', p^.FileName, ' ', MD5Str (p^.MD5)); + if p^.IsUnit then begin + WriteLn (f, Prefix, p^.InterfaceName, ' ', p^.FileName, ' ', MD5Str (p^.MD5)); + end; p := p^.Next end end; @@ -656,7 +670,7 @@ Assert (i = e + OptionCount); for i := 1 to n - m + 1 do Parameters^[e + OptionCount + i] := NewString (AdditionalParameters[i + m - 1]^); - if (Verbosity >= 2) or (@CmdLine <> nil) then + if (Verbosity >= 1) or (@CmdLine <> nil) then begin l := Length (Compilers[PascalFlag].ProgName); for i := 1 to Parameters^.Count do @@ -666,7 +680,7 @@ for i := 1 to Parameters^.Count do s^ := s^ + ' ' + Parameters^[i]^; if @CmdLine <> nil then CmdLine := s^; - Message (2, s^); + Message (1, s^); Dispose (s) end; ProgressMessageStartSubprocess; @@ -730,16 +744,6 @@ UnitNameMatch := LoCaseStr( Dep.SrcBaseName ) = LoCaseStr( InterfaceName ); end;
-function NewUsesElement (const InterfaceName, FileName: String; Next: PUnitList) = p: PUnitList; -begin - New (p); - p^.InterfaceName := LoCaseStr (InterfaceName); - p^.FileName := FileName; - MD5Clear (p^.MD5); - p^.Dep := nil; - p^.Next := Next -end; - procedure GetDep (var Dep: TDep);
function ReadBufferAndIncludes (var OutputFile: File; var StdErrFile: Text; var Buffer: PBytes; @@ -1345,10 +1349,13 @@ ps := DepToDo^.Dep^.LinkedFiles; while ps <> nil do begin - { Just make sure the file is added to Deps. We don't need - any dependency relations because files linked with - linker directives can be compiled at any time. } - Discard (FindDep (ObjectPath, ps^.s, '', fk_CFile)); + { Must compile $L files before implementation. } + CurrentDep := FindDep (ObjectPath, ps^.s, '', fk_CFile); + AddDepList (CurrentDep^.Dep^.UsedBy[False], DepToDo^.Dep); + DepToDo^.Dep^.UsedUnits[False] := NewUsesElement ( CurrentDep^.Dep^.InterfaceName, CurrentDep^.Dep^.SrcName, DepToDo^.Dep^.UsedUnits[False]); + // what FileName should I use? + DepToDo^.Dep^.UsedUnits[False]^.Dep := CurrentDep^.Dep; + DepToDo^.Dep^.UsedUnits[False]^.IsUnit := False; ps := ps^.Next end; DepToDo := DepToDo^.Next