1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
11 -- Copyright (C) 2001, Ada Core Technologies, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
27 ------------------------------------------------------------------------------
29 with Ada.Characters.Handling;
31 with GNAT.Directory_Operations; use GNAT.Directory_Operations;
32 with GNAT.OS_Lib; use GNAT.OS_Lib;
36 with Output; use Output;
37 with Osint; use Osint;
38 with Namet; use Namet;
40 with Types; use Types;
42 package body MLib.Prj is
44 package Files renames MLib.Fil;
45 package Target renames MLib.Tgt;
47 -- List of objects to put inside the library
49 Object_Files : Argument_List_Access;
50 package Objects is new Table.Table
51 (Table_Name => "Mlib.Prj.Objects",
52 Table_Component_Type => String_Access,
53 Table_Index_Type => Natural,
56 Table_Increment => 50);
58 -- List of non-Ada object files
60 Foreign_Objects : Argument_List_Access;
61 package Foreigns is new Table.Table
62 (Table_Name => "Mlib.Prj.Foreigns",
63 Table_Component_Type => String_Access,
64 Table_Index_Type => Natural,
67 Table_Increment => 20);
71 Ali_Files : Argument_List_Access;
72 package Alis is new Table.Table
73 (Table_Name => "Mlib.Prj.Alis",
74 Table_Component_Type => String_Access,
75 Table_Index_Type => Natural,
78 Table_Increment => 50);
80 -- List of options set in the command line.
82 Options : Argument_List_Access;
83 package Opts is new Table.Table
84 (Table_Name => "Mlib.Prj.Opts",
85 Table_Component_Type => String_Access,
86 Table_Index_Type => Natural,
89 Table_Increment => 5);
91 type Build_Mode_State is
92 (None, Static, Dynamic, Relocatable);
94 procedure Check (Filename : String);
95 -- Check if filename is a regular file. Fail if it is not.
97 procedure Check_Context;
98 -- Check each object files in table Object_Files
99 -- Fail if any of them is not a regular file
101 procedure Reset_Tables;
102 -- Make sure that all the above tables are empty
103 -- (Objects, Foreign_Objects, Ali_Files, Options)
109 procedure Build_Library (For_Project : Project_Id) is
110 Data : constant Project_Data := Projects.Table (For_Project);
112 Project_Name : constant String :=
113 Get_Name_String (Data.Name);
115 Lib_Filename : String_Access;
116 Lib_Dirpath : String_Access := new String'(".");
117 DLL_Address : String_Access := new String'(Target.Default_DLL_Address);
118 Lib_Version : String_Access := new String'("");
120 The_Build_Mode : Build_Mode_State := None;
125 -- Fail if project is not a library project
127 if not Data.Library then
128 Fail ("project """, Project_Name, """ has no library");
131 Lib_Dirpath := new String'(Get_Name_String (Data.Library_Dir));
132 Lib_Filename := new String'(Get_Name_String (Data.Library_Name));
134 case Data.Library_Kind is
136 The_Build_Mode := Static;
139 The_Build_Mode := Dynamic;
142 The_Build_Mode := Relocatable;
144 if Target.PIC_Option /= "" then
146 Opts.Table (Opts.Last) := new String'(Target.PIC_Option);
150 -- Get the library version, if any
152 if Data.Lib_Internal_Name /= No_Name then
153 Lib_Version := new String'(Get_Name_String (Data.Lib_Internal_Name));
156 -- Add the objects found in the object directory
159 Object_Dir : Dir_Type;
160 Filename : String (1 .. 255);
162 Object_Dir_Path : constant String :=
163 Get_Name_String (Data.Object_Directory);
165 Open (Dir => Object_Dir, Dir_Name => Object_Dir_Path);
167 -- For all entries in the object directory
170 Read (Object_Dir, Filename, Last);
174 -- Check if it is an object file
176 if Files.Is_Obj (Filename (1 .. Last)) then
177 -- record this object file
179 Objects.Increment_Last;
180 Objects.Table (Objects.Last) :=
181 new String' (Object_Dir_Path & Directory_Separator &
182 Filename (1 .. Last));
186 Files.Ext_To (Object_Dir_Path &
187 Filename (1 .. Last), "ali"))
189 -- Record the corresponding ali file
192 Alis.Table (Alis.Last) :=
193 new String' (Object_Dir_Path &
195 (Filename (1 .. Last), "ali"));
198 -- The object file is a foreign object file
200 Foreigns.Increment_Last;
201 Foreigns.Table (Foreigns.Last) :=
202 new String'(Object_Dir_Path &
203 Filename (1 .. Last));
209 Close (Dir => Object_Dir);
212 when Directory_Error =>
213 Fail ("cannot find object directory """,
214 Get_Name_String (Data.Object_Directory),
218 -- We want to link some Ada files, so we need to link with
219 -- the GNAT runtime (libgnat & libgnarl)
221 if The_Build_Mode = Dynamic or else The_Build_Mode = Relocatable then
223 Opts.Table (Opts.Last) := new String' ("-lgnarl");
225 Opts.Table (Opts.Last) := new String' ("-lgnat");
229 new Argument_List'(Argument_List (Objects.Table (1 .. Objects.Last)));
232 new Argument_List'(Argument_List
233 (Foreigns.Table (1 .. Foreigns.Last)));
236 new Argument_List'(Argument_List (Alis.Table (1 .. Alis.Last)));
239 new Argument_List'(Argument_List (Opts.Table (1 .. Opts.Last)));
241 -- We fail if there are no object to put in the library
242 -- (Ada or foreign objects)
244 if Object_Files'Length = 0 then
245 Fail ("no object files");
249 if not Opt.Quiet_Output then
251 Write_Str ("building ");
252 Write_Str (Ada.Characters.Handling.To_Lower
253 (Build_Mode_State'Image (The_Build_Mode)));
254 Write_Str (" library for project ");
255 Write_Line (Project_Name);
259 -- We check that all object files are regular files
263 -- And we call the procedure to build the library,
264 -- depending on the build mode
266 case The_Build_Mode is
267 when Dynamic | Relocatable =>
268 Target.Build_Dynamic_Library
269 (Ofiles => Object_Files.all,
270 Foreign => Foreign_Objects.all,
271 Afiles => Ali_Files.all,
272 Options => Options.all,
273 Lib_Filename => Lib_Filename.all,
274 Lib_Dir => Lib_Dirpath.all,
275 Lib_Address => DLL_Address.all,
276 Lib_Version => Lib_Version.all,
277 Relocatable => The_Build_Mode = Relocatable);
290 -- We need to copy the ALI files from the object directory
291 -- to the library directory, so that the linker find them
292 -- there, and does not need to look in the object directory
293 -- where it would also find the object files; and we don't want
294 -- that: we want the linker to use the library.
296 Target.Copy_ALI_Files
297 (From => Projects.Table (For_Project).Object_Directory,
298 To => Projects.Table (For_Project).Library_Dir);
306 procedure Check (Filename : String) is
308 if not Is_Regular_File (Filename) then
309 Fail (Filename, " not found.");
318 procedure Check_Context is
320 -- check that each object file exist
322 for F in Object_Files'Range loop
323 Check (Object_Files (F).all);
331 procedure Reset_Tables is