mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 09:19:39 +01:00 
			
		
		
		
	activated by defining 'newst', but doesn't compile yet. Changes in type checking and oop are completed. What is left is to write a new symtablestack and adapt the parser to use it.
		
			
				
	
	
		
			655 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			655 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    $Id$
 | 
						|
    Copyright (c) 1998-2000 by Peter Vreman
 | 
						|
 | 
						|
    This unit handles the linker and binder calls for programs and
 | 
						|
    libraries
 | 
						|
 | 
						|
    This program is free software; you can redistribute it and/or modify
 | 
						|
    it under the terms of the GNU General Public License as published by
 | 
						|
    the Free Software Foundation; either version 2 of the License, or
 | 
						|
    (at your option) any later version.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU General Public License
 | 
						|
    along with this program; if not, write to the Free Software
 | 
						|
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
 | 
						|
 ****************************************************************************
 | 
						|
}
 | 
						|
Unit link;
 | 
						|
 | 
						|
Interface
 | 
						|
 | 
						|
{ Needed for LFN support in path to the executable }
 | 
						|
{$ifdef GO32V2}
 | 
						|
  {$define ALWAYSSHELL}
 | 
						|
{$endif}
 | 
						|
 | 
						|
uses cobjects,files;
 | 
						|
 | 
						|
Type
 | 
						|
    TLinkerInfo=record
 | 
						|
      ExeCmd,
 | 
						|
      DllCmd        : array[1..3] of string[80];
 | 
						|
      ResName       : string[12];
 | 
						|
      ExtraOptions  : string;
 | 
						|
      DynamicLinker : string[80];
 | 
						|
    end;
 | 
						|
 | 
						|
    PLinker=^TLinker;
 | 
						|
    TLinker = Object
 | 
						|
    public
 | 
						|
       Info            : TLinkerInfo;
 | 
						|
       ObjectFiles,
 | 
						|
       SharedLibFiles,
 | 
						|
       StaticLibFiles  : TStringContainer;
 | 
						|
     { Methods }
 | 
						|
       Constructor Init;
 | 
						|
       Destructor Done;
 | 
						|
       procedure AddModuleFiles(hp:pmodule);
 | 
						|
       function  FindObjectFile(s : string) : string;
 | 
						|
       function  FindLibraryFile(s:string;const ext:string) : string;
 | 
						|
       Procedure AddObject(const S : String);
 | 
						|
       Procedure AddStaticLibrary(const S : String);
 | 
						|
       Procedure AddSharedLibrary(S : String);
 | 
						|
       Function  FindUtil(const s:string):String;
 | 
						|
       Function  DoExec(const command,para:string;showinfo,useshell:boolean):boolean;
 | 
						|
     { Virtuals }
 | 
						|
       procedure SetDefaultInfo;virtual;
 | 
						|
       Function  MakeExecutable:boolean;virtual;
 | 
						|
       Function  MakeSharedLibrary:boolean;virtual;
 | 
						|
       Function  MakeStaticLibrary:boolean;virtual;
 | 
						|
     end;
 | 
						|
 | 
						|
Var
 | 
						|
  Linker : PLinker;
 | 
						|
 | 
						|
procedure InitLinker;
 | 
						|
procedure DoneLinker;
 | 
						|
 | 
						|
 | 
						|
Implementation
 | 
						|
 | 
						|
uses
 | 
						|
{$ifdef Delphi}
 | 
						|
  dmisc,
 | 
						|
{$else Delphi}
 | 
						|
  dos,
 | 
						|
{$endif Delphi}
 | 
						|
  globtype,systems,
 | 
						|
  script,globals,verbose,ppu
 | 
						|
{$ifdef i386}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    ,t_linux
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETOS2}
 | 
						|
    ,t_os2
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETWIN32}
 | 
						|
    ,t_win32
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETGO32V1}
 | 
						|
    ,t_go32v1
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETGO32V2}
 | 
						|
    ,t_go32v2
 | 
						|
  {$endif}
 | 
						|
{$endif}
 | 
						|
{$ifdef m68k}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    ,t_linux
 | 
						|
  {$endif}
 | 
						|
{$endif}
 | 
						|
{$ifdef powerpc}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    ,t_linux
 | 
						|
  {$endif}
 | 
						|
{$endif}
 | 
						|
{$ifdef alpha}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    ,t_linux
 | 
						|
  {$endif}
 | 
						|
{$endif}
 | 
						|
  ,gendef
 | 
						|
  ;
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                                   TLINKER
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
Constructor TLinker.Init;
 | 
						|
