1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1996-2006, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 -- Gnatlink usage: please consult the gnat documentation
31 with Gnatvsn
; use Gnatvsn
;
33 with Indepsw
; use Indepsw
;
34 with Namet
; use Namet
;
36 with Osint
; use Osint
;
37 with Output
; use Output
;
39 with Switch
; use Switch
;
40 with System
; use System
;
42 with Targparm
; use Targparm
;
45 with Ada
.Command_Line
; use Ada
.Command_Line
;
46 with Ada
.Exceptions
; use Ada
.Exceptions
;
47 with GNAT
.OS_Lib
; use GNAT
.OS_Lib
;
48 with Interfaces
.C_Streams
; use Interfaces
.C_Streams
;
49 with Interfaces
.C
.Strings
; use Interfaces
.C
.Strings
;
53 pragma Ident
(Gnatvsn
.Gnat_Static_Version_String
);
55 Shared_Libgcc_String
: constant String := "-shared-libgcc";
56 Shared_Libgcc
: constant String_Access
:=
57 new String'(Shared_Libgcc_String);
58 -- Used to invoke gcc when the binder is invoked with -shared
60 package Gcc_Linker_Options is new Table.Table (
61 Table_Component_Type => String_Access,
62 Table_Index_Type => Integer,
65 Table_Increment => 100,
66 Table_Name => "Gnatlink.Gcc_Linker_Options");
67 -- Comments needed ???
69 package Libpath is new Table.Table (
70 Table_Component_Type => Character,
71 Table_Index_Type => Integer,
73 Table_Initial => 4096,
75 Table_Name => "Gnatlink.Libpath");
76 -- Comments needed ???
78 package Linker_Options is new Table.Table (
79 Table_Component_Type => String_Access,
80 Table_Index_Type => Integer,
83 Table_Increment => 100,
84 Table_Name => "Gnatlink.Linker_Options");
85 -- Comments needed ???
87 package Linker_Objects is new Table.Table (
88 Table_Component_Type => String_Access,
89 Table_Index_Type => Integer,
92 Table_Increment => 100,
93 Table_Name => "Gnatlink.Linker_Objects");
94 -- This table collects the objects file to be passed to the linker. In the
95 -- case where the linker command line is too long then programs objects
96 -- are put on the Response_File_Objects table. Note that the binder object
97 -- file and the user's objects remain in this table. This is very
98 -- important because on the GNU linker command line the -L switch is not
99 -- used to look for objects files but -L switch is used to look for
100 -- objects listed in the response file. This is not a problem with the
101 -- applications objects as they are specified with a fullname.
103 package Response_File_Objects is new Table.Table (
104 Table_Component_Type => String_Access,
105 Table_Index_Type => Integer,
106 Table_Low_Bound => 1,
108 Table_Increment => 100,
109 Table_Name => "Gnatlink.Response_File_Objects");
110 -- This table collects the objects file that are to be put in the response
111 -- file. Only application objects are collected there (see details in
112 -- Linker_Objects table comments)
114 package Binder_Options_From_ALI is new Table.Table (
115 Table_Component_Type => String_Access,
116 Table_Index_Type => Integer,
117 Table_Low_Bound => 1, -- equals low bound of Argument_List for Spawn
119 Table_Increment => 100,
120 Table_Name => "Gnatlink.Binder_Options_From_ALI");
121 -- This table collects the switches from the ALI file of the main
124 package Binder_Options is new Table.Table (
125 Table_Component_Type => String_Access,
126 Table_Index_Type => Integer,
127 Table_Low_Bound => 1, -- equals low bound of Argument_List for Spawn
129 Table_Increment => 100,
130 Table_Name => "Gnatlink.Binder_Options");
131 -- This table collects the arguments to be passed to compile the binder
134 Gcc : String_Access := Program_Name ("gcc");
136 Read_Mode : constant String := "r" & ASCII.Nul;
138 Begin_Info : String := "-- BEGIN Object file/option list";
139 End_Info : String := "-- END Object file/option list ";
140 -- Note: above lines are modified in C mode, see option processing
142 Gcc_Path : String_Access;
143 Linker_Path : String_Access;
145 Output_File_Name : String_Access;
146 Ali_File_Name : String_Access;
147 Binder_Spec_Src_File : String_Access;
148 Binder_Body_Src_File : String_Access;
149 Binder_Ali_File : String_Access;
150 Binder_Obj_File : String_Access;
152 Tname : Temp_File_Name;
153 Tname_FD : File_Descriptor := Invalid_FD;
154 -- Temporary file used by linker to pass list of object files on
155 -- certain systems with limitations on size of arguments.
157 Debug_Flag_Present : Boolean := False;
158 Verbose_Mode : Boolean := False;
159 Very_Verbose_Mode : Boolean := False;
161 Ada_Bind_File : Boolean := True;
162 -- Set to True if bind file is generated in Ada
164 Standard_Gcc : Boolean := True;
166 Compile_Bind_File : Boolean := True;
167 -- Set to False if bind file is not to be compiled
169 Create_Map_File : Boolean := False;
170 -- Set to True by switch -M. The map file name is derived from
171 -- the ALI file name (mainprog.ali => mainprog.map).
173 Object_List_File_Supported : Boolean;
175 (C, Object_List_File_Supported, "__gnat_objlist_file_supported");
176 -- Predicate indicating whether the linker has an option whereby the
177 -- names of object files can be passed to the linker in a file.
179 Object_List_File_Required : Boolean := False;
180 -- Set to True to force generation of a response file
182 function Base_Name (File_Name : String) return String;
183 -- Return just the file name part without the extension (if present)
185 procedure Delete (Name : String);
186 -- Wrapper to unlink as status is ignored by this application
188 procedure Error_Msg (Message : String);
189 -- Output the error or warning Message
191 procedure Exit_With_Error (Error : String);
192 -- Output Error and exit program with a fatal condition
194 procedure Process_Args;
195 -- Go through all the arguments and build option tables
197 procedure Process_Binder_File (Name : String);
198 -- Reads the binder file and extracts linker arguments
200 procedure Write_Header;
201 -- Show user the program name, version and copyright
203 procedure Write_Usage;
204 -- Show user the program options
210 function Base_Name (File_Name : String) return String is
215 Findex1 := File_Name'First;
217 -- The file might be specified by a full path name. However,
218 -- we want the path to be stripped away.
220 for J in reverse File_Name'Range loop
221 if Is_Directory_Separator (File_Name (J)) then
227 Findex2 := File_Name'Last;
228 while Findex2 > Findex1
229 and then File_Name (Findex2) /= '.'
231 Findex2 := Findex2 - 1;
234 if Findex2 = Findex1 then
235 Findex2 := File_Name'Last + 1;
238 return File_Name (Findex1 .. Findex2 - 1);
245 procedure Delete (Name : String) is
247 pragma Unreferenced (Status);
249 Status := unlink (Name'Address);
250 -- Is it really right to ignore an error here ???
257 procedure Error_Msg (Message : String) is
259 Write_Str (Base_Name (Command_Name));
265 ---------------------
266 -- Exit_With_Error --
267 ---------------------
269 procedure Exit_With_Error (Error : String) is
272 Exit_Program (E_Fatal);
279 procedure Process_Args is
281 Skip_Next : Boolean := False;
282 -- Set to true if the next argument is to be added into the list of
283 -- linker's argument without parsing it.
286 -- Loop through arguments of gnatlink command
290 exit when Next_Arg > Argument_Count;
292 Process_One_Arg : declare
293 Arg : constant String := Argument (Next_Arg);
296 -- Case of argument which is a switch
298 -- We definitely need section by section comments here ???
302 -- This argument must not be parsed, just add it to the
303 -- list of linker's options.
307 Linker_Options.Increment_Last;
308 Linker_Options.Table (Linker_Options.Last) :=
311 elsif Arg
'Length /= 0 and then Arg
(1) = '-' then
312 if Arg
'Length > 4 and then Arg
(2 .. 5) = "gnat" then
314 ("invalid switch: """ & Arg
& """ (gnat not needed here)");
317 if Arg
= "-Xlinker" then
319 -- Next argument should be sent directly to the linker.
320 -- We do not want to parse it here.
324 Linker_Options
.Increment_Last
;
325 Linker_Options
.Table
(Linker_Options
.Last
) :=
329 and then (Arg'Length < 5 or else Arg (2 .. 5) /= "gnat")
331 Debug_Flag_Present := True;
333 Linker_Options.Increment_Last;
334 Linker_Options.Table (Linker_Options.Last) :=
337 Binder_Options
.Increment_Last
;
338 Binder_Options
.Table
(Binder_Options
.Last
) :=
339 Linker_Options
.Table
(Linker_Options
.Last
);
341 elsif Arg
'Length >= 3 and then Arg
(2) = 'M' then
343 Switches
: String_List_Access
;
346 Convert
(Map_File
, Arg
(3 .. Arg
'Last), Switches
);
348 if Switches
/= null then
349 for J
in Switches
'Range loop
350 Linker_Options
.Increment_Last
;
351 Linker_Options
.Table
(Linker_Options
.Last
) :=
357 elsif Arg
'Length = 2 then
360 Ada_Bind_File
:= True;
361 Begin_Info
:= "-- BEGIN Object file/option list";
362 End_Info
:= "-- END Object file/option list ";
365 Linker_Options
.Increment_Last
;
366 Linker_Options
.Table
(Linker_Options
.Last
) :=
369 Binder_Options.Increment_Last;
370 Binder_Options.Table (Binder_Options.Last) :=
371 Linker_Options.Table (Linker_Options.Last);
373 Next_Arg := Next_Arg + 1;
375 if Next_Arg > Argument_Count then
376 Exit_With_Error ("Missing argument for -b");
379 Get_Machine_Name : declare
380 Name_Arg : constant String_Access :=
381 new String'(Argument
(Next_Arg
));
384 Linker_Options
.Increment_Last
;
385 Linker_Options
.Table
(Linker_Options
.Last
) :=
388 Binder_Options
.Increment_Last
;
389 Binder_Options
.Table
(Binder_Options
.Last
) :=
392 end Get_Machine_Name
;
395 Ada_Bind_File
:= False;
396 Begin_Info
:= "/* BEGIN Object file/option list";
397 End_Info
:= " END Object file/option list */";
400 if Object_List_File_Supported
then
401 Object_List_File_Required
:= True;
404 ("Object list file not supported on this target");
408 Create_Map_File
:= True;
411 Compile_Bind_File
:= False;
414 Linker_Options
.Increment_Last
;
415 Linker_Options
.Table
(Linker_Options
.Last
) :=
418 Next_Arg := Next_Arg + 1;
420 if Next_Arg > Argument_Count then
421 Exit_With_Error ("Missing argument for -o");
424 Output_File_Name := new String'(Argument
(Next_Arg
));
426 Linker_Options
.Increment_Last
;
427 Linker_Options
.Table
(Linker_Options
.Last
) :=
431 Opt
.Run_Path_Option
:= False;
435 -- Support "double" verbose mode. Second -v
436 -- gets sent to the linker and binder phases.
439 Very_Verbose_Mode
:= True;
441 Linker_Options
.Increment_Last
;
442 Linker_Options
.Table
(Linker_Options
.Last
) :=
445 Binder_Options.Increment_Last;
446 Binder_Options.Table (Binder_Options.Last) :=
447 Linker_Options.Table (Linker_Options.Last);
450 Verbose_Mode := True;
455 Linker_Options.Increment_Last;
456 Linker_Options.Table (Linker_Options.Last) :=
461 elsif Arg
(2) = 'B' then
462 Linker_Options
.Increment_Last
;
463 Linker_Options
.Table
(Linker_Options
.Last
) :=
466 Binder_Options.Increment_Last;
467 Binder_Options.Table (Binder_Options.Last) :=
468 Linker_Options.Table (Linker_Options.Last);
470 elsif Arg'Length >= 7 and then Arg (1 .. 7) = "--LINK=" then
471 if Arg'Length = 7 then
472 Exit_With_Error ("Missing argument for --LINK=");
476 GNAT.OS_Lib.Locate_Exec_On_Path (Arg (8 .. Arg'Last));
478 if Linker_Path = null then
480 ("Could not locate linker: " & Arg (8 .. Arg'Last));
483 elsif Arg'Length > 6 and then Arg (1 .. 6) = "--GCC=" then
485 Program_Args : constant Argument_List_Access :=
486 Argument_String_To_List
487 (Arg (7 .. Arg'Last));
490 Gcc := new String'(Program_Args
.all (1).all);
491 Standard_Gcc
:= False;
493 -- Set appropriate flags for switches passed
495 for J
in 2 .. Program_Args
.all'Last loop
497 Arg
: constant String := Program_Args
.all (J
).all;
498 AF
: constant Integer := Arg
'First;
501 if Arg
'Length /= 0 and then Arg
(AF
) = '-' then
502 if Arg
(AF
+ 1) = 'g'
503 and then (Arg
'Length = 2
504 or else Arg
(AF
+ 2) in '0' .. '3'
505 or else Arg
(AF
+ 2 .. Arg
'Last) = "coff")
507 Debug_Flag_Present
:= True;
511 -- Add directory to source search dirs so that
512 -- Get_Target_Parameters can find system.ads
514 if Arg
(AF
.. AF
+ 1) = "-I"
515 and then Arg
'Length > 2
517 Add_Src_Search_Dir
(Arg
(AF
+ 2 .. Arg
'Last));
520 -- Pass to gcc for compiling binder generated file
521 -- No use passing libraries, it will just generate
524 if not (Arg
(AF
.. AF
+ 1) = "-l"
525 or else Arg
(AF
.. AF
+ 1) = "-L")
527 Binder_Options
.Increment_Last
;
528 Binder_Options
.Table
(Binder_Options
.Last
) :=
532 -- Pass to gcc for linking program
534 Gcc_Linker_Options.Increment_Last;
535 Gcc_Linker_Options.Table
536 (Gcc_Linker_Options.Last) := new String'(Arg
);
541 -- Send all multi-character switches not recognized as
542 -- a special case by gnatlink to the linker/loader stage.
545 Linker_Options
.Increment_Last
;
546 Linker_Options
.Table
(Linker_Options
.Last
) :=
550 -- Here if argument is a file name rather than a switch
553 -- If explicit ali file, capture it
556 and then Arg (Arg'Last - 3 .. Arg'Last) = ".ali"
558 if Ali_File_Name = null then
559 Ali_File_Name := new String'(Arg
);
561 Exit_With_Error
("cannot handle more than one ALI file");
564 -- If target object file, record object file
566 elsif Arg
'Length > Get_Target_Object_Suffix
.all'Length
569 Get_Target_Object_Suffix
.all'Length + 1 .. Arg
'Last)
570 = Get_Target_Object_Suffix
.all
572 Linker_Objects
.Increment_Last
;
573 Linker_Objects
.Table
(Linker_Objects
.Last
) :=
576 -- If host object file, record object file
577 -- e.g. accept foo.o as well as foo.obj on VMS target
579 elsif Arg'Length > Get_Object_Suffix.all'Length
581 (Arg'Last - Get_Object_Suffix.all'Length + 1 .. Arg'Last)
582 = Get_Object_Suffix.all
584 Linker_Objects.Increment_Last;
585 Linker_Objects.Table (Linker_Objects.Last) :=
588 -- If corresponding ali file exists, capture it
590 elsif Ali_File_Name
= null
591 and then Is_Regular_File
(Arg
& ".ali")
593 Ali_File_Name
:= new String'(Arg & ".ali");
595 -- Otherwise assume this is a linker options entry, but
596 -- see below for interesting adjustment to this assumption.
599 Linker_Options.Increment_Last;
600 Linker_Options.Table (Linker_Options.Last) :=
606 Next_Arg
:= Next_Arg
+ 1;
609 -- If Ada bind file, then compile it with warnings suppressed, because
610 -- otherwise the with of the main program may cause junk warnings.
612 if Ada_Bind_File
then
613 Binder_Options
.Increment_Last
;
614 Binder_Options
.Table
(Binder_Options
.Last
) := new String'("-gnatws");
617 -- If we did not get an ali file at all, and we had at least one
618 -- linker option, then assume that was the intended ali file after
619 -- all, so that we get a nicer message later on.
621 if Ali_File_Name = null
622 and then Linker_Options.Last >= Linker_Options.First
625 new String'(Linker_Options
.Table
(Linker_Options
.First
).all &
630 -------------------------
631 -- Process_Binder_File --
632 -------------------------
634 procedure Process_Binder_File
(Name
: String) is
636 -- Binder file's descriptor
638 Link_Bytes
: Integer := 0;
639 -- Projected number of bytes for the linker command line
642 pragma Import
(C
, Link_Max
, "__gnat_link_max");
643 -- Maximum number of bytes on the command line supported by the OS
644 -- linker. Passed this limit the response file mechanism must be used
647 Next_Line
: String (1 .. 1000);
648 -- Current line value
652 -- Current line slice (the slice does not contain line terminator)
655 -- Current line last character for shared libraries (without version)
657 Objs_Begin
: Integer := 0;
658 -- First object file index in Linker_Objects table
660 Objs_End
: Integer := 0;
661 -- Last object file index in Linker_Objects table
664 -- Used for various Interfaces.C_Streams calls
666 Closing_Status
: Boolean;
669 GNAT_Static
: Boolean := False;
670 -- Save state of -static option
672 GNAT_Shared
: Boolean := False;
673 -- Save state of -shared option
675 Xlinker_Was_Previous
: Boolean := False;
676 -- Indicate that "-Xlinker" was the option preceding the current
677 -- option. If True, then the current option is never suppressed.
681 -- These data items are used to store current binder file context.
682 -- The context is composed of the file descriptor position and the
683 -- current line together with the slice indexes (first and last
684 -- position) for this line. The rollback data are used by the
685 -- Store_File_Context and Rollback_File_Context routines below.
686 -- The file context mechanism interact only with the Get_Next_Line
687 -- call. For example:
689 -- Store_File_Context;
691 -- Rollback_File_Context;
694 -- Both Get_Next_Line calls above will read the exact same data from
695 -- the file. In other words, Next_Line, Nfirst and Nlast variables
696 -- will be set with the exact same values.
698 RB_File_Pos
: long
; -- File position
699 RB_Next_Line
: String (1 .. 1000); -- Current line content
700 RB_Nlast
: Integer; -- Slice last index
701 RB_Nfirst
: Integer; -- Slice first index
703 Run_Path_Option_Ptr
: Interfaces
.C
.Strings
.chars_ptr
;
704 pragma Import
(C
, Run_Path_Option_Ptr
, "__gnat_run_path_option");
705 -- Pointer to string representing the native linker option which
706 -- specifies the path where the dynamic loader should find shared
707 -- libraries. Equal to null string if this system doesn't support it.
709 Object_Library_Ext_Ptr
: Interfaces
.C
.Strings
.chars_ptr
;
711 (C
, Object_Library_Ext_Ptr
, "__gnat_object_library_extension");
712 -- Pointer to string specifying the default extension for
713 -- object libraries, e.g. Unix uses ".a", VMS uses ".olb".
715 Object_File_Option_Ptr
: Interfaces
.C
.Strings
.chars_ptr
;
716 pragma Import
(C
, Object_File_Option_Ptr
, "__gnat_object_file_option");
717 -- Pointer to a string representing the linker option which specifies
718 -- the response file.
720 Using_GNU_Linker
: Boolean;
721 pragma Import
(C
, Using_GNU_Linker
, "__gnat_using_gnu_linker");
722 -- Predicate indicating whether this target uses the GNU linker. In
723 -- this case we must output a GNU linker compatible response file.
725 Opening
: aliased constant String := """";
726 Closing
: aliased constant String := '"' & ASCII
.LF
;
727 -- Needed to quote object paths in object list files when GNU linker
730 procedure Get_Next_Line
;
731 -- Read the next line from the binder file without the line
734 function Index
(S
, Pattern
: String) return Natural;
735 -- Return the last occurrence of Pattern in S, or 0 if none
737 function Is_Option_Present
(Opt
: String) return Boolean;
738 -- Return true if the option Opt is already present in
739 -- Linker_Options table.
741 procedure Store_File_Context
;
742 -- Store current file context, Fd position and current line data.
743 -- The file context is stored into the rollback data above (RB_*).
744 -- Store_File_Context can be called at any time, only the last call
745 -- will be used (i.e. this routine overwrites the file context).
747 procedure Rollback_File_Context
;
748 -- Restore file context from rollback data. This routine must be called
749 -- after Store_File_Context. The binder file context will be restored
750 -- with the data stored by the last Store_File_Context call.
756 procedure Get_Next_Line
is
760 Fchars
:= fgets
(Next_Line
'Address, Next_Line
'Length, Fd
);
762 if Fchars
= System
.Null_Address
then
763 Exit_With_Error
("Error reading binder output");
766 Nfirst
:= Next_Line
'First;
768 while Nlast
<= Next_Line
'Last
769 and then Next_Line
(Nlast
) /= ASCII
.LF
770 and then Next_Line
(Nlast
) /= ASCII
.CR
782 function Index
(S
, Pattern
: String) return Natural is
783 Len
: constant Natural := Pattern
'Length;
786 for J
in reverse S
'First .. S
'Last - Len
+ 1 loop
787 if Pattern
= S
(J
.. J
+ Len
- 1) then
795 -----------------------
796 -- Is_Option_Present --
797 -----------------------
799 function Is_Option_Present
(Opt
: String) return Boolean is
801 for I
in 1 .. Linker_Options
.Last
loop
803 if Linker_Options
.Table
(I
).all = Opt
then
810 end Is_Option_Present
;
812 ---------------------------
813 -- Rollback_File_Context --
814 ---------------------------
816 procedure Rollback_File_Context
is
818 Next_Line
:= RB_Next_Line
;
821 Status
:= fseek
(Fd
, RB_File_Pos
, Interfaces
.C_Streams
.SEEK_SET
);
824 Exit_With_Error
("Error setting file position");
826 end Rollback_File_Context
;
828 ------------------------
829 -- Store_File_Context --
830 ------------------------
832 procedure Store_File_Context
is
833 use type System
.CRTL
.long
;
835 RB_Next_Line
:= Next_Line
;
838 RB_File_Pos
:= ftell
(Fd
);
840 if RB_File_Pos
= -1 then
841 Exit_With_Error
("Error getting file position");
843 end Store_File_Context
;
845 -- Start of processing for Process_Binder_File
848 Fd
:= fopen
(Name
'Address, Read_Mode
'Address);
850 if Fd
= NULL_Stream
then
851 Exit_With_Error
("Failed to open binder output");
854 -- Skip up to the Begin Info line
858 exit when Next_Line
(Nfirst
.. Nlast
) = Begin_Info
;
864 -- Go to end when end line is reached (this will happen in
865 -- High_Integrity_Mode where no -L switches are generated)
867 exit when Next_Line
(Nfirst
.. Nlast
) = End_Info
;
869 if Ada_Bind_File
then
870 Next_Line
(Nfirst
.. Nlast
- 8) :=
871 Next_Line
(Nfirst
+ 8 .. Nlast
);
875 -- Go to next section when switches are reached
877 exit when Next_Line
(1) = '-';
879 -- Otherwise we have another object file to collect
881 Linker_Objects
.Increment_Last
;
883 -- Mark the positions of first and last object files in case
884 -- they need to be placed with a named file on systems having
885 -- linker line limitations.
887 if Objs_Begin
= 0 then
888 Objs_Begin
:= Linker_Objects
.Last
;
891 Linker_Objects
.Table
(Linker_Objects
.Last
) :=
892 new String'(Next_Line (Nfirst .. Nlast));
894 Link_Bytes := Link_Bytes + Nlast - Nfirst + 2;
895 -- Nlast - Nfirst + 1, for the size, plus one for the space between
899 Objs_End := Linker_Objects.Last;
901 -- Let's continue to compute the Link_Bytes, the linker options are
902 -- part of command line length.
906 while Next_Line (Nfirst .. Nlast) /= End_Info loop
907 Link_Bytes := Link_Bytes + Nlast - Nfirst + 2;
912 Rollback_File_Context;
914 -- On systems that have limitations on handling very long linker lines
915 -- we make use of the system linker option which takes a list of object
916 -- file names from a file instead of the command line itself. What we do
917 -- is to replace the list of object files by the special linker option
918 -- which then reads the object file list from a file instead. The option
919 -- to read from a file instead of the command line is only triggered if
920 -- a conservative threshold is passed.
922 if Object_List_File_Required
923 or else (Object_List_File_Supported
924 and then Link_Bytes > Link_Max)
926 -- Create a temporary file containing the Ada user object files
927 -- needed by the link. This list is taken from the bind file
928 -- and is output one object per line for maximal compatibility with
929 -- linkers supporting this option.
931 Create_Temp_File (Tname_FD, Tname);
933 -- ??? File descriptor should be checked to not be Invalid_FD.
934 -- ??? Status of Write and Close operations should be checked, and
935 -- failure should occur if a status is wrong.
937 -- If target is using the GNU linker we must add a special header
938 -- and footer in the response file.
940 -- The syntax is : INPUT (object1.o object2.o ... )
942 -- Because the GNU linker does not like name with characters such
943 -- as '!', we must put the object paths between double quotes.
945 if Using_GNU_Linker then
947 GNU_Header : aliased constant String := "INPUT (";
950 Status := Write (Tname_FD, GNU_Header'Address,
955 for J in Objs_Begin .. Objs_End loop
957 -- Opening quote for GNU linker
959 if Using_GNU_Linker then
960 Status := Write (Tname_FD, Opening'Address, 1);
963 Status := Write (Tname_FD, Linker_Objects.Table (J).all'Address,
964 Linker_Objects.Table (J).all'Length);
966 -- Closing quote for GNU linker
968 if Using_GNU_Linker then
969 Status := Write (Tname_FD, Closing'Address, 2);
972 Status := Write (Tname_FD, ASCII.LF'Address, 1);
975 Response_File_Objects.Increment_Last;
976 Response_File_Objects.Table (Response_File_Objects.Last) :=
977 Linker_Objects.Table (J);
980 -- Handle GNU linker response file footer
982 if Using_GNU_Linker then
984 GNU_Footer : aliased constant String := ")";
987 Status := Write (Tname_FD, GNU_Footer'Address,
992 Close (Tname_FD, Closing_Status);
994 -- Add the special objects list file option together with the name
995 -- of the temporary file (removing the null character) to the objects
998 Linker_Objects.Table (Objs_Begin) :=
999 new String'(Value
(Object_File_Option_Ptr
) &
1000 Tname
(Tname
'First .. Tname
'Last - 1));
1002 -- The slots containing these object file names are then removed
1003 -- from the objects table so they do not appear in the link. They
1004 -- are removed by moving up the linker options and non-Ada object
1005 -- files appearing after the Ada object list in the table.
1011 N
:= Objs_End
- Objs_Begin
+ 1;
1013 for J
in Objs_End
+ 1 .. Linker_Objects
.Last
loop
1014 Linker_Objects
.Table
(J
- N
+ 1) := Linker_Objects
.Table
(J
);
1017 Linker_Objects
.Set_Last
(Linker_Objects
.Last
- N
+ 1);
1021 -- Process switches and options
1023 if Next_Line
(Nfirst
.. Nlast
) /= End_Info
then
1024 Xlinker_Was_Previous
:= False;
1027 if Xlinker_Was_Previous
1028 or else Next_Line
(Nfirst
.. Nlast
) = "-Xlinker"
1030 Linker_Options
.Increment_Last
;
1031 Linker_Options
.Table
(Linker_Options
.Last
) :=
1032 new String'(Next_Line (Nfirst .. Nlast));
1034 elsif Next_Line (Nfirst .. Nlast) = "-static" then
1035 GNAT_Static := True;
1037 elsif Next_Line (Nfirst .. Nlast) = "-shared" then
1038 GNAT_Shared := True;
1040 -- Add binder options only if not already set on the command
1041 -- line. This rule is a way to control the linker options order.
1043 -- The following test needs comments, why is it VMS specific.
1044 -- The above comment looks out of date ???
1046 elsif not (OpenVMS_On_Target
1048 Is_Option_Present (Next_Line (Nfirst .. Nlast)))
1050 if Nlast > Nfirst + 2 and then
1051 Next_Line (Nfirst .. Nfirst + 1) = "-L"
1053 -- Construct a library search path for use later
1054 -- to locate static gnatlib libraries.
1056 if Libpath.Last > 1 then
1057 Libpath.Increment_Last;
1058 Libpath.Table (Libpath.Last) := Path_Separator;
1061 for I in Nfirst + 2 .. Nlast loop
1062 Libpath.Increment_Last;
1063 Libpath.Table (Libpath.Last) := Next_Line (I);
1066 Linker_Options.Increment_Last;
1068 Linker_Options.Table (Linker_Options.Last) :=
1069 new String'(Next_Line
(Nfirst
.. Nlast
));
1071 elsif Next_Line
(Nfirst
.. Nlast
) = "-ldecgnat"
1072 or else Next_Line
(Nfirst
.. Nlast
) = "-lgnarl"
1073 or else Next_Line
(Nfirst
.. Nlast
) = "-lgnat"
1075 (1 .. Natural'Min (Nlast
, 8 + Library_Version
'Length)) =
1076 Shared_Lib
("gnarl")
1078 (1 .. Natural'Min (Nlast
, 7 + Library_Version
'Length)) =
1081 -- If it is a shared library, remove the library version.
1082 -- We will be looking for the static version of the library
1083 -- as it is in the same directory as the shared version.
1085 if Next_Line
(Nlast
- Library_Version
'Length + 1 .. Nlast
)
1088 -- Set Last to point to last character before the
1091 Last
:= Nlast
- Library_Version
'Length - 1;
1096 -- Given a Gnat standard library, search the
1097 -- library path to find the library location
1100 File_Path
: String_Access
;
1102 Object_Lib_Extension
: constant String :=
1103 Value
(Object_Library_Ext_Ptr
);
1105 File_Name
: constant String := "lib" &
1106 Next_Line
(Nfirst
+ 2 .. Last
) &
1107 Object_Lib_Extension
;
1109 Run_Path_Opt
: constant String :=
1110 Value
(Run_Path_Option_Ptr
);
1112 GCC_Index
: Natural;
1113 Run_Path_Opt_Index
: Natural := 0;
1117 Locate_Regular_File
(File_Name
,
1118 String (Libpath
.Table
(1 .. Libpath
.Last
)));
1120 if File_Path
/= null then
1123 -- If static gnatlib found, explicitly
1124 -- specify to overcome possible linker
1125 -- default usage of shared version.
1127 Linker_Options
.Increment_Last
;
1129 Linker_Options
.Table
(Linker_Options
.Last
) :=
1130 new String'(File_Path.all);
1132 elsif GNAT_Shared then
1133 if Opt.Run_Path_Option then
1134 -- If shared gnatlib desired, add the
1135 -- appropriate system specific switch
1136 -- so that it can be located at runtime.
1138 if Run_Path_Opt'Length /= 0 then
1139 -- Output the system specific linker command
1140 -- that allows the image activator to find
1141 -- the shared library at runtime.
1142 -- Also add path to find libgcc_s.so, if
1145 -- To find the location of the shared version
1146 -- of libgcc, we look for "gcc-lib" in the
1147 -- path of the library. However, this
1148 -- subdirectory is no longer present in
1149 -- in recent version of GCC. So, we look for
1150 -- the last subdirectory "lib" in the path.
1153 Index (File_Path.all, "gcc-lib");
1155 if GCC_Index /= 0 then
1156 -- The shared version of libgcc is
1157 -- located in the parent directory.
1159 GCC_Index := GCC_Index - 1;
1163 Index (File_Path.all, "/lib/");
1165 if GCC_Index = 0 then
1167 Index (File_Path.all,
1168 Directory_Separator &
1170 Directory_Separator);
1173 -- We have found a subdirectory "lib",
1174 -- this is where the shared version of
1175 -- libgcc should be located.
1177 if GCC_Index /= 0 then
1178 GCC_Index := GCC_Index + 3;
1182 -- Look for an eventual run_path_option in
1183 -- the linker switches.
1185 for J in reverse 1 .. Linker_Options.Last loop
1186 if Linker_Options.Table (J) /= null
1188 Linker_Options.Table (J)'Length
1189 > Run_Path_Opt'Length
1191 Linker_Options.Table (J)
1192 (1 .. Run_Path_Opt'Length) =
1195 -- We have found a already specified
1196 -- run_path_option: we will add to this
1197 -- switch, because only one
1198 -- run_path_option should be specified.
1200 Run_Path_Opt_Index := J;
1205 -- If there is no run_path_option, we need
1208 if Run_Path_Opt_Index = 0 then
1209 Linker_Options.Increment_Last;
1212 if GCC_Index = 0 then
1213 if Run_Path_Opt_Index = 0 then
1214 Linker_Options.Table
1215 (Linker_Options.Last) :=
1219 (1 .. File_Path
'Length
1220 - File_Name
'Length));
1223 Linker_Options
.Table
1224 (Run_Path_Opt_Index
) :=
1226 (Linker_Options.Table
1227 (Run_Path_Opt_Index).all
1230 (1 .. File_Path'Length
1231 - File_Name'Length));
1235 if Run_Path_Opt_Index = 0 then
1236 Linker_Options.Table
1237 (Linker_Options.Last) :=
1238 new String'(Run_Path_Opt
1240 (1 .. File_Path
'Length
1243 & File_Path
(1 .. GCC_Index
));
1246 Linker_Options
.Table
1247 (Run_Path_Opt_Index
) :=
1249 (Linker_Options.Table
1250 (Run_Path_Opt_Index).all
1253 (1 .. File_Path'Length
1256 & File_Path (1 .. GCC_Index));
1262 -- Then we add the appropriate -l switch
1264 Linker_Options.Increment_Last;
1265 Linker_Options.Table (Linker_Options.Last) :=
1266 new String'(Next_Line
(Nfirst
.. Nlast
));
1270 -- If gnatlib library not found, then
1271 -- add it anyway in case some other
1272 -- mechanimsm may find it.
1274 Linker_Options
.Increment_Last
;
1275 Linker_Options
.Table
(Linker_Options
.Last
) :=
1276 new String'(Next_Line (Nfirst .. Nlast));
1280 Linker_Options.Increment_Last;
1281 Linker_Options.Table (Linker_Options.Last) :=
1282 new String'(Next_Line
(Nfirst
.. Nlast
));
1286 Xlinker_Was_Previous
:= Next_Line
(Nfirst
.. Nlast
) = "-Xlinker";
1289 exit when Next_Line
(Nfirst
.. Nlast
) = End_Info
;
1291 if Ada_Bind_File
then
1292 Next_Line
(Nfirst
.. Nlast
- 8) :=
1293 Next_Line
(Nfirst
+ 8 .. Nlast
);
1299 -- If -shared was specified, invoke gcc with -shared-libgcc
1302 Linker_Options
.Increment_Last
;
1303 Linker_Options
.Table
(Linker_Options
.Last
) := Shared_Libgcc
;
1306 Status
:= fclose
(Fd
);
1307 end Process_Binder_File
;
1313 procedure Write_Header
is
1315 if Verbose_Mode
then
1317 Write_Str
("GNATLINK ");
1318 Write_Str
(Gnat_Version_String
);
1320 Write_Str
("Copyright 1995-" &
1322 ", Free Software Foundation, Inc");
1331 procedure Write_Usage
is
1335 Write_Str
("Usage: ");
1336 Write_Str
(Base_Name
(Command_Name
));
1337 Write_Str
(" switches mainprog.ali [non-Ada-objects] [linker-options]");
1340 Write_Line
(" mainprog.ali the ALI file of the main program");
1342 Write_Line
(" -A Binder generated source file is in Ada (default)");
1343 Write_Line
(" -C Binder generated source file is in C");
1344 Write_Line
(" -f force object file list to be generated");
1345 Write_Line
(" -g Compile binder source file with debug information");
1346 Write_Line
(" -n Do not compile the binder source file");
1347 Write_Line
(" -R Do not use a run_path_option");
1348 Write_Line
(" -v verbose mode");
1349 Write_Line
(" -v -v very verbose mode");
1351 Write_Line
(" -o nam Use 'nam' as the name of the executable");
1352 Write_Line
(" -b target Compile the binder source to run on target");
1353 Write_Line
(" -Bdir Load compiler executables from dir");
1355 if Is_Supported
(Map_File
) then
1356 Write_Line
(" -Mmap Create map file map");
1357 Write_Line
(" -M Create map file mainprog.map");
1360 Write_Line
(" --GCC=comp Use comp as the compiler");
1361 Write_Line
(" --LINK=nam Use 'nam' for the linking rather than 'gcc'");
1363 Write_Line
(" [non-Ada-objects] list of non Ada object files");
1364 Write_Line
(" [linker-options] other options for the linker");
1367 -- Start of processing for Gnatlink
1370 -- Add the directory where gnatlink is invoked in front of the
1371 -- path, if gnatlink is invoked with directory information.
1372 -- Only do this if the platform is not VMS, where the notion of path
1373 -- does not really exist.
1375 if not Hostparm
.OpenVMS
then
1377 Command
: constant String := Command_Name
;
1380 for Index
in reverse Command
'Range loop
1381 if Command
(Index
) = Directory_Separator
then
1383 Absolute_Dir
: constant String :=
1385 (Command
(Command
'First .. Index
));
1387 PATH
: constant String :=
1390 Getenv
("PATH").all;
1393 Setenv
("PATH", PATH
);
1404 if Argument_Count
= 0
1406 (Verbose_Mode
and then Argument_Count
= 1)
1409 Exit_Program
(E_Fatal
);
1412 if Hostparm
.Java_VM
then
1413 Gcc
:= new String'("jgnat");
1414 Ada_Bind_File := True;
1415 Begin_Info := "-- BEGIN Object file/option list";
1416 End_Info := "-- END Object file/option list ";
1419 -- We always compile with -c
1421 Binder_Options_From_ALI.Increment_Last;
1422 Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
1425 -- If the main program is in Ada it is compiled with the following
1428 -- -gnatA stops reading gnat.adc, since we don't know what
1429 -- pagmas would work, and we do not need it anyway.
1431 -- -gnatWb allows brackets coding for wide characters
1433 -- -gnatiw allows wide characters in identifiers. This is needed
1434 -- because bindgen uses brackets encoding for all upper
1435 -- half and wide characters in identifier names.
1437 if Ada_Bind_File
then
1438 Binder_Options_From_ALI
.Increment_Last
;
1439 Binder_Options_From_ALI
.Table
(Binder_Options_From_ALI
.Last
) :=
1440 new String'("-gnatA");
1441 Binder_Options_From_ALI.Increment_Last;
1442 Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
1443 new String'("-gnatWb");
1444 Binder_Options_From_ALI
.Increment_Last
;
1445 Binder_Options_From_ALI
.Table
(Binder_Options_From_ALI
.Last
) :=
1446 new String'("-gnatiw");
1449 -- Locate all the necessary programs and verify required files are present
1451 Gcc_Path := GNAT.OS_Lib.Locate_Exec_On_Path (Gcc.all);
1453 if Gcc_Path = null then
1454 Exit_With_Error ("Couldn't locate " & Gcc.all);
1457 if Linker_Path = null then
1458 Linker_Path := Gcc_Path;
1461 if Ali_File_Name = null then
1462 Exit_With_Error ("no ali file given for link");
1465 if not Is_Regular_File (Ali_File_Name.all) then
1466 Exit_With_Error (Ali_File_Name.all & " not found");
1469 -- Get target parameters
1474 Osint.Add_Default_Search_Dirs;
1475 Targparm.Get_Target_Parameters;
1477 -- Read the ALI file of the main subprogram if the binder generated
1478 -- file needs to be compiled and no --GCC= switch has been specified.
1479 -- Fetch the back end switches from this ALI file and use these switches
1480 -- to compile the binder generated file
1482 if Compile_Bind_File and then Standard_Gcc then
1485 Name_Len := Ali_File_Name'Length;
1486 Name_Buffer (1 .. Name_Len) := Ali_File_Name.all;
1490 F : constant File_Name_Type := Name_Find;
1491 T : Text_Buffer_Ptr;
1495 -- Load the ALI file
1497 T := Read_Library_Info (F, True);
1499 -- Read it. Note that we ignore errors, since we only want very
1500 -- limited information from the ali file, and likely a slightly
1501 -- wrong version will be just fine, though in normal operation
1502 -- we don't expect this to happen!
1509 Ignore_Errors => True);
1511 if A /= No_ALI_Id then
1513 Index in Units.Table (ALIs.Table (A).First_Unit).First_Arg ..
1514 Units.Table (ALIs.Table (A).First_Unit).Last_Arg
1516 -- Do not compile with the front end switches except for --RTS
1517 -- if the binder generated file is in Ada.
1520 Arg : String_Ptr renames Args.Table (Index);
1522 if not Is_Front_End_Switch (Arg.all)
1525 and then Arg'Length > 5
1526 and then Arg (Arg'First + 2 .. Arg'First + 5) = "RTS=")
1528 Binder_Options_From_ALI.Increment_Last;
1529 Binder_Options_From_ALI.Table
1530 (Binder_Options_From_ALI.Last) := String_Access (Arg);
1540 -- If no output name specified, then use the base name of .ali file name
1542 if Output_File_Name = null then
1544 new String'(Base_Name
(Ali_File_Name
.all)
1545 & Get_Target_Debuggable_Suffix
.all);
1547 Linker_Options
.Increment_Last
;
1548 Linker_Options
.Table
(Linker_Options
.Last
) :=
1551 Linker_Options.Increment_Last;
1552 Linker_Options.Table (Linker_Options.Last) :=
1553 new String'(Output_File_Name
.all);
1556 -- Warn if main program is called "test", as that may be a built-in command
1557 -- on Unix. On non-Unix systems executables have a suffix, so the warning
1558 -- will not appear. However, do not warn in the case of a cross compiler.
1560 -- Assume this is a cross tool if the executable name is not gnatlink
1562 if Base_Name
(Command_Name
) = "gnatlink"
1563 and then Output_File_Name
.all = "test"
1565 Error_Msg
("warning: executable name """ & Output_File_Name
.all
1566 & """ may conflict with shell command");
1569 -- If -M switch was specified, add the switches to create the map file
1571 if Create_Map_File
then
1573 Map_Name
: constant String := Base_Name
(Ali_File_Name
.all) & ".map";
1574 Switches
: String_List_Access
;
1577 Convert
(Map_File
, Map_Name
, Switches
);
1579 if Switches
/= null then
1580 for J
in Switches
'Range loop
1581 Linker_Options
.Increment_Last
;
1582 Linker_Options
.Table
(Linker_Options
.Last
) := Switches
(J
);
1588 -- Perform consistency checks
1590 -- Transform the .ali file name into the binder output file name
1592 Make_Binder_File_Names
: declare
1593 Fname
: constant String := Base_Name
(Ali_File_Name
.all);
1594 Fname_Len
: Integer := Fname
'Length;
1596 function Get_Maximum_File_Name_Length
return Integer;
1597 pragma Import
(C
, Get_Maximum_File_Name_Length
,
1598 "__gnat_get_maximum_file_name_length");
1600 Maximum_File_Name_Length
: constant Integer :=
1601 Get_Maximum_File_Name_Length
;
1603 Bind_File_Prefix
: Types
.String_Ptr
;
1604 -- Contains prefix used for bind files
1609 if not Ada_Bind_File
then
1610 Bind_File_Prefix
:= new String'("b_");
1611 elsif OpenVMS_On_Target then
1612 Bind_File_Prefix := new String'("b__");
1614 Bind_File_Prefix
:= new String'("b~");
1617 -- If the length of the binder file becomes too long due to
1618 -- the addition of the "b?" prefix, then truncate it.
1620 if Maximum_File_Name_Length > 0 then
1622 Maximum_File_Name_Length - Bind_File_Prefix.all'Length
1624 Fname_Len := Fname_Len - 1;
1629 Fnam : constant String :=
1630 Bind_File_Prefix.all &
1631 Fname (Fname'First .. Fname'First + Fname_Len - 1);
1634 if Ada_Bind_File then
1635 Binder_Spec_Src_File := new String'(Fnam
& ".ads");
1636 Binder_Body_Src_File
:= new String'(Fnam & ".adb");
1637 Binder_Ali_File := new String'(Fnam
& ".ali");
1639 Binder_Body_Src_File
:= new String'(Fnam & ".c");
1642 Binder_Obj_File := new String'(Fnam
& Get_Target_Object_Suffix
.all);
1645 if Fname_Len
/= Fname
'Length then
1646 Binder_Options
.Increment_Last
;
1647 Binder_Options
.Table
(Binder_Options
.Last
) := new String'("-o");
1648 Binder_Options.Increment_Last;
1649 Binder_Options.Table (Binder_Options.Last) := Binder_Obj_File;
1651 end Make_Binder_File_Names;
1653 Process_Binder_File (Binder_Body_Src_File.all & ASCII.NUL);
1655 -- Compile the binder file. This is fast, so we always do it, unless
1656 -- specifically told not to by the -n switch
1658 if Compile_Bind_File then
1661 Args : Argument_List
1662 (1 .. Binder_Options_From_ALI.Last + Binder_Options.Last + 1);
1665 for J in 1 .. Binder_Options_From_ALI.Last loop
1666 Args (J) := Binder_Options_From_ALI.Table (J);
1669 for J in 1 .. Binder_Options.Last loop
1670 Args (Binder_Options_From_ALI.Last + J) :=
1671 Binder_Options.Table (J);
1674 Args (Args'Last) := Binder_Body_Src_File;
1676 if Verbose_Mode then
1677 Write_Str (Base_Name (Gcc_Path.all));
1679 for J in Args'Range loop
1681 Write_Str (Args (J).all);
1687 GNAT.OS_Lib.Spawn (Gcc_Path.all, Args, Success);
1690 Exit_Program (E_Fatal);
1695 -- Now, actually link the program
1697 -- Skip this step for now on the JVM since the Java interpreter will do
1698 -- the actual link at run time. We might consider packing all class files
1699 -- in a .zip file during this step.
1701 if not Hostparm.Java_VM then
1703 Num_Args : Natural :=
1704 (Linker_Options.Last - Linker_Options.First + 1) +
1705 (Gcc_Linker_Options.Last - Gcc_Linker_Options.First + 1) +
1706 (Linker_Objects.Last - Linker_Objects.First + 1);
1707 Stack_Op : Boolean := False;
1708 IDENT_Op : Boolean := False;
1711 -- Remove duplicate stack size setting from the Linker_Options
1712 -- table. The stack setting option "-Xlinker --stack=R,C" can be
1713 -- found in one line when set by a pragma Linker_Options or in two
1714 -- lines ("-Xlinker" then "--stack=R,C") when set on the command
1715 -- line. We also check for the "-Wl,--stack=R" style option.
1717 -- We must remove the second stack setting option instance
1718 -- because the one on the command line will always be the first
1719 -- one. And any subsequent stack setting option will overwrite the
1720 -- previous one. This is done especially for GNAT/NT where we set
1721 -- the stack size for tasking programs by a pragma in the NT
1722 -- specific tasking package System.Task_Primitives.Oparations.
1724 -- Note: This is not a FOR loop that runs from Linker_Options.First
1725 -- to Linker_Options.Last, since operations within the loop can
1726 -- modify the length of the table.
1728 Clean_Link_Option_Set : declare
1729 J : Natural := Linker_Options.First;
1730 Shared_Libgcc_Seen : Boolean := False;
1733 while J <= Linker_Options.Last loop
1735 if Linker_Options.Table (J).all = "-Xlinker"
1736 and then J < Linker_Options.Last
1737 and then Linker_Options.Table (J + 1)'Length > 8
1738 and then Linker_Options.Table (J + 1) (1 .. 8) = "--stack="
1741 Linker_Options.Table (J .. Linker_Options.Last - 2) :=
1742 Linker_Options.Table (J + 2 .. Linker_Options.Last);
1743 Linker_Options.Decrement_Last;
1744 Linker_Options.Decrement_Last;
1745 Num_Args := Num_Args - 2;
1752 -- Remove duplicate -shared-libgcc switch
1754 if Linker_Options.Table (J).all = Shared_Libgcc_String then
1755 if Shared_Libgcc_Seen then
1756 Linker_Options.Table (J .. Linker_Options.Last - 1) :=
1757 Linker_Options.Table (J + 1 .. Linker_Options.Last);
1758 Linker_Options.Decrement_Last;
1759 Num_Args := Num_Args - 1;
1762 Shared_Libgcc_Seen := True;
1766 -- Here we just check for a canonical form that matches the
1767 -- pragma Linker_Options set in the NT runtime.
1769 if (Linker_Options.Table (J)'Length > 17
1770 and then Linker_Options.Table (J) (1 .. 17)
1771 = "-Xlinker --stack=")
1773 (Linker_Options.Table (J)'Length > 12
1774 and then Linker_Options.Table (J) (1 .. 12)
1778 Linker_Options.Table (J .. Linker_Options.Last - 1) :=
1779 Linker_Options.Table (J + 1 .. Linker_Options.Last);
1780 Linker_Options.Decrement_Last;
1781 Num_Args := Num_Args - 1;
1788 -- Remove duplicate IDENTIFICATION directives (VMS)
1790 if Linker_Options.Table (J)'Length > 27
1791 and then Linker_Options.Table (J) (1 .. 28)
1792 = "--for-linker=IDENTIFICATION="
1795 Linker_Options.Table (J .. Linker_Options.Last - 1) :=
1796 Linker_Options.Table (J + 1 .. Linker_Options.Last);
1797 Linker_Options.Decrement_Last;
1798 Num_Args := Num_Args - 1;
1806 end Clean_Link_Option_Set;
1808 -- Prepare arguments for call to linker
1810 Call_Linker : declare
1812 Args : Argument_List (1 .. Num_Args + 1);
1813 Index : Integer := Args'First;
1816 Args (Index) := Binder_Obj_File;
1818 -- Add the object files and any -largs libraries
1820 for J in Linker_Objects.First .. Linker_Objects.Last loop
1822 Args (Index) := Linker_Objects.Table (J);
1825 -- Add the linker options from the binder file
1827 for J in Linker_Options.First .. Linker_Options.Last loop
1829 Args (Index) := Linker_Options.Table (J);
1832 -- Finally add the libraries from the --GCC= switch
1834 for J in Gcc_Linker_Options.First .. Gcc_Linker_Options.Last loop
1836 Args (Index) := Gcc_Linker_Options.Table (J);
1839 if Verbose_Mode then
1840 Write_Str (Linker_Path.all);
1842 for J in Args'Range loop
1844 Write_Str (Args (J).all);
1849 -- If we are on very verbose mode (-v -v) and a response file
1850 -- is used we display its content.
1852 if Very_Verbose_Mode and then Tname_FD /= Invalid_FD then
1854 Write_Str ("Response file (" &
1855 Tname (Tname'First .. Tname'Last - 1) &
1860 Response_File_Objects.First ..
1861 Response_File_Objects.Last
1863 Write_Str (Response_File_Objects.Table (J).all);
1871 GNAT.OS_Lib.Spawn (Linker_Path.all, Args, Success);
1873 -- Delete the temporary file used in conjuction with linking if
1874 -- one was created. See Process_Bind_File for details.
1876 if Tname_FD /= Invalid_FD then
1881 Error_Msg ("cannot call " & Linker_Path.all);
1882 Exit_Program (E_Fatal);
1888 -- Only keep the binder output file and it's associated object
1889 -- file if compiling with the -g option. These files are only
1890 -- useful if debugging.
1892 if not Debug_Flag_Present then
1893 if Binder_Ali_File /= null then
1894 Delete (Binder_Ali_File.all & ASCII.NUL);
1897 if Binder_Spec_Src_File /= null then
1898 Delete (Binder_Spec_Src_File.all & ASCII.NUL);
1901 Delete (Binder_Body_Src_File.all & ASCII.NUL);
1903 if not Hostparm.Java_VM then
1904 Delete (Binder_Obj_File.all & ASCII.NUL);
1908 Exit_Program (E_Success);
1912 Write_Line (Exception_Information (X));
1913 Exit_With_Error ("INTERNAL ERROR. Please report");