From 94f3f07a97a5327308bdcabca3615f80bd6f6116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1roly=20Balogh?= <karoly@freepascal.org> Date: Fri, 4 Aug 2006 20:05:22 +0000 Subject: [PATCH] + first attempt to have linking support for AmigaOS/PowerPC git-svn-id: trunk@4349 - --- compiler/systems/i_amiga.pas | 2 +- compiler/systems/t_amiga.pas | 214 ++++++++++++++++++++++++++++++++++- 2 files changed, 209 insertions(+), 7 deletions(-) diff --git a/compiler/systems/i_amiga.pas b/compiler/systems/i_amiga.pas index 3f6db8f0df..e184b2c14a 100644 --- a/compiler/systems/i_amiga.pas +++ b/compiler/systems/i_amiga.pas @@ -94,7 +94,7 @@ unit i_amiga; flags : [tf_files_case_aware,tf_use_function_relative_addresses]; cpu : cpu_powerpc; unit_env : ''; - extradefines : ''; + extradefines : 'PPC603'; exeext : ''; defext : '.def'; scriptext : '.sh'; diff --git a/compiler/systems/t_amiga.pas b/compiler/systems/t_amiga.pas index 8ac029e9d9..29a10d02a2 100644 --- a/compiler/systems/t_amiga.pas +++ b/compiler/systems/t_amiga.pas @@ -1,8 +1,8 @@ { - Copyright (c) 2001-2002 by Peter Vreman + Copyright (c) 2004-2006 by Free Pascal Development Team This unit implements support import, export, link routines - for the (m68k/powerpc) Amiga target + for the Amiga targets (AmigaOS/m68k, AmigaOS/PPC) 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 @@ -26,13 +26,213 @@ unit t_amiga; interface +uses + link, + cutils,cclasses, + globtype,globals,systems,verbose,script,fmodule,i_amiga; + + +type + PLinkerAmiga = ^TLinkerAmiga; + TLinkerAmiga = class(texternallinker) + private + function WriteResponseFile(isdll: boolean): boolean; +// procedure SetAmiga68kInfo; + procedure SetAmigaPPCInfo; +// function MakeAmiga68kExe: boolean; + function MakeAmigaPPCExe: boolean; + public + constructor Create; override; + procedure SetDefaultInfo; override; + function MakeExecutable: boolean; override; + end; + implementation - uses - link, - cutils,cclasses, - globtype,globals,systems,verbose,script,fmodule,i_amiga; +{$IF DEFINED(MORPHOS) OR DEFINED(AMIGA)} +{ * PathConv is implemented in the system unit! * } +function PathConv(path: string): string; external name 'PATHCONV'; +{$ELSE} +function PathConv(path: string): string; +begin + PathConv:=path; +end; +{$ENDIF} + + +{**************************************************************************** + TLinkerAmiga +****************************************************************************} + +constructor TLinkerAmiga.Create; +begin + Inherited Create; + { allow duplicated libs (PM) } + SharedLibFiles.doubles:=true; + StaticLibFiles.doubles:=true; +end; + +procedure TLinkerAmiga.SetAmigaPPCInfo; +begin + with Info do begin + ExeCmd[1]:='ld $OPT -defsym=__amigaos4__=1 -d -q -n -o $EXE $RES'; + end; +end; + +procedure TLinkerAmiga.SetDefaultInfo; +begin + case (target_info.system) of + system_m68k_amiga: begin end; + system_powerpc_amiga: SetAmigaPPCInfo; + end; +end; + + +function TLinkerAmiga.WriteResponseFile(isdll: boolean): boolean; +var + linkres : TLinkRes; + i : longint; + HPath : TStringListItem; + s : string; + linklibc : boolean; +begin + WriteResponseFile:=False; + + { Open link.res file } + LinkRes:=TLinkRes.Create(outputexedir+Info.ResName); + + { Write path to search libraries } + HPath:=TStringListItem(current_module.locallibrarysearchpath.First); + while assigned(HPath) do + begin + s:=HPath.Str; + if (cs_link_on_target in aktglobalswitches) then + s:=ScriptFixFileName(s); + LinkRes.Add('-L'+s); + HPath:=TStringListItem(HPath.Next); + end; + HPath:=TStringListItem(LibrarySearchPath.First); + while assigned(HPath) do + begin + s:=HPath.Str; + if s<>'' then + LinkRes.Add('SEARCH_DIR('+PathConv(maybequoted(s))+')'); + HPath:=TStringListItem(HPath.Next); + end; + + LinkRes.Add('INPUT ('); + { add objectfiles, start with prt0 always } + s:=FindObjectFile('prt0','',false); + LinkRes.AddFileName(s); + while not ObjectFiles.Empty do + begin + s:=ObjectFiles.GetFirst; + if s<>'' then + begin + LinkRes.AddFileName(PathConv(maybequoted(s))); + end; + end; + + { Write staticlibraries } + if not StaticLibFiles.Empty then + begin + LinkRes.Add(')'); + LinkRes.Add('GROUP('); + while not StaticLibFiles.Empty do + begin + S:=StaticLibFiles.GetFirst; + LinkRes.AddFileName(PathConv(maybequoted(s))); + end; + end; + + if (cs_link_on_target in aktglobalswitches) then + begin + LinkRes.Add(')'); + + { Write sharedlibraries like -l<lib>, also add the needed dynamic linker + here to be sure that it gets linked this is needed for glibc2 systems (PFV) } + linklibc:=false; + while not SharedLibFiles.Empty do + begin + S:=SharedLibFiles.GetFirst; + if s<>'c' then + begin + i:=Pos(target_info.sharedlibext,S); + if i>0 then + Delete(S,i,255); + LinkRes.Add('-l'+s); + end + else + begin + LinkRes.Add('-l'+s); + linklibc:=true; + end; + end; + { be sure that libc&libgcc is the last lib } + if linklibc then + begin + LinkRes.Add('-lc'); + LinkRes.Add('-lgcc'); + end; + end + else + begin + while not SharedLibFiles.Empty do + begin + S:=SharedLibFiles.GetFirst; + LinkRes.Add('lib'+s+target_info.staticlibext); + end; + LinkRes.Add(')'); + end; + +{ Write and Close response } + linkres.writetodisk; + linkres.free; + + WriteResponseFile:=True; +end; + +function TLinkerAmiga.MakeAmigaPPCExe: boolean; +var + BinStr : string; + CmdStr : TCmdStr; + StripStr: string[40]; +begin + StripStr:=''; + if (cs_link_strip in aktglobalswitches) then StripStr:='-s'; + + { Call linker } + SplitBinCmd(Info.ExeCmd[1],BinStr,CmdStr); + Replace(cmdstr,'$OPT',Info.ExtraOptions); + Replace(cmdstr,'$EXE',PathConv(maybequoted(ScriptFixFileName(current_module.exefilename^)))); + Replace(cmdstr,'$RES',PathConv(maybequoted(ScriptFixFileName(outputexedir+Info.ResName)))); + Replace(cmdstr,'$STRIP',StripStr); + MakeAmigaPPCExe:=DoExec(FindUtil(BinStr),CmdStr,true,false); +end; + +function TLinkerAmiga.MakeExecutable:boolean; +var + success : boolean; +begin + if not(cs_link_nolink in aktglobalswitches) then + Message1(exec_i_linking,current_module.exefilename^); + + { Write used files and libraries } + WriteResponseFile(false); + + case (target_info.system) of + system_m68k_amiga: begin end; + system_powerpc_amiga: success:=MakeAmigaPPCExe; + end; + + { Remove ReponseFile } + if (success) and not(cs_link_nolink in aktglobalswitches) then + RemoveFile(outputexedir+Info.ResName); + + MakeExecutable:=success; { otherwise a recursive call to link method } +end; + {***************************************************************************** Initialize @@ -40,9 +240,11 @@ implementation initialization {$ifdef cpu68} +{$warning No executable creation support for m68k yet!} RegisterTarget(system_m68k_Amiga_info); {$endif cpu68} {$ifdef cpupowerpc} + RegisterExternalLinker(system_powerpc_Amiga_info,TLinkerAmiga); RegisterTarget(system_powerpc_Amiga_info); {$endif cpupowerpc} end.