begin
 | 
						|
  ObjectFiles.Init_no_double;
 | 
						|
  SharedLibFiles.Init_no_double;
 | 
						|
  StaticLibFiles.Init_no_double;
 | 
						|
{ set generic defaults }
 | 
						|
  FillChar(Info,sizeof(Info),0);
 | 
						|
  Info.ResName:='link.res';
 | 
						|
{ set the linker specific defaults }
 | 
						|
  SetDefaultInfo;
 | 
						|
{ Allow Parameter overrides for linker info }
 | 
						|
  with Info do
 | 
						|
   begin
 | 
						|
     if ParaLinkOptions<>'' then
 | 
						|
      ExtraOptions:=ParaLinkOptions;
 | 
						|
     if ParaDynamicLinker<>'' then
 | 
						|
      DynamicLinker:=ParaDynamicLinker;
 | 
						|
   end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Destructor TLinker.Done;
 | 
						|
begin
 | 
						|
  ObjectFiles.Done;
 | 
						|
  SharedLibFiles.Done;
 | 
						|
  StaticLibFiles.Done;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure TLinker.SetDefaultInfo;
 | 
						|
begin
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TLinker.AddModuleFiles(hp:pmodule);
 | 
						|
var
 | 
						|
  mask : longint;
 | 
						|
 | 
						|
  {$IFDEF NEWST}
 | 
						|
  procedure addobj(action:pointer);{$IFDEF TP}far;{$ENDIF}
 | 
						|
 | 
						|
  begin
 | 
						|
    if Plinkitem(action)^.needlink and mask<>0 then
 | 
						|
        addobject(Plinkitem(action)^.data^);
 | 
						|
  end;
 | 
						|
 | 
						|
  procedure addstat(action:pointer);{$IFDEF TP}far;{$ENDIF}
 | 
						|
 | 
						|
  begin
 | 
						|
    if Plinkitem(action)^.needlink and mask<>0 then
 | 
						|
        addstaticlibrary(Plinkitem(action)^.data^);
 | 
						|
  end;
 | 
						|
 | 
						|
  procedure addshar(action:pointer);{$IFDEF TP}far;{$ENDIF}
 | 
						|
 | 
						|
  begin
 | 
						|
    if Plinkitem(action)^.needlink and mask<>0 then
 | 
						|
        addsharedlibrary(Plinkitem(action)^.data^);
 | 
						|
  end;
 | 
						|
  {$ENDIF NEWST}
 | 
						|
 | 
						|
