OSDN Git Service

2005-03-29 Ed Falis <falis@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / mlib-tgt-darwin.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             M L I B . T G T                              --
6 --                             (Darwin Version)                             --
7 --                                                                          --
8 --                                 B o d y                                  --
9 --                                                                          --
10 --              Copyright (C) 2001-2005, Free Software Foundation, 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 Darwin 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    use GNAT;
44    use MLib;
45
46    No_Arguments        : aliased Argument_List         := (1 .. 0 => null);
47    Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
48
49    Wl_Init_String : aliased String         := "-Wl,-init";
50    Wl_Init        : constant String_Access := Wl_Init_String'Access;
51
52    Init_Fini_List :  constant Argument_List_Access :=
53                        new Argument_List'(1 => Wl_Init,
54                                           2 => null);
55    --  Used to put switches for automatic elaboration. Note that there is no
56    --  linking option on Darwin for automatic finalization of a shared
57    --  library.
58
59    ---------------------
60    -- Archive_Builder --
61    ---------------------
62
63    function Archive_Builder return String is
64    begin
65       return "ar";
66    end Archive_Builder;
67
68    -----------------------------
69    -- Archive_Builder_Options --
70    -----------------------------
71
72    function Archive_Builder_Options return String_List_Access is
73    begin
74       return new String_List'(1 => new String'("cr"));
75    end Archive_Builder_Options;
76
77    -----------------
78    -- Archive_Ext --
79    -----------------
80
81    function Archive_Ext return  String is
82    begin
83       return "a";
84    end Archive_Ext;
85
86    ---------------------
87    -- Archive_Indexer --
88    ---------------------
89
90    function Archive_Indexer return String is
91    begin
92       return "ranlib";
93    end Archive_Indexer;
94
95    -----------------------------
96    -- Archive_Indexer_Options --
97    -----------------------------
98
99    function Archive_Indexer_Options return String_List_Access is
100    begin
101       return new String_List'(1 => new String'("-c"));
102    end Archive_Indexer_Options;
103
104    ---------------------------
105    -- Build_Dynamic_Library --
106    ---------------------------
107
108    procedure Build_Dynamic_Library
109      (Ofiles       : Argument_List;
110       Foreign      : Argument_List;
111       Afiles       : Argument_List;
112       Options      : Argument_List;
113       Options_2    : Argument_List;
114       Interfaces   : Argument_List;
115       Lib_Filename : String;
116       Lib_Dir      : String;
117       Symbol_Data  : Symbol_Record;
118       Driver_Name  : Name_Id := No_Name;
119       Lib_Version  : String  := "";
120       Auto_Init    : Boolean := False)
121    is
122       pragma Unreferenced (Foreign);
123       pragma Unreferenced (Afiles);
124       pragma Unreferenced (Interfaces);
125       pragma Unreferenced (Symbol_Data);
126
127       Lib_File : constant String :=
128                    Lib_Dir & Directory_Separator & "lib" &
129                    Fil.Ext_To (Lib_Filename, DLL_Ext);
130
131       Version_Arg          : String_Access;
132       Symbolic_Link_Needed : Boolean := False;
133
134       Init_Fini : Argument_List_Access := Empty_Argument_List;
135
136    begin
137       if Opt.Verbose_Mode then
138          Write_Str ("building relocatable shared library ");
139          Write_Line (Lib_File);
140       end if;
141
142       --  If specified, add automatic elaboration/finalization
143
144       if Auto_Init then
145          Init_Fini := Init_Fini_List;
146          Init_Fini (2) := new String'("-Wl,_" & Lib_Filename & "init");
147       end if;
148
149       if Lib_Version = "" then
150          Utl.Gcc
151            (Output_File => Lib_File,
152             Objects     => Ofiles,
153             Options     => Options & Init_Fini.all,
154             Driver_Name => Driver_Name,
155             Options_2   => Options_2);
156
157       else
158          --  Instruct the linker to build the shared library as a flat
159          --  namespace image, which is not the default. The default is a two
160          --  level namespace image.
161
162          Version_Arg := new String'("-Wl,-flat_namespace");
163
164          if Is_Absolute_Path (Lib_Version) then
165             Utl.Gcc
166               (Output_File => Lib_Version,
167                Objects     => Ofiles,
168                Options     => Options & Version_Arg & Init_Fini.all,
169                Driver_Name => Driver_Name,
170                Options_2   => Options_2);
171             Symbolic_Link_Needed := Lib_Version /= Lib_File;
172
173          else
174             Utl.Gcc
175               (Output_File => Lib_Dir & Directory_Separator & Lib_Version,
176                Objects     => Ofiles,
177                Options     => Options & Version_Arg & Init_Fini.all,
178                Driver_Name => Driver_Name,
179                Options_2   => Options_2);
180             Symbolic_Link_Needed :=
181               Lib_Dir & Directory_Separator & Lib_Version /= Lib_File;
182          end if;
183
184          if Symbolic_Link_Needed then
185             declare
186                Success : Boolean;
187                Oldpath : String (1 .. Lib_Version'Length + 1);
188                Newpath : String (1 .. Lib_File'Length + 1);
189
190                Result : Integer;
191                pragma Unreferenced (Result);
192
193                function Symlink
194                  (Oldpath : System.Address;
195                   Newpath : System.Address) return Integer;
196                pragma Import (C, Symlink, "__gnat_symlink");
197
198             begin
199                Oldpath (1 .. Lib_Version'Length) := Lib_Version;
200                Oldpath (Oldpath'Last)            := ASCII.NUL;
201                Newpath (1 .. Lib_File'Length)    := Lib_File;
202                Newpath (Newpath'Last)            := ASCII.NUL;
203
204                Delete_File (Lib_File, Success);
205
206                Result := Symlink (Oldpath'Address, Newpath'Address);
207             end;
208          end if;
209       end if;
210    end Build_Dynamic_Library;
211
212    -------------
213    -- DLL_Ext --
214    -------------
215
216    function DLL_Ext return String is
217    begin
218       return "dylib";
219    end DLL_Ext;
220
221    --------------------
222    -- Dynamic_Option --
223    --------------------
224
225    function Dynamic_Option return String is
226    begin
227       return "-dynamiclib";
228    end Dynamic_Option;
229
230    -------------------
231    -- Is_Object_Ext --
232    -------------------
233
234    function Is_Object_Ext (Ext : String) return Boolean is
235    begin
236       return Ext = ".o";
237    end Is_Object_Ext;
238
239    --------------
240    -- Is_C_Ext --
241    --------------
242
243    function Is_C_Ext (Ext : String) return Boolean is
244    begin
245       return Ext = ".c";
246    end Is_C_Ext;
247
248    --------------------
249    -- Is_Archive_Ext --
250    --------------------
251
252    function Is_Archive_Ext (Ext : String) return Boolean is
253    begin
254       return Ext = ".dylib" or else Ext = ".a";
255    end Is_Archive_Ext;
256
257    -------------
258    -- Libgnat --
259    -------------
260
261    function Libgnat return String is
262    begin
263       return "libgnat.a";
264    end Libgnat;
265
266    ------------------------
267    -- Library_Exists_For --
268    ------------------------
269
270    function Library_Exists_For
271      (Project : Project_Id; In_Tree : Project_Tree_Ref) return Boolean
272    is
273    begin
274       if not In_Tree.Projects.Table (Project).Library then
275          Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
276                        "for non library project");
277          return False;
278
279       else
280          declare
281             Lib_Dir : constant String :=
282               Get_Name_String
283                 (In_Tree.Projects.Table (Project).Library_Dir);
284             Lib_Name : constant String :=
285               Get_Name_String
286                 (In_Tree.Projects.Table (Project).Library_Name);
287
288          begin
289             if In_Tree.Projects.Table (Project).Library_Kind =
290               Static
291             then
292                return Is_Regular_File
293                  (Lib_Dir & Directory_Separator & "lib" &
294                   Fil.Ext_To (Lib_Name, Archive_Ext));
295
296             else
297                return Is_Regular_File
298                  (Lib_Dir & Directory_Separator & "lib" &
299                   Fil.Ext_To (Lib_Name, DLL_Ext));
300             end if;
301          end;
302       end if;
303    end Library_Exists_For;
304
305    ---------------------------
306    -- Library_File_Name_For --
307    ---------------------------
308
309    function Library_File_Name_For
310      (Project : Project_Id;
311       In_Tree : Project_Tree_Ref) return Name_Id
312    is
313    begin
314       if not In_Tree.Projects.Table (Project).Library then
315          Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
316                        "for non library project");
317          return No_Name;
318
319       else
320          declare
321             Lib_Name : constant String :=
322               Get_Name_String
323                 (In_Tree.Projects.Table (Project).Library_Name);
324
325          begin
326             Name_Len := 3;
327             Name_Buffer (1 .. Name_Len) := "lib";
328
329             if In_Tree.Projects.Table (Project).Library_Kind =
330               Static then
331                Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
332
333             else
334                Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
335             end if;
336
337             return Name_Find;
338          end;
339       end if;
340    end Library_File_Name_For;
341
342    ----------------
343    -- Object_Ext --
344    ----------------
345
346    function Object_Ext return String is
347    begin
348       return "o";
349    end Object_Ext;
350
351    ----------------
352    -- PIC_Option --
353    ----------------
354
355    function PIC_Option return String is
356    begin
357       return "-fPIC";
358    end PIC_Option;
359
360    -----------------------------------------------
361    -- Standalone_Library_Auto_Init_Is_Supported --
362    -----------------------------------------------
363
364    function Standalone_Library_Auto_Init_Is_Supported return Boolean is
365    begin
366       return True;
367    end Standalone_Library_Auto_Init_Is_Supported;
368
369    ---------------------------
370    -- Support_For_Libraries --
371    ---------------------------
372
373    function Support_For_Libraries return Library_Support is
374    begin
375       return Full;
376    end Support_For_Libraries;
377
378 end MLib.Tgt;