1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
10 -- Copyright (C) 2001, Ada Core Technologies, Inc. --
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. --
23 -- GNAT was originally developed by the GNAT team at New York University. --
24 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
26 ------------------------------------------------------------------------------
28 with Ada
.Characters
.Handling
;
30 with GNAT
.Directory_Operations
; use GNAT
.Directory_Operations
;
31 with GNAT
.OS_Lib
; use GNAT
.OS_Lib
;
35 with Output
; use Output
;
36 with Osint
; use Osint
;
37 with Namet
; use Namet
;
39 with Types
; use Types
;
41 package body MLib
.Prj
is
43 package Files
renames MLib
.Fil
;
44 package Target
renames MLib
.Tgt
;
46 -- List of objects to put inside the library
48 Object_Files
: Argument_List_Access
;
49 package Objects
is new Table
.Table
50 (Table_Name
=> "Mlib.Prj.Objects",
51 Table_Component_Type
=> String_Access
,
52 Table_Index_Type
=> Natural,
55 Table_Increment
=> 50);
57 -- List of non-Ada object files
59 Foreign_Objects
: Argument_List_Access
;
60 package Foreigns
is new Table
.Table
61 (Table_Name
=> "Mlib.Prj.Foreigns",
62 Table_Component_Type
=> String_Access
,
63 Table_Index_Type
=> Natural,
66 Table_Increment
=> 20);
70 Ali_Files
: Argument_List_Access
;
71 package Alis
is new Table
.Table
72 (Table_Name
=> "Mlib.Prj.Alis",
73 Table_Component_Type
=> String_Access
,
74 Table_Index_Type
=> Natural,
77 Table_Increment
=> 50);
79 -- List of options set in the command line.
81 Options
: Argument_List_Access
;
82 package Opts
is new Table
.Table
83 (Table_Name
=> "Mlib.Prj.Opts",
84 Table_Component_Type
=> String_Access
,
85 Table_Index_Type
=> Natural,
88 Table_Increment
=> 5);
90 type Build_Mode_State
is
91 (None
, Static
, Dynamic
, Relocatable
);
93 procedure Check
(Filename
: String);
94 -- Check if filename is a regular file. Fail if it is not.
96 procedure Check_Context
;
97 -- Check each object files in table Object_Files
98 -- Fail if any of them is not a regular file
100 procedure Reset_Tables
;
101 -- Make sure that all the above tables are empty
102 -- (Objects, Foreign_Objects, Ali_Files, Options)
108 procedure Build_Library
(For_Project
: Project_Id
) is
109 Data
: constant Project_Data
:= Projects
.Table
(For_Project
);
111 Project_Name
: constant String :=
112 Get_Name_String
(Data
.Name
);
114 Lib_Filename
: String_Access
;
115 Lib_Dirpath
: String_Access
:= new String'(".");
116 DLL_Address : String_Access := new String'(Target
.Default_DLL_Address
);
117 Lib_Version
: String_Access
:= new String'("");
119 The_Build_Mode : Build_Mode_State := None;
124 -- Fail if project is not a library project
126 if not Data.Library then
127 Fail ("project """, Project_Name, """ has no library");
130 Lib_Dirpath := new String'(Get_Name_String
(Data
.Library_Dir
));
131 Lib_Filename
:= new String'(Get_Name_String (Data.Library_Name));
133 case Data.Library_Kind is
135 The_Build_Mode := Static;
138 The_Build_Mode := Dynamic;
141 The_Build_Mode := Relocatable;
143 if Target.PIC_Option /= "" then
145 Opts.Table (Opts.Last) := new String'(Target
.PIC_Option
);
149 -- Get the library version, if any
151 if Data
.Lib_Internal_Name
/= No_Name
then
152 Lib_Version
:= new String'(Get_Name_String (Data.Lib_Internal_Name));
155 -- Add the objects found in the object directory
158 Object_Dir : Dir_Type;
159 Filename : String (1 .. 255);
161 Object_Dir_Path : constant String :=
162 Get_Name_String (Data.Object_Directory);
164 Open (Dir => Object_Dir, Dir_Name => Object_Dir_Path);
166 -- For all entries in the object directory
169 Read (Object_Dir, Filename, Last);
173 -- Check if it is an object file
175 if Files.Is_Obj (Filename (1 .. Last)) then
176 -- record this object file
178 Objects.Increment_Last;
179 Objects.Table (Objects.Last) :=
180 new String' (Object_Dir_Path
& Directory_Separator
&
181 Filename
(1 .. Last
));
185 Files
.Ext_To
(Object_Dir_Path
&
186 Filename
(1 .. Last
), "ali"))
188 -- Record the corresponding ali file
191 Alis
.Table
(Alis
.Last
) :=
192 new String' (Object_Dir_Path &
194 (Filename (1 .. Last), "ali"));
197 -- The object file is a foreign object file
199 Foreigns.Increment_Last;
200 Foreigns.Table (Foreigns.Last) :=
201 new String'(Object_Dir_Path
&
202 Filename
(1 .. Last
));
208 Close
(Dir
=> Object_Dir
);
211 when Directory_Error
=>
212 Fail
("cannot find object directory """,
213 Get_Name_String
(Data
.Object_Directory
),
217 -- We want to link some Ada files, so we need to link with
218 -- the GNAT runtime (libgnat & libgnarl)
220 if The_Build_Mode
= Dynamic
or else The_Build_Mode
= Relocatable
then
222 Opts
.Table
(Opts
.Last
) := new String' ("-lgnarl");
224 Opts.Table (Opts.Last) := new String' ("-lgnat");
228 new Argument_List
'(Argument_List (Objects.Table (1 .. Objects.Last)));
231 new Argument_List'(Argument_List
232 (Foreigns
.Table
(1 .. Foreigns
.Last
)));
235 new Argument_List
'(Argument_List (Alis.Table (1 .. Alis.Last)));
238 new Argument_List'(Argument_List
(Opts
.Table
(1 .. Opts
.Last
)));
240 -- We fail if there are no object to put in the library
241 -- (Ada or foreign objects)
243 if Object_Files
'Length = 0 then
244 Fail
("no object files");
248 if not Opt
.Quiet_Output
then
250 Write_Str
("building ");
251 Write_Str
(Ada
.Characters
.Handling
.To_Lower
252 (Build_Mode_State
'Image (The_Build_Mode
)));
253 Write_Str
(" library for project ");
254 Write_Line
(Project_Name
);
258 -- We check that all object files are regular files
262 -- And we call the procedure to build the library,
263 -- depending on the build mode
265 case The_Build_Mode
is
266 when Dynamic | Relocatable
=>
267 Target
.Build_Dynamic_Library
268 (Ofiles
=> Object_Files
.all,
269 Foreign
=> Foreign_Objects
.all,
270 Afiles
=> Ali_Files
.all,
271 Options
=> Options
.all,
272 Lib_Filename
=> Lib_Filename
.all,
273 Lib_Dir
=> Lib_Dirpath
.all,
274 Lib_Address
=> DLL_Address
.all,
275 Lib_Version
=> Lib_Version
.all,
276 Relocatable
=> The_Build_Mode
= Relocatable
);
289 -- We need to copy the ALI files from the object directory
290 -- to the library directory, so that the linker find them
291 -- there, and does not need to look in the object directory
292 -- where it would also find the object files; and we don't want
293 -- that: we want the linker to use the library.
295 Target
.Copy_ALI_Files
296 (From
=> Projects
.Table
(For_Project
).Object_Directory
,
297 To
=> Projects
.Table
(For_Project
).Library_Dir
);
305 procedure Check
(Filename
: String) is
307 if not Is_Regular_File
(Filename
) then
308 Fail
(Filename
, " not found.");
317 procedure Check_Context
is
319 -- check that each object file exist
321 for F
in Object_Files
'Range loop
322 Check
(Object_Files
(F
).all);
330 procedure Reset_Tables
is