begin
 | 
						|
  with hp^ do
 | 
						|
   begin
 | 
						|
   { link unit files }
 | 
						|
     if (flags and uf_no_link)=0 then
 | 
						|
      begin
 | 
						|
        { create mask which unit files need linking }
 | 
						|
        mask:=link_allways;
 | 
						|
        if hp^.is_unit then
 | 
						|
         begin
 | 
						|
           { static linking ? }
 | 
						|
           if (cs_link_static in aktglobalswitches) then
 | 
						|
            begin
 | 
						|
              if (flags and uf_static_linked)=0 then
 | 
						|
               begin
 | 
						|
                 { if smart not avail then try static linking }
 | 
						|
                 if (flags and uf_static_linked)<>0 then
 | 
						|
                  begin
 | 
						|
                    Comment(V_Hint,'unit '+modulename^+' can''t be static linked, switching to smart linking');
 | 
						|
                    mask:=mask or link_smart;
 | 
						|
                  end
 | 
						|
                 else
 | 
						|
                  Comment(V_Error,'unit '+modulename^+' can''t be smart or static linked');
 | 
						|
               end
 | 
						|
              else
 | 
						|
                mask:=mask or link_static;
 | 
						|
            end;
 | 
						|
           { smart linking ? }
 | 
						|
           if (cs_link_smart in aktglobalswitches) then
 | 
						|
            begin
 | 
						|
              if (flags and uf_smart_linked)=0 then
 | 
						|
               begin
 | 
						|
                 { if smart not avail then try static linking }
 | 
						|
                 if (flags and uf_static_linked)<>0 then
 | 
						|
                  begin
 | 
						|
                    Comment(V_Hint,'unit '+modulename^+' can''t be smart linked, switching to static linking');
 | 
						|
                    mask:=mask or link_static;
 | 
						|
                  end
 | 
						|
                 else
 | 
						|
                  Comment(V_Error,'unit '+modulename^+' can''t be smart or static linked');
 | 
						|
               end
 | 
						|
              else
 | 
						|
               mask:=mask or link_smart;
 | 
						|
            end;
 | 
						|
           { shared linking }
 | 
						|
           if (cs_link_shared in aktglobalswitches) then
 | 
						|
            begin
 | 
						|
              if (flags and uf_shared_linked)=0 then
 | 
						|
               begin
 | 
						|
                 { if shared not avail then try static linking }
 | 
						|
                 if (flags and uf_static_linked)<>0 then
 | 
						|
                  begin
 | 
						|
                    Comment(V_Hint,'unit '+modulename^+' can''t be shared linked, switching to static linking');
 | 
						|
                    mask:=mask or link_static;
 | 
						|
                  end
 | 
						|
                 else
 | 
						|
                  Comment(V_Error,'unit '+modulename^+' can''t be shared or static linked');
 | 
						|
               end
 | 
						|
              else
 | 
						|
               mask:=mask or link_shared;
 | 
						|
            end;
 | 
						|
         end
 | 
						|
        else
 | 
						|
         begin
 | 
						|
           { for programs link always static }
 | 
						|
           mask:=mask or link_static;
 | 
						|
         end;
 | 
						|
        { unit files }
 | 
						|
      {$IFDEF NEWST}
 | 
						|
        linkunitofiles.foreach(@addobj);
 | 
						|
        linkunitofiles.freeall;
 | 
						|
        linkunitstaticlibs.foreach(@addstat);
 | 
						|
        linkunitstaticlibs.freeall;
 | 
						|
        linkunitsharedlibs.foreach(@addshar);
 | 
						|
        linkunitsharedlibs.freeall;
 | 
						|
      {$ELSE}
 | 
						|
        while not linkunitofiles.empty do
 | 
						|
         AddObject(linkunitofiles.getusemask(mask));
 | 
						|
        while not linkunitstaticlibs.empty do
 | 
						|
         AddStaticLibrary(linkunitstaticlibs.getusemask(mask));
 | 
						|
        while not linkunitsharedlibs.empty do
 | 
						|
         AddSharedLibrary(linkunitsharedlibs.getusemask(mask));
 | 
						|
      {$ENDIF NEWST}
 | 
						|
      end;
 | 
						|
   { Other needed .o and libs, specified using $L,$LINKLIB,external }
 | 
						|
     mask:=link_allways;
 | 
						|
   {$IFDEF NEWST}
 | 
						|
     linkotherofiles.foreach(@addobj);
 | 
						|
     linkotherofiles.freeall;
 | 
						|
     linkotherstaticlibs.foreach(@addstat);
 | 
						|
     linkotherstaticlibs.freeall;
 | 
						|
     linkothersharedlibs.foreach(@addshar);
 | 
						|
     linkothersharedlibs.freeall;
 | 
						|
   {$ELSE}
 | 
						|
     while not linkotherofiles.empty do
 | 
						|
      AddObject(linkotherofiles.Getusemask(mask));
 | 
						|
     while not linkotherstaticlibs.empty do
 | 
						|
      AddStaticLibrary(linkotherstaticlibs.Getusemask(mask));
 | 
						|
     while not linkothersharedlibs.empty do
 | 
						|
      AddSharedLibrary(linkothersharedlibs.Getusemask(mask));
 | 
						|
   {$ENDIF NEWST}
 | 
						|
   end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function TLinker.FindUtil(const s:string):string;
 | 
						|
