OSDN Git Service

2005-06-14 Jose Ruiz <ruiz@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / mlib-tgt-irix.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             M L I B . T G T                              --
6 --                              (IRIX Version)                              --
7 --                                                                          --
8 --                                 B o d y                                  --
9 --                                                                          --
10 --           Copyright (C) 2003-2005, Ada Core Technologies, Inc.           --
11 --                                                                          --
12 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
13 -- terms of the  GNU General Public License as published  by the Free Soft- --
14 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
15 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
18 -- for  more details.  You should have  received  a copy of the GNU General --
19 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
20 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
21 -- MA 02111-1307, USA.                                                      --
22 --                                                                          --
23 -- GNAT was originally developed  by the GNAT team at  New York University. --
24 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
25 --                                                                          --
26 ------------------------------------------------------------------------------
27
28 --  This package provides a set of target dependent routines to build
29 --  static, dynamic and shared libraries.
30
31 --  This is the IRIX version of the body.
32
33 with MLib.Fil;
34 with MLib.Utl;
35 with Namet;  use Namet;
36 with Opt;
37 with Output; use Output;
38 with Prj.Com;
39 with System;
40
41 package body MLib.Tgt is
42
43    No_Arguments        : aliased Argument_List         := (1 .. 0 => null);
44    Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
45
46    Wl_Init_String : aliased String         := "-Wl,-init";
47    Wl_Init        : constant String_Access := Wl_Init_String'Access;
48    Wl_Fini_String : aliased String         := "-Wl,-fini";
49    Wl_Fini        : constant String_Access := Wl_Fini_String'Access;
50
51    Init_Fini_List :  constant Argument_List_Access :=
52                        new Argument_List'(1 => Wl_Init,
53                                           2 => null,
54                                           3 => Wl_Fini,
55                                           4 => null);
56    --  Used to put switches for automatic elaboration/finalization
57
58    ---------------------
59    -- Archive_Builder --
60    ---------------------
61
62    function Archive_Builder return String is
63    begin
64       return "ar";
65    end Archive_Builder;
66
67    -----------------------------
68    -- Archive_Builder_Options --
69    -----------------------------
70
71    function Archive_Builder_Options return String_List_Access is
72    begin
73       return new String_List'(1 => new String'("cr"));
74    end Archive_Builder_Options;
75
76    -----------------
77    -- Archive_Ext --
78    -----------------
79
80    function Archive_Ext return String is
81    begin
82       return "a";
83    end Archive_Ext;
84
85    ---------------------
86    -- Archive_Indexer --
87    ---------------------
88
89    function Archive_Indexer return String is
90    begin
91       return "ranlib";
92    end Archive_Indexer;
93
94    -----------------------------
95    -- Archive_Indexer_Options --
96    -----------------------------
97
98    function Archive_Indexer_Options return String_List_Access is
99    begin
100       return new String_List (1 .. 0);
101    end Archive_Indexer_Options;
102
103    ---------------------------
104    -- Build_Dynamic_Library --
105    ---------------------------
106
107    procedure Build_Dynamic_Library
108      (Ofiles       : Argument_List;
109       Foreign      : Argument_List;
110       Afiles       : Argument_List;
111       Options      : Argument_List;
112       Options_2    : Argument_List;
113       Interfaces   : Argument_List;
114       Lib_Filename : String;
115       Lib_Dir      : String;
116       Symbol_Data  : Symbol_Record;
117       Driver_Name  : Name_Id := No_Name;
118       Lib_Version  : String  := "";
119       Auto_Init    : Boolean := False)
120    is
121       pragma Unreferenced (Foreign);
122       pragma Unreferenced (Afiles);
123       pragma Unreferenced (Interfaces);
124       pragma Unreferenced (Symbol_Data);
125
126       Lib_File : constant String :=
127                    Lib_Dir & Directory_Separator & "lib" &
128                    MLib.Fil.Ext_To (Lib_Filename, DLL_Ext);
129
130       Version_Arg          : String_Access;
131       Symbolic_Link_Needed : Boolean := False;
132
133       Init_Fini : Argument_List_Access := Empty_Argument_List;
134
135       N_Options    : Argument_List := Options;
136       Options_Last : Natural := N_Options'Last;
137       --  After moving -lxxx to Options_2, N_Options up to index Options_Last
138       --  will contain the Options to pass to MLib.Utl.Gcc.
139
140       Real_Options_2 : Argument_List (1 .. Options'Length + Options_2'Length);
141       Real_Options_2_Last : Natural := 0;
142       --  Real_Options_2 up to index Real_Options_2_Last will contain the
143       --  Options_2 to pass to MLib.Utl.Gcc.
144
145    begin
146       if Opt.Verbose_Mode then
147          Write_Str ("building relocatable shared library ");
148          Write_Line (Lib_File);
149       end if;
150
151       --  If specified, add automatic elaboration/finalization
152
153       if Auto_Init then
154          Init_Fini := Init_Fini_List;
155          Init_Fini (2) := new String'("-Wl," & Lib_Filename & "init");
156          Init_Fini (4) := new String'("-Wl," & Lib_Filename & "final");
157       end if;
158
159       --  Move all -lxxx to Options_2
160
161       declare
162          Index : Natural := N_Options'First;
163          Arg   : String_Access;
164
165       begin
166          while Index <= Options_Last loop
167             Arg := N_Options (Index);
168
169             if Arg'Length > 2
170               and then Arg (Arg'First .. Arg'First + 1) = "-l"
171             then
172                Real_Options_2_Last := Real_Options_2_Last + 1;
173                Real_Options_2 (Real_Options_2_Last) := Arg;
174                N_Options (Index .. Options_Last - 1) :=
175                  N_Options (Index + 1 .. Options_Last);
176                Options_Last := Options_Last - 1;
177
178             else
179                Index := Index + 1;
180             end if;
181          end loop;
182       end;
183
184       --  Add to Real_Options_2 the argument Options_2
185
186       Real_Options_2
187         (Real_Options_2_Last + 1 .. Real_Options_2_Last + Options_2'Length) :=
188         Options_2;
189       Real_Options_2_Last := Real_Options_2_Last + Options_2'Length;
190
191       if Lib_Version = "" then
192          MLib.Utl.Gcc
193            (Output_File => Lib_File,
194             Objects     => Ofiles,
195             Options     => N_Options (N_Options'First .. Options_Last) &
196                            Init_Fini.all,
197             Driver_Name => Driver_Name,
198             Options_2   => Real_Options_2 (1 .. Real_Options_2_Last));
199
200       else
201          Version_Arg := new String'("-Wl,-soname," & Lib_Version);
202
203          if Is_Absolute_Path (Lib_Version) then
204             MLib.Utl.Gcc
205               (Output_File => Lib_Version,
206                Objects     => Ofiles,
207                Options     => N_Options (N_Options'First .. Options_Last) &
208                               Version_Arg & Init_Fini.all,
209                Driver_Name => Driver_Name,
210                Options_2   => Real_Options_2 (1 .. Real_Options_2_Last));
211             Symbolic_Link_Needed := Lib_Version /= Lib_File;
212
213          else
214             MLib.Utl.Gcc
215               (Output_File => Lib_Dir & Directory_Separator & Lib_Version,
216                Objects     => Ofiles,
217                Options     => N_Options (N_Options'First .. Options_Last) &
218                               Version_Arg & Init_Fini.all,
219                Driver_Name => Driver_Name,
220                Options_2   => Real_Options_2 (1 .. Real_Options_2_Last));
221             Symbolic_Link_Needed :=
222               Lib_Dir & Directory_Separator & Lib_Version /= Lib_File;
223          end if;
224
225          if Symbolic_Link_Needed then
226             declare
227                Success : Boolean;
228                Oldpath : String (1 .. Lib_Version'Length + 1);
229                Newpath : String (1 .. Lib_File'Length + 1);
230
231                Result : Integer;
232                pragma Unreferenced (Result);
233
234                function Symlink
235                  (Oldpath : System.Address;
236                   Newpath : System.Address)
237                   return    Integer;
238                pragma Import (C, Symlink, "__gnat_symlink");
239
240             begin
241                Oldpath (1 .. Lib_Version'Length) := Lib_Version;
242                Oldpath (Oldpath'Last)            := ASCII.NUL;
243                Newpath (1 .. Lib_File'Length)    := Lib_File;
244                Newpath (Newpath'Last)            := ASCII.NUL;
245
246                Delete_File (Lib_File, Success);
247
248                Result := Symlink (Oldpath'Address, Newpath'Address);
249             end;
250          end if;
251       end if;
252    end Build_Dynamic_Library;
253
254    -------------
255    -- DLL_Ext --
256    -------------
257
258    function DLL_Ext return String is
259    begin
260       return "so";
261    end DLL_Ext;
262
263    --------------------
264    -- Dynamic_Option --
265    --------------------
266
267    function Dynamic_Option return String is
268    begin
269       return "-shared";
270    end Dynamic_Option;
271
272    -------------------
273    -- Is_Object_Ext --
274    -------------------
275
276    function Is_Object_Ext (Ext : String) return Boolean is
277    begin
278       return Ext = ".o";
279    end Is_Object_Ext;
280
281    --------------
282    -- Is_C_Ext --
283    --------------
284
285    function Is_C_Ext (Ext : String) return Boolean is
286    begin
287       return Ext = ".c";
288    end Is_C_Ext;
289
290    --------------------
291    -- Is_Archive_Ext --
292    --------------------
293
294    function Is_Archive_Ext (Ext : String) return Boolean is
295    begin
296       return Ext = ".a" or else Ext = ".so";
297    end Is_Archive_Ext;
298
299    -------------
300    -- Libgnat --
301    -------------
302
303    function Libgnat return String is
304    begin
305       return "libgnat.a";
306    end Libgnat;
307
308    ------------------------
309    -- Library_Exists_For --
310    ------------------------
311
312    function Library_Exists_For
313      (Project : Project_Id; In_Tree : Project_Tree_Ref) return Boolean
314    is
315    begin
316       if not In_Tree.Projects.Table (Project).Library then
317          Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
318                        "for non library project");
319          return False;
320
321       else
322          declare
323             Lib_Dir : constant String :=
324               Get_Name_String
325                 (In_Tree.Projects.Table (Project).Library_Dir);
326             Lib_Name : constant String :=
327               Get_Name_String
328                 (In_Tree.Projects.Table (Project).Library_Name);
329
330          begin
331             if In_Tree.Projects.Table (Project).Library_Kind =
332               Static
333             then
334                return Is_Regular_File
335                  (Lib_Dir & Directory_Separator & "lib" &
336                   Fil.Ext_To (Lib_Name, Archive_Ext));
337
338             else
339                return Is_Regular_File
340                  (Lib_Dir & Directory_Separator & "lib" &
341                   Fil.Ext_To (Lib_Name, DLL_Ext));
342             end if;
343          end;
344       end if;
345    end Library_Exists_For;
346
347    ---------------------------
348    -- Library_File_Name_For --
349    ---------------------------
350
351    function Library_File_Name_For
352      (Project : Project_Id;
353       In_Tree : Project_Tree_Ref) return Name_Id
354    is
355    begin
356       if not In_Tree.Projects.Table (Project).Library then
357          Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
358                        "for non library project");
359          return No_Name;
360
361       else
362          declare
363             Lib_Name : constant String :=
364               Get_Name_String
365                 (In_Tree.Projects.Table (Project).Library_Name);
366
367          begin
368             Name_Len := 3;
369             Name_Buffer (1 .. Name_Len) := "lib";
370
371             if In_Tree.Projects.Table (Project).Library_Kind =
372               Static
373             then
374                Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
375
376             else
377                Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
378             end if;
379
380             return Name_Find;
381          end;
382       end if;
383    end Library_File_Name_For;
384
385    ----------------
386    -- Object_Ext --
387    ----------------
388
389    function Object_Ext return String is
390    begin
391       return "o";
392    end Object_Ext;
393
394    ----------------
395    -- PIC_Option --
396    ----------------
397
398    function PIC_Option return String is
399    begin
400       return "-fPIC";
401    end PIC_Option;
402
403    -----------------------------------------------
404    -- Standalone_Library_Auto_Init_Is_Supported --
405    -----------------------------------------------
406
407    function Standalone_Library_Auto_Init_Is_Supported return Boolean is
408    begin
409       return True;
410    end Standalone_Library_Auto_Init_Is_Supported;
411
412    ---------------------------
413    -- Support_For_Libraries --
414    ---------------------------
415
416    function Support_For_Libraries return Library_Support is
417    begin
418       return Full;
419    end Support_For_Libraries;
420
421 end MLib.Tgt;