[Ada] gnatlink improvements
Arnaud Charlet
charlet@adacore.com
Tue Jun 12 13:33:00 GMT 2007
Tested on i686-linux, committed on trunk
When gnatlink is called with --LINK=... to indicate an underlying linker
other than gcc, it is not appropriate to add -static-libgcc to the
switches, because the underlying linker may not support this switch or
fail. This patch ensures that -static-libgcc is not used when --LINK=
specify an underlying linker other than gcc.
The test for this is to build using "gnatmake <main> -largs --LINK=..."
with an underlying linker that will not accept -static-libgcc.
When gnatlink invokes the underlying linker and this invocation fails for
any reason, it was displaying "cannot call ...", even when the call was
possible but resulted in an error. This error message was confusing and
has been modified to "error when calling ...".
2007-06-06 Vincent Celier <celier@adacore.com>
* gnatlink.adb (Gnatlink): Do not specify -static-libgcc when --LINK=
has been specified
Correct error message when invocation of the linker fails
Add explicit size clause for the C imported variables
Object_List_File_Supported and Using_GNU_Linker to emphasize that
we expect char size.
Read target parameters earlier, since this is needed to set
Target_VM properly. Also do not use -static/shared-libgcc for non GCC
targets.
-------------- next part --------------
Index: gnatlink.adb
===================================================================
--- gnatlink.adb (revision 124068)
+++ gnatlink.adb (working copy)
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1996-2006, Free Software Foundation, Inc. --
+-- Copyright (C) 1996-2007, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -44,10 +44,12 @@ with Types;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Exceptions; use Ada.Exceptions;
-with GNAT.OS_Lib; use GNAT.OS_Lib;
+
+with System.OS_Lib; use System.OS_Lib;
+with System.CRTL;
+
with Interfaces.C_Streams; use Interfaces.C_Streams;
with Interfaces.C.Strings; use Interfaces.C.Strings;
-with System.CRTL;
procedure Gnatlink is
pragma Ident (Gnatvsn.Gnat_Static_Version_String);
@@ -176,6 +178,7 @@ procedure Gnatlink is
-- the ALI file name (mainprog.ali => mainprog.map).
Object_List_File_Supported : Boolean;
+ for Object_List_File_Supported'Size use Character'Size;
pragma Import
(C, Object_List_File_Supported, "__gnat_objlist_file_supported");
-- Predicate indicating whether the linker has an option whereby the
@@ -416,9 +419,16 @@ procedure Gnatlink is
Compile_Bind_File := False;
when 'o' =>
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'(Arg);
+ if VM_Target = CLI_Target then
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) :=
+ new String'("/QUIET");
+
+ else
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) :=
+ new String'(Arg);
+ end if;
Next_Arg := Next_Arg + 1;
@@ -426,7 +436,13 @@ procedure Gnatlink is
Exit_With_Error ("Missing argument for -o");
end if;
- Output_File_Name := new String'(Argument (Next_Arg));
+ if VM_Target = CLI_Target then
+ Output_File_Name :=
+ new String'("/OUTPUT=" & Argument (Next_Arg));
+ else
+ Output_File_Name :=
+ new String'(Argument (Next_Arg));
+ end if;
Linker_Options.Increment_Last;
Linker_Options.Table (Linker_Options.Last) :=
@@ -478,7 +494,7 @@ procedure Gnatlink is
end if;
Linker_Path :=
- GNAT.OS_Lib.Locate_Exec_On_Path (Arg (8 .. Arg'Last));
+ System.OS_Lib.Locate_Exec_On_Path (Arg (8 .. Arg'Last));
if Linker_Path = null then
Exit_With_Error
@@ -724,6 +740,7 @@ procedure Gnatlink is
-- the response file.
Using_GNU_Linker : Boolean;
+ for Using_GNU_Linker'Size use Character'Size;
pragma Import (C, Using_GNU_Linker, "__gnat_using_gnu_linker");
-- Predicate indicating whether this target uses the GNU linker. In
-- this case we must output a GNU linker compatible response file.
@@ -1415,8 +1432,21 @@ begin
Exit_Program (E_Fatal);
end if;
- if Hostparm.Java_VM then
- Gcc := new String'("jgnat");
+ -- Get target parameters
+
+ Namet.Initialize;
+ Csets.Initialize;
+ Snames.Initialize;
+ Osint.Add_Default_Search_Dirs;
+ Targparm.Get_Target_Parameters;
+
+ if VM_Target /= No_VM then
+ case VM_Target is
+ when JVM_Target => Gcc := new String'("jgnat");
+ when CLI_Target => Gcc := new String'("dotnet-gnatcompile");
+ when No_VM => raise Program_Error;
+ end case;
+
Ada_Bind_File := True;
Begin_Info := "-- BEGIN Object file/option list";
End_Info := "-- END Object file/option list ";
@@ -1454,14 +1484,22 @@ begin
-- Locate all the necessary programs and verify required files are present
- Gcc_Path := GNAT.OS_Lib.Locate_Exec_On_Path (Gcc.all);
+ Gcc_Path := System.OS_Lib.Locate_Exec_On_Path (Gcc.all);
if Gcc_Path = null then
Exit_With_Error ("Couldn't locate " & Gcc.all);
end if;
if Linker_Path = null then
- Linker_Path := Gcc_Path;
+ if VM_Target = CLI_Target then
+ Linker_Path := System.OS_Lib.Locate_Exec_On_Path ("ilasm");
+
+ if Linker_Path = null then
+ Exit_With_Error ("Couldn't locate ilasm");
+ end if;
+ else
+ Linker_Path := Gcc_Path;
+ end if;
end if;
if Ali_File_Name = null then
@@ -1472,14 +1510,6 @@ begin
Exit_With_Error (Ali_File_Name.all & " not found");
end if;
- -- Get target parameters
-
- Namet.Initialize;
- Csets.Initialize;
- Snames.Initialize;
- Osint.Add_Default_Search_Dirs;
- Targparm.Get_Target_Parameters;
-
-- Read the ALI file of the main subprogram if the binder generated
-- file needs to be compiled and no --GCC= switch has been specified.
-- Fetch the back end switches from this ALI file and use these switches
@@ -1548,15 +1578,27 @@ begin
if Output_File_Name = null then
Output_File_Name :=
new String'(Base_Name (Ali_File_Name.all)
- & Get_Target_Debuggable_Suffix.all);
+ & Get_Target_Debuggable_Suffix.all);
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'("-o");
-
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'(Output_File_Name.all);
+ if VM_Target = CLI_Target then
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := new String'("/QUIET");
+
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := new String'("/DEBUG");
+
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) :=
+ new String'("/OUTPUT=" & Output_File_Name.all);
+
+ else
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := new String'("-o");
+
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) :=
+ new String'(Output_File_Name.all);
+ end if;
end if;
-- Warn if main program is called "test", as that may be a built-in command
@@ -1690,7 +1732,7 @@ begin
Write_Eol;
end if;
- GNAT.OS_Lib.Spawn (Gcc_Path.all, Args, Success);
+ System.OS_Lib.Spawn (Gcc_Path.all, Args, Success);
if not Success then
Exit_Program (E_Fatal);
@@ -1700,11 +1742,11 @@ begin
-- Now, actually link the program
- -- Skip this step for now on the JVM since the Java interpreter will do
+ -- Skip this step for now on JVM since the Java interpreter will do
-- the actual link at run time. We might consider packing all class files
-- in a .zip file during this step.
- if not Hostparm.Java_VM then
+ if VM_Target /= JVM_Target then
Link_Step : declare
Num_Args : Natural :=
(Linker_Options.Last - Linker_Options.First + 1) +
@@ -1714,6 +1756,27 @@ begin
IDENT_Op : Boolean := False;
begin
+ if VM_Target = CLI_Target then
+
+ -- Remove extraneous flags not relevant for CIL. Also remove empty
+ -- arguments, since ilasm chokes on them.
+
+ for J in reverse Linker_Options.First .. Linker_Options.Last loop
+ if Linker_Options.Table (J)'Length = 0
+ or else Linker_Options.Table (J) (1 .. 2) = "-L"
+ or else Linker_Options.Table (J) (1 .. 2) = "-l"
+ or else Linker_Options.Table (J) (1 .. 3) = "-Wl"
+ or else Linker_Options.Table (J) (1 .. 3) = "-sh"
+ or else Linker_Options.Table (J) (1 .. 2) = "-g"
+ then
+ Linker_Options.Table (J .. Linker_Options.Last - 1) :=
+ Linker_Options.Table (J + 1 .. Linker_Options.Last);
+ Linker_Options.Decrement_Last;
+ Num_Args := Num_Args - 1;
+ end if;
+ end loop;
+ end if;
+
-- Remove duplicate stack size setting from the Linker_Options
-- table. The stack setting option "-Xlinker --stack=R,C" can be
-- found in one line when set by a pragma Linker_Options or in two
@@ -1810,14 +1873,17 @@ begin
J := J + 1;
end loop;
- -- If gcc is not called with -shared-libgcc, call it with
- -- -static-libgcc, as there are some platforms where one of these
- -- two switches is compulsory to link.
+ if Linker_Path = Gcc_Path and then VM_Target = No_VM then
- if not Shared_Libgcc_Seen then
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) := Static_Libgcc;
- Num_Args := Num_Args + 1;
+ -- If gcc is not called with -shared-libgcc, call it with
+ -- -static-libgcc, as there are some platforms where one of
+ -- these two switches is compulsory to link.
+
+ if not Shared_Libgcc_Seen then
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := Static_Libgcc;
+ Num_Args := Num_Args + 1;
+ end if;
end if;
end Clean_Link_Option_Set;
@@ -1885,7 +1951,7 @@ begin
end if;
end if;
- GNAT.OS_Lib.Spawn (Linker_Path.all, Args, Success);
+ System.OS_Lib.Spawn (Linker_Path.all, Args, Success);
-- Delete the temporary file used in conjuction with linking if
-- one was created. See Process_Bind_File for details.
@@ -1895,7 +1961,7 @@ begin
end if;
if not Success then
- Error_Msg ("cannot call " & Linker_Path.all);
+ Error_Msg ("error when calling " & Linker_Path.all);
Exit_Program (E_Fatal);
end if;
end Call_Linker;
@@ -1917,7 +1983,7 @@ begin
Delete (Binder_Body_Src_File.all & ASCII.NUL);
- if not Hostparm.Java_VM then
+ if VM_Target = No_VM then
Delete (Binder_Obj_File.all & ASCII.NUL);
end if;
end if;
More information about the Gcc-patches
mailing list