var
 | 
						|
  ldfound : boolean;
 | 
						|
  LastBin : string;
 | 
						|
begin
 | 
						|
  LastBin:='';
 | 
						|
  if utilsdirectory<>'' then
 | 
						|
   LastBin:=FindFile(s+source_os.exeext,utilsdirectory,ldfound)+s+source_os.exeext;
 | 
						|
  if LastBin='' then
 | 
						|
   LastBin:=FindExe(s,ldfound);
 | 
						|
  if (not ldfound) and not(cs_link_extern in aktglobalswitches) then
 | 
						|
   begin
 | 
						|
     Message1(exec_w_util_not_found,s);
 | 
						|
     aktglobalswitches:=aktglobalswitches+[cs_link_extern];
 | 
						|
   end;
 | 
						|
  if ldfound then
 | 
						|
   Message1(exec_t_using_util,LastBin);
 | 
						|
  FindUtil:=LastBin;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{ searches an object file }
 | 
						|
function TLinker.FindObjectFile(s:string) : string;
 | 
						|
var
 | 
						|
  found : boolean;
 | 
						|
begin
 | 
						|
  findobjectfile:='';
 | 
						|
  if s='' then
 | 
						|
   exit;
 | 
						|
  if pos('.',s)=0 then
 | 
						|
   s:=s+target_info.objext;
 | 
						|
  s:=FixFileName(s);
 | 
						|
  if FileExists(s) then
 | 
						|
   begin
 | 
						|
     Findobjectfile:=s;
 | 
						|
     exit;
 | 
						|
   end;
 | 
						|
  { find object file
 | 
						|
     1. cwd
 | 
						|
     2. unit search path
 | 
						|
     3. local object path
 | 
						|
     4. global object path
 | 
						|
     5. exepath }
 | 
						|
  found:=false;
 | 
						|
  findobjectfile:=FindFile(s,'.'+DirSep,found)+s;
 | 
						|
  if (not found) then
 | 
						|
   findobjectfile:=UnitSearchPath.FindFile(s,found)+s;
 | 
						|
  if (not found) then
 | 
						|
   findobjectfile:=current_module^.localobjectsearchpath.FindFile(s,found)+s;
 | 
						|
  if (not found) then
 | 
						|
   findobjectfile:=objectsearchpath.FindFile(s,found)+s;
 | 
						|
  if (not found) then
 | 
						|
   findobjectfile:=FindFile(s,exepath,found)+s;
 | 
						|
  if not(cs_link_extern in aktglobalswitches) and (not found) then
 | 
						|
   Message1(exec_w_objfile_not_found,s);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{ searches an library file }
 | 
						|
function TLinker.FindLibraryFile(s:string;const ext:string) : string;
 | 
						|
var
 | 
						|
  found : boolean;
 | 
						|
begin
 | 
						|
  findlibraryfile:='';
 | 
						|
  if s='' then
 | 
						|
   exit;
 | 
						|
  if pos('.',s)=0 then
 | 
						|
   s:=s+ext;
 | 
						|
  if FileExists(s) then
 | 
						|
   begin
 | 
						|
     FindLibraryFile:=s;
 | 
						|
     exit;
 | 
						|
   end;
 | 
						|
  { find libary
 | 
						|
     1. cwd
 | 
						|
     2. local libary dir
 | 
						|
     3. global libary dir
 | 
						|
     4. exe path of the compiler }
 | 
						|
  found:=false;
 | 
						|
  findlibraryfile:=FindFile(s,'.'+DirSep,found)+s;
 | 
						|
  if (not found) then
 | 
						|
   findlibraryfile:=current_module^.locallibrarysearchpath.FindFile(s,found)+s;
 | 
						|
  if (not found) then
 | 
						|
   findlibraryfile:=librarysearchpath.FindFile(s,found)+s;
 | 
						|
  if (not found) then
 | 
						|
   findlibraryfile:=FindFile(s,exepath,found)+s;
 | 
						|
  if not(cs_link_extern in aktglobalswitches) and (not found) then
 | 
						|
   Message1(exec_w_libfile_not_found,s);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure TLinker.AddObject(const S : String);
 | 
						|
