mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 18:47:52 +02:00
* Link ordering working FreeBSD implementation
git-svn-id: trunk@3894 -
This commit is contained in:
parent
8e952b634d
commit
2a5332e3bd
@ -520,7 +520,7 @@ type
|
||||
end;
|
||||
|
||||
|
||||
Const WeightDefault = 100;
|
||||
Const WeightDefault = 1000;
|
||||
|
||||
Type
|
||||
TLinkRec = record
|
||||
@ -3344,7 +3344,7 @@ end;
|
||||
|
||||
function TLinkStrMap.AddWeight(keyvalue:String):boolean;
|
||||
|
||||
var i : Longint;
|
||||
var i,j : Longint;
|
||||
Code : Word;
|
||||
s : AnsiString;
|
||||
|
||||
@ -3354,10 +3354,10 @@ begin
|
||||
if i=0 then
|
||||
exit;
|
||||
s:=Copy(KeyValue,i+1,length(KeyValue)-i);
|
||||
val(s,i,code);
|
||||
if code<>0 Then
|
||||
val(s,j,code);
|
||||
if code=0 Then
|
||||
begin
|
||||
Add(Copy(KeyValue,1,i-1),'',i);
|
||||
Add(Copy(KeyValue,1,i-1),'',j);
|
||||
AddWeight:=True;
|
||||
end;
|
||||
end;
|
||||
@ -3371,7 +3371,7 @@ begin
|
||||
while i<=k do
|
||||
begin
|
||||
j:=i;
|
||||
while (i<=k) and (keys[i]<>';') do
|
||||
while (i<=k) and (keys[i]<>',') do
|
||||
inc(i);
|
||||
add(copy(keys,j,i-j),'',weight);
|
||||
inc(i);
|
||||
@ -3407,7 +3407,8 @@ begin
|
||||
lookup:=-1;
|
||||
i:=0;
|
||||
{$B-}
|
||||
while (i<itemcnt) and (fmap[i].key<>key) do inc(i);
|
||||
while (i<itemcnt) and (fmap[i].key<>key) do
|
||||
inc(i);
|
||||
{$B+}
|
||||
if i<>itemcnt then
|
||||
lookup:=i;
|
||||
@ -3452,7 +3453,6 @@ begin
|
||||
dest.add(LibN)
|
||||
else
|
||||
dest.addseries(fmap[r].value);
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -3470,3 +3470,4 @@ end;
|
||||
|
||||
|
||||
end.
|
||||
|
@ -142,7 +142,7 @@ than 255 characters. That's why using Ansi Strings}
|
||||
cs_link_nolink,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
|
||||
cs_link_strip,cs_link_staticflag,cs_link_on_target,cs_link_extern,cs_link_opt_vtable,
|
||||
cs_link_opt_used_sections,
|
||||
cs_link_map,cs_link_pthread
|
||||
cs_link_map,cs_link_pthread,cs_link_no_default_lib_order
|
||||
);
|
||||
tglobalswitches = set of tglobalswitch;
|
||||
|
||||
|
@ -65,6 +65,7 @@ Type
|
||||
Function MakeStaticLibrary:boolean;virtual;
|
||||
procedure ExpandAndApplyOrder(var Src:TStringList);
|
||||
procedure LoadPredefinedLibraryOrder;virtual;
|
||||
function ReOrderEntries : boolean;
|
||||
end;
|
||||
|
||||
TExternalLinker = class(TLinker)
|
||||
@ -507,10 +508,11 @@ begin
|
||||
if (LinkLibraryAliases.count=0) and (LinkLibraryOrder.Count=0) Then
|
||||
exit;
|
||||
p:=TLinkStrMap.Create;
|
||||
|
||||
|
||||
// expand libaliases, clears src
|
||||
LinkLibraryAliases.expand(src,p);
|
||||
|
||||
// writeln(src.count,' ',p.count,' ',linklibraryorder.count,' ',linklibraryaliases.count);
|
||||
// apply order
|
||||
p.UpdateWeights(LinkLibraryOrder);
|
||||
p.SortOnWeight;
|
||||
@ -526,6 +528,12 @@ procedure TLinker.LoadPredefinedLibraryOrder;
|
||||
begin
|
||||
end;
|
||||
|
||||
function TLinker.ReOrderEntries : boolean;
|
||||
|
||||
begin
|
||||
result:=(LinkLibraryOrder.count>0) or (LinkLibraryAliases.count>0);
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
TEXTERNALLINKER
|
||||
*****************************************************************************}
|
||||
|
@ -1277,8 +1277,9 @@ begin
|
||||
DefaultReplacements(utilsprefix);
|
||||
More:='';
|
||||
end;
|
||||
'L' : begin // -XLO is link order -XLA is link alias
|
||||
if (j=length(more)) or not ((more[j+1]='O') or (more[j+1]='A')) then
|
||||
'L' : begin // -XLO is link order -XLA is link alias. -XLD avoids load defaults.
|
||||
// these are not aggregable.
|
||||
if (j=length(more)) or not (more[j+1] in ['O','A','D']) then
|
||||
IllegalPara(opt)
|
||||
else
|
||||
begin
|
||||
@ -1290,11 +1291,15 @@ begin
|
||||
end;
|
||||
'O' : begin
|
||||
s:=Copy(more,3,length(More)-2);
|
||||
if not LinkLibraryAliases.AddWeight(s) Then
|
||||
if not LinkLibraryOrder.AddWeight(s) Then
|
||||
IllegalPara(opt);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
'D' : include(initglobalswitches,cs_link_no_default_lib_order)
|
||||
else
|
||||
IllegalPara(opt);
|
||||
end; {case}
|
||||
j:=length(more);
|
||||
end; {else begin}
|
||||
end;
|
||||
'S' :
|
||||
begin
|
||||
|
@ -79,6 +79,7 @@ implementation
|
||||
procedure SetDefaultInfo;override;
|
||||
function MakeExecutable:boolean;override;
|
||||
function MakeSharedLibrary:boolean;override;
|
||||
procedure LoadPredefinedLibraryOrder; override;
|
||||
end;
|
||||
|
||||
|
||||
@ -292,27 +293,30 @@ begin
|
||||
DllCmd[2]:='strip --strip-unneeded $EXE'
|
||||
else
|
||||
DllCmd[2]:='strip -x $EXE';
|
||||
{ first try glibc2 }
|
||||
{$ifdef GLIBC2} {Keep linux code in place. FBSD might go to a different
|
||||
glibc too once}
|
||||
DynamicLinker:='/lib/ld-linux.so.2';
|
||||
if FileExists(DynamicLinker) then
|
||||
begin
|
||||
Glibc2:=true;
|
||||
{ Check for 2.0 files, else use the glibc 2.1 stub }
|
||||
if FileExists('/lib/ld-2.0.*') then
|
||||
Glibc21:=false
|
||||
else
|
||||
Glibc21:=true;
|
||||
end
|
||||
else
|
||||
DynamicLinker:='/lib/ld-linux.so.1';
|
||||
{$else}
|
||||
DynamicLinker:='';
|
||||
{$endif}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLinkerBSD.LoadPredefinedLibraryOrder;
|
||||
// put your linkorder/linkalias overrides here.
|
||||
// Note: assumes only called when reordering/aliasing is used.
|
||||
Begin
|
||||
if not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
|
||||
begin
|
||||
if (target_info.system =system_i386_freebsd) and
|
||||
not (cs_link_no_default_lib_order in aktglobalswitches) Then
|
||||
Begin
|
||||
LinkLibraryOrder.add('gcc','',15);
|
||||
LinkLibraryOrder.add('c','',50); // c and c_p mutual. excl?
|
||||
LinkLibraryOrder.add('c_p','',55);
|
||||
LinkLibraryOrder.add('pthread','',75); // pthread and c_r should be mutually exclusive
|
||||
LinkLibraryOrder.add('c_r','',76);
|
||||
LinkLibraryOrder.add('kvm','',80); // must be before ncurses
|
||||
if (cs_link_pthread in aktglobalswitches) Then // convert libpthread to libc_r.
|
||||
LinkLibraryAliases.add('pthread','c_r');
|
||||
end;
|
||||
end;
|
||||
End;
|
||||
|
||||
Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
|
||||
Var
|
||||
@ -327,27 +331,29 @@ Var
|
||||
linkdynamic,
|
||||
linklibc : boolean;
|
||||
Fl1,Fl2 : Boolean;
|
||||
|
||||
IsDarwin : Boolean;
|
||||
ReOrder : Boolean;
|
||||
|
||||
begin
|
||||
WriteResponseFile:=False;
|
||||
ReOrder:=False;
|
||||
IsDarwin:=target_info.system in [system_powerpc_darwin,system_i386_darwin];
|
||||
{ set special options for some targets }
|
||||
if not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
|
||||
if not IsDarwin Then
|
||||
begin
|
||||
linkdynamic:=not(SharedLibFiles.empty);
|
||||
linklibc:=(SharedLibFiles.Find('c')<>nil);
|
||||
linkpthread:=(SharedLibFiles.Find('pthread')<>nil);
|
||||
if (target_info.system =system_i386_freebsd) and linkpthread Then
|
||||
Begin
|
||||
if not (cs_link_pthread in aktglobalswitches) Then
|
||||
begin
|
||||
{delete pthreads from list, in this case it is in libc_r}
|
||||
SharedLibFiles.Remove(SharedLibFiles.Find('pthread').str);
|
||||
LibrarySuffix:='r';
|
||||
end;
|
||||
End;
|
||||
prtobj:='prt0';
|
||||
cprtobj:='cprt0';
|
||||
gprtobj:='gprt0';
|
||||
linkdynamic:=not(SharedLibFiles.empty);
|
||||
linklibc:=(SharedLibFiles.Find('c')<>nil);
|
||||
// this one is a bit complex.
|
||||
// Only reorder for now if -XL or -XO params are given
|
||||
// or when -Xf.
|
||||
reorder:= linklibc and
|
||||
(
|
||||
ReorderEntries
|
||||
or
|
||||
(cs_link_pthread in aktglobalswitches));
|
||||
if cs_profile in aktmoduleswitches then
|
||||
begin
|
||||
prtobj:=gprtobj;
|
||||
@ -360,6 +366,9 @@ begin
|
||||
if linklibc then
|
||||
prtobj:=cprtobj;
|
||||
end;
|
||||
if reorder Then
|
||||
ExpandAndApplyOrder(SharedLibFiles);
|
||||
// after this point addition of shared libs not allowed.
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -419,7 +428,7 @@ begin
|
||||
LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
|
||||
{ try to add crti and crtbegin if linking to C }
|
||||
if linklibc and
|
||||
not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
|
||||
not IsDarwin Then
|
||||
begin
|
||||
if librarysearchpath.FindFile('crtbegin.o',s) then
|
||||
LinkRes.AddFileName(s);
|
||||
@ -459,7 +468,7 @@ begin
|
||||
While not SharedLibFiles.Empty do
|
||||
begin
|
||||
S:=SharedLibFiles.GetFirst;
|
||||
if s<>'c' then
|
||||
if (s<>'c') or reorder then
|
||||
begin
|
||||
i:=Pos(target_info.sharedlibext,S);
|
||||
if i>0 then
|
||||
@ -473,7 +482,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
{ be sure that libc is the last lib }
|
||||
if linklibc then
|
||||
if linklibc and not reorder then
|
||||
Begin
|
||||
If LibrarySuffix=' ' Then
|
||||
LinkRes.Add('-lc')
|
||||
@ -492,7 +501,7 @@ begin
|
||||
end;
|
||||
{ objects which must be at the end }
|
||||
if linklibc and
|
||||
not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
|
||||
not IsDarwin Then
|
||||
begin
|
||||
Fl1:=librarysearchpath.FindFile('crtend.o',s1);
|
||||
Fl2:=librarysearchpath.FindFile('crtn.o',s2);
|
||||
@ -508,8 +517,7 @@ begin
|
||||
end;
|
||||
{ ignore the fact that our relocations are in non-writable sections, }
|
||||
{ will be fixed once we have pic support }
|
||||
if isdll and
|
||||
(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
|
||||
if isdll and IsDarwin Then
|
||||
LinkRes.Add('-read_only_relocs suppress');
|
||||
{ Write and Close response }
|
||||
linkres.writetodisk;
|
||||
|
Loading…
Reference in New Issue
Block a user