begin
 | 
						|
  ObjectFiles.Insert(FindObjectFile(s));
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure TLinker.AddSharedLibrary(S:String);
 | 
						|
begin
 | 
						|
{ remove prefix 'lib' }
 | 
						|
  if Copy(s,1,length(target_os.libprefix))=target_os.libprefix then
 | 
						|
   Delete(s,1,length(target_os.libprefix));
 | 
						|
{ remove extension if any }
 | 
						|
  if Copy(s,length(s)-length(target_os.sharedlibext)+1,length(target_os.sharedlibext))=target_os.sharedlibext then
 | 
						|
   Delete(s,length(s)-length(target_os.sharedlibext)+1,length(target_os.sharedlibext)+1);
 | 
						|
{ ready to be inserted }
 | 
						|
  SharedLibFiles.Insert (S);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure TLinker.AddStaticLibrary(const S:String);
 | 
						|
begin
 | 
						|
  StaticLibFiles.Insert(FindLibraryFile(s,target_os.staticlibext));
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function TLinker.DoExec(const command,para:string;showinfo,useshell:boolean):boolean;
 | 
						|
begin
 | 
						|
  DoExec:=true;
 | 
						|
  if not(cs_link_extern in aktglobalswitches) then
 | 
						|
   begin
 | 
						|
     swapvectors;
 | 
						|
{$ifdef ALWAYSSHELL}
 | 
						|
     shell(command+' '+para);
 | 
						|
{$else}
 | 
						|
     if useshell then
 | 
						|
      shell(command+' '+para)
 | 
						|
     else
 | 
						|
      exec(command,para);
 | 
						|
{$endif}
 | 
						|
     swapvectors;
 | 
						|
     if (doserror<>0) then
 | 
						|
      begin
 | 
						|
         Message(exec_w_cant_call_linker);
 | 
						|
         aktglobalswitches:=aktglobalswitches+[cs_link_extern];
 | 
						|
         DoExec:=false;
 | 
						|
      end
 | 
						|
     else
 | 
						|
      if (dosexitcode<>0) then
 | 
						|
       begin
 | 
						|
        Message(exec_w_error_while_linking);
 | 
						|
        aktglobalswitches:=aktglobalswitches+[cs_link_extern];
 | 
						|
        DoExec:=false;
 | 
						|
       end;
 | 
						|
   end;
 | 
						|
{ Update asmres when externmode is set }
 | 
						|
  if cs_link_extern in aktglobalswitches then
 | 
						|
   begin
 | 
						|
     if showinfo then
 | 
						|
       begin
 | 
						|
         if DLLsource then
 | 
						|
           AsmRes.AddLinkCommand(Command,Para,current_module^.sharedlibfilename^)
 | 
						|
         else
 | 
						|
           AsmRes.AddLinkCommand(Command,Para,current_module^.exefilename^);
 | 
						|
       end
 | 
						|
     else
 | 
						|
      AsmRes.AddLinkCommand(Command,Para,'');
 | 
						|
   end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TLinker.MakeExecutable:boolean;
 | 
						|
begin
 | 
						|
  MakeExecutable:=false;
 | 
						|
  Message(exec_e_exe_not_supported);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function TLinker.MakeSharedLibrary:boolean;
 | 
						|
begin
 | 
						|
  MakeSharedLibrary:=false;
 | 
						|
  Message(exec_e_dll_not_supported);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function TLinker.MakeStaticLibrary:boolean;
 | 
						|
var
 | 
						|
  smartpath,
 | 
						|
  cmdstr,
 | 
						|
  binstr  : string;
 | 
						|
  success : boolean;
 | 
						|
begin
 | 
						|
  MakeStaticLibrary:=false;
 | 
						|
{ remove the library, to be sure that it is rewritten }
 | 
						|
  RemoveFile(current_module^.staticlibfilename^);
 | 
						|
{ Call AR }
 | 
						|
  smartpath:=current_module^.outputpath^+FixPath(FixFileName(current_module^.modulename^)+target_info.smartext,false);
 | 
						|
  SplitBinCmd(target_ar.arcmd,binstr,cmdstr);
 | 
						|
  Replace(cmdstr,'$LIB',current_module^.staticlibfilename^);
 | 
						|
  Replace(cmdstr,'$FILES',FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
 | 
						|
  success:=DoExec(FindUtil(binstr),cmdstr,false,true);
 | 
						|
{ Clean up }
 | 
						|
  if not(cs_asm_leave in aktglobalswitches) then
 | 
						|
   if not(cs_link_extern in aktglobalswitches) then
 | 
						|
    begin
 | 
						|
      while not SmartLinkOFiles.Empty do
 | 
						|
       RemoveFile(SmartLinkOFiles.Get);
 | 
						|
      RemoveDir(smartpath);
 | 
						|
    end
 | 
						|
   else
 | 
						|
    begin
 | 
						|
      AsmRes.AddDeleteCommand(FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
 | 
						|
      AsmRes.Add('rmdir '+smartpath);
 | 
						|
    end;
 | 
						|
  MakeStaticLibrary:=success;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                                 Init/Done
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
procedure InitLinker;
 | 
						|
begin
 | 
						|
  case target_info.target of
 | 
						|
{$ifdef i386}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    target_i386_linux :
 | 
						|
      linker:=new(plinkerlinux,Init);
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETWIN32}
 | 
						|
    target_i386_Win32 :
 | 
						|
      linker:=new(plinkerwin32,Init);
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETGO32V1}
 | 
						|
    target_i386_Go32v1 :
 | 
						|
      linker:=new(plinkergo32v1,Init);
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETGO32V2}
 | 
						|
    target_i386_Go32v2 :
 | 
						|
      linker:=new(plinkergo32v2,Init);
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETOS2}
 | 
						|
    target_i386_os2 :
 | 
						|
      linker:=new(plinkeros2,Init);
 | 
						|
  {$endif}
 | 
						|
{$endif i386}
 | 
						|
{$ifdef m68k}
 | 
						|
  {$ifndef NOTARGETPALMOS}
 | 
						|
    target_m68k_palmos:
 | 
						|
      linker:=new(plinker,Init);
 | 
						|
  {$endif}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    target_m68k_linux :
 | 
						|
      linker:=new(plinkerlinux,Init);
 | 
						|
  {$endif}
 | 
						|
{$endif m68k}
 | 
						|
{$ifdef alpha}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    target_alpha_linux :
 | 
						|
      linker:=new(plinkerlinux,Init);
 | 
						|
  {$endif}
 | 
						|
{$endif alpha}
 | 
						|
{$ifdef powerpc}
 | 
						|
  {$ifndef NOTARGETLINUX}
 | 
						|
    target_powerpc_linux :
 | 
						|
      linker:=new(plinkerlinux,Init);
 | 
						|
  {$endif}
 | 
						|
{$endif powerpc}
 | 
						|
    else
 | 
						|
      linker:=new(plinker,Init);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure DoneLinker;
 | 
						|
begin
 | 
						|
  if assigned(linker) then
 | 
						|
   dispose(linker,done);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
end.
 | 
						|
{
 | 
						|
  $Log$
 | 
						|
  Revision 1.85  2000-02-28 17:23:57  daniel
 | 
						|
  * Current work of symtable integration committed. The symtable can be
 | 
						|
    activated by defining 'newst', but doesn't compile yet. Changes in type
 | 
						|
    checking and oop are completed. What is left is to write a new
 | 
						|
    symtablestack and adapt the parser to use it.
 | 
						|
 | 
						|
  Revision 1.84  2000/02/24 18:41:39  peter
 | 
						|
    * removed warnings/notes
 | 
						|
 | 
						|
  Revision 1.83  2000/02/09 13:22:54  peter
 | 
						|
    * log truncated
 | 
						|
 | 
						|
  Revision 1.82  2000/01/14 14:40:37  pierre
 | 
						|
   * use ./ instead of . to look into startup dir
 | 
						|
 | 
						|
  Revision 1.81  2000/01/12 10:38:18  peter
 | 
						|
    * smartlinking fixes for binary writer
 | 
						|
    * release alignreg code and moved instruction writing align to cpuasm,
 | 
						|
      but it doesn't use the specified register yet
 | 
						|
 | 
						|
  Revision 1.80  2000/01/11 09:52:06  peter
 | 
						|
    * fixed placing of .sl directories
 | 
						|
    * use -b again for base-file selection
 | 
						|
    * fixed group writing for linux with smartlinking
 | 
						|
 | 
						|
  Revision 1.79  2000/01/07 01:14:27  peter
 | 
						|
    * updated copyright to 2000
 | 
						|
 | 
						|
  Revision 1.78  1999/11/22 22:22:30  pierre
 | 
						|
   * Give better info in script
 | 
						|
 | 
						|
  Revision 1.77  1999/11/12 11:03:50  peter
 | 
						|
    * searchpaths changed to stringqueue object
 | 
						|
 | 
						|
  Revision 1.76  1999/11/06 14:34:21  peter
 | 
						|
    * truncated log to 20 revs
 | 
						|
 | 
						|
  Revision 1.75  1999/10/26 12:25:04  peter
 | 
						|
    * fixed os2 linker
 | 
						|
 | 
						|
  Revision 1.74  1999/10/21 14:29:34  peter
 | 
						|
    * redesigned linker object
 | 
						|
    + library support for linux (only procedures can be exported)
 | 
						|
 | 
						|
  Revision 1.72  1999/09/16 23:05:52  florian
 | 
						|
    * m68k compiler is again compilable (only gas writer, no assembler reader)
 | 
						|
 | 
						|
  Revision 1.71  1999/09/16 11:34:56  pierre
 | 
						|
   * typo correction
 | 
						|
 | 
						|
  Revision 1.70  1999/09/15 22:09:16  florian
 | 
						|
    + rtti is now automatically generated for published classes, i.e.
 | 
						|
      they are handled like an implicit property
 | 
						|
 | 
						|
  Revision 1.69  1999/09/15 20:24:56  daniel
 | 
						|
  + Dw switch now does something.
 | 
						|
 | 
						|
  Revision 1.68  1999/08/18 17:05:53  florian
 | 
						|
    + implemented initilizing of data for the new code generator
 | 
						|
      so it should compile now simple programs
 | 
						|
 | 
						|
  Revision 1.67  1999/08/16 15:35:23  pierre
 | 
						|
    * fix for DLL relocation problems
 | 
						|
    * external bss vars had wrong stabs for pecoff
 | 
						|
    + -WB11000000 to specify default image base, allows to
 | 
						|
      load several DLLs with debugging info included
 | 
						|
      (relocatable DLL are stripped because the relocation
 | 
						|
       of the .Stab section is misplaced by ldw)
 | 
						|
 | 
						|
  Revision 1.66  1999/08/11 17:26:34  peter
 | 
						|
    * tlinker object is now inherited for win32 and dos
 | 
						|
    * postprocessexecutable is now a method of tlinker
 | 
						|
 | 
						|
  Revision 1.65  1999/08/10 12:51:16  pierre
 | 
						|
    * bind_win32_dll removed (Relocsection used instead)
 | 
						|
    * now relocsection is true by default ! (needs dlltool
 | 
						|
      for DLL generation)
 | 
						|
 | 
						|
  Revision 1.64  1999/07/30 23:19:45  peter
 | 
						|
    * fixed placing of dynamiclinker in link.res (should be the last after
 | 
						|
      all other libraries)
 | 
						|
 | 
						|
  Revision 1.63  1999/07/29 01:31:39  peter
 | 
						|
    * fixed shared library linking for glibc2 systems
 | 
						|
 | 
						|
  Revision 1.62  1999/07/27 11:05:51  peter
 | 
						|
    * glibc 2.1.2 support
 | 
						|
 | 
						|
}
 |