1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-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 -- This package provides the core high level routines used by GNATDLL
28 -- to build Windows DLL
32 with GNAT
.Directory_Operations
;
41 function Get_Dll_Name
(Lib_Filename
: String) return String;
42 -- Returns <Lib_Filename> if it contains a file extension otherwise it
43 -- returns <Lib_Filename>.dll.
45 ---------------------------
46 -- Build_Dynamic_Library --
47 ---------------------------
49 procedure Build_Dynamic_Library
50 (Ofiles
: Argument_List
;
51 Afiles
: Argument_List
;
52 Options
: Argument_List
;
53 Bargs_Options
: Argument_List
;
54 Largs_Options
: Argument_List
;
55 Lib_Filename
: String;
56 Def_Filename
: String;
57 Lib_Address
: String := "";
58 Build_Import
: Boolean := False;
59 Relocatable
: Boolean := False;
60 Map_File
: Boolean := False)
63 use type OS_Lib
.Argument_List
;
65 Base_Filename
: constant String := MDLL
.Fil
.Ext_To
(Lib_Filename
);
67 Def_File
: aliased constant String := Def_Filename
;
68 Jnk_File
: aliased String := Base_Filename
& ".jnk";
69 Bas_File
: aliased constant String := Base_Filename
& ".base";
70 Dll_File
: aliased String := Get_Dll_Name
(Lib_Filename
);
71 Exp_File
: aliased String := Base_Filename
& ".exp";
72 Lib_File
: aliased constant String := "lib" & Base_Filename
& ".a";
74 Bas_Opt
: aliased String := "-Wl,--base-file," & Bas_File
;
75 Lib_Opt
: aliased String := "-mdll";
76 Out_Opt
: aliased String := "-o";
77 Adr_Opt
: aliased String := "-Wl,--image-base=" & Lib_Address
;
78 Map_Opt
: aliased String := "-Wl,-Map," & Lib_Filename
& ".map";
80 L_Afiles
: Argument_List
:= Afiles
;
81 -- Local afiles list. This list can be reordered to ensure that the
82 -- binder ALI file is not the first entry in this list.
84 All_Options
: constant Argument_List
:= Options
& Largs_Options
;
86 procedure Build_Reloc_DLL
;
87 -- Build a relocatable DLL with only objects file specified. This uses
88 -- the well known five step build (see GNAT User's Guide).
90 procedure Ada_Build_Reloc_DLL
;
91 -- Build a relocatable DLL with Ada code. This uses the well known five
92 -- step build (see GNAT User's Guide).
94 procedure Build_Non_Reloc_DLL
;
95 -- Build a non relocatable DLL containing no Ada code
97 procedure Ada_Build_Non_Reloc_DLL
;
98 -- Build a non relocatable DLL with Ada code
100 ---------------------
101 -- Build_Reloc_DLL --
102 ---------------------
104 procedure Build_Reloc_DLL
is
106 Objects_Exp_File
: constant OS_Lib
.Argument_List
:=
107 Exp_File
'Unchecked_Access & Ofiles
;
108 -- Objects plus the export table (.exp) file
114 Text_IO
.Put_Line
("building relocatable DLL...");
115 Text_IO
.Put
("make " & Dll_File
);
118 Text_IO
.Put_Line
(" and " & Lib_File
);
124 -- 1) Build base file with objects files
126 Utl
.Gcc
(Output_File
=> Jnk_File
,
128 Options
=> All_Options
,
129 Base_File
=> Bas_File
,
132 -- 2) Build exp from base file
134 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
135 Base_File
=> Bas_File
,
136 Exp_Table
=> Exp_File
,
137 Build_Import
=> False);
139 -- 3) Build base file with exp file and objects files
141 Utl
.Gcc
(Output_File
=> Jnk_File
,
142 Files
=> Objects_Exp_File
,
143 Options
=> All_Options
,
144 Base_File
=> Bas_File
,
147 -- 4) Build new exp from base file and the lib file (.a)
149 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
150 Base_File
=> Bas_File
,
151 Exp_Table
=> Exp_File
,
152 Build_Import
=> Build_Import
);
154 -- 5) Build the dynamic library
157 Params
: constant OS_Lib
.Argument_List
:=
158 Map_Opt
'Unchecked_Access &
159 Adr_Opt
'Unchecked_Access & All_Options
;
160 First_Param
: Positive := Params
'First + 1;
164 First_Param
:= Params
'First;
168 (Output_File
=> Dll_File
,
169 Files
=> Objects_Exp_File
,
170 Options
=> Params
(First_Param
.. Params
'Last),
174 OS_Lib
.Delete_File
(Exp_File
, Success
);
175 OS_Lib
.Delete_File
(Bas_File
, Success
);
176 OS_Lib
.Delete_File
(Jnk_File
, Success
);
180 OS_Lib
.Delete_File
(Exp_File
, Success
);
181 OS_Lib
.Delete_File
(Bas_File
, Success
);
182 OS_Lib
.Delete_File
(Jnk_File
, Success
);
186 -------------------------
187 -- Ada_Build_Reloc_DLL --
188 -------------------------
190 procedure Ada_Build_Reloc_DLL
is
195 Text_IO
.Put_Line
("Building relocatable DLL...");
196 Text_IO
.Put
("make " & Dll_File
);
199 Text_IO
.Put_Line
(" and " & Lib_File
);
205 -- 1) Build base file with objects files
207 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
210 Params
: constant OS_Lib
.Argument_List
:=
211 Out_Opt
'Unchecked_Access &
212 Jnk_File
'Unchecked_Access &
213 Lib_Opt
'Unchecked_Access &
214 Bas_Opt
'Unchecked_Access &
218 Utl
.Gnatlink
(L_Afiles
(L_Afiles
'Last).all, Params
);
221 -- 2) Build exp from base file
223 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
224 Base_File
=> Bas_File
,
225 Exp_Table
=> Exp_File
,
226 Build_Import
=> False);
228 -- 3) Build base file with exp file and objects files
230 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
233 Params
: constant OS_Lib
.Argument_List
:=
234 Out_Opt
'Unchecked_Access &
235 Jnk_File
'Unchecked_Access &
236 Lib_Opt
'Unchecked_Access &
237 Bas_Opt
'Unchecked_Access &
238 Exp_File
'Unchecked_Access &
242 Utl
.Gnatlink
(L_Afiles
(L_Afiles
'Last).all, Params
);
245 -- 4) Build new exp from base file and the lib file (.a)
247 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
248 Base_File
=> Bas_File
,
249 Exp_Table
=> Exp_File
,
250 Build_Import
=> Build_Import
);
252 -- 5) Build the dynamic library
254 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
257 Params
: constant OS_Lib
.Argument_List
:=
258 Map_Opt
'Unchecked_Access &
259 Out_Opt
'Unchecked_Access &
260 Dll_File
'Unchecked_Access &
261 Lib_Opt
'Unchecked_Access &
262 Exp_File
'Unchecked_Access &
263 Adr_Opt
'Unchecked_Access &
266 First_Param
: Positive := Params
'First + 1;
270 First_Param
:= Params
'First;
274 (L_Afiles
(L_Afiles
'Last).all,
275 Params
(First_Param
.. Params
'Last));
278 OS_Lib
.Delete_File
(Exp_File
, Success
);
279 OS_Lib
.Delete_File
(Bas_File
, Success
);
280 OS_Lib
.Delete_File
(Jnk_File
, Success
);
284 OS_Lib
.Delete_File
(Exp_File
, Success
);
285 OS_Lib
.Delete_File
(Bas_File
, Success
);
286 OS_Lib
.Delete_File
(Jnk_File
, Success
);
288 end Ada_Build_Reloc_DLL
;
290 -------------------------
291 -- Build_Non_Reloc_DLL --
292 -------------------------
294 procedure Build_Non_Reloc_DLL
is
299 Text_IO
.Put_Line
("building non relocatable DLL...");
300 Text_IO
.Put
("make " & Dll_File
&
301 " using address " & Lib_Address
);
304 Text_IO
.Put_Line
(" and " & Lib_File
);
310 -- Build exp table and the lib .a file
312 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
313 Exp_Table
=> Exp_File
,
314 Build_Import
=> Build_Import
);
319 Params
: OS_Lib
.Argument_List
:=
320 Adr_Opt
'Unchecked_Access & All_Options
;
323 Params
:= Map_Opt
'Unchecked_Access & Params
;
326 Utl
.Gcc
(Output_File
=> Dll_File
,
327 Files
=> Exp_File
'Unchecked_Access & Ofiles
,
332 OS_Lib
.Delete_File
(Exp_File
, Success
);
336 OS_Lib
.Delete_File
(Exp_File
, Success
);
338 end Build_Non_Reloc_DLL
;
340 -----------------------------
341 -- Ada_Build_Non_Reloc_DLL --
342 -----------------------------
344 -- Build a non relocatable DLL with Ada code
346 procedure Ada_Build_Non_Reloc_DLL
is
351 Text_IO
.Put_Line
("building non relocatable DLL...");
352 Text_IO
.Put
("make " & Dll_File
&
353 " using address " & Lib_Address
);
356 Text_IO
.Put_Line
(" and " & Lib_File
);
362 -- Build exp table and the lib .a file
364 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
365 Exp_Table
=> Exp_File
,
366 Build_Import
=> Build_Import
);
370 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
373 Params
: OS_Lib
.Argument_List
:=
374 Out_Opt
'Unchecked_Access &
375 Dll_File
'Unchecked_Access &
376 Lib_Opt
'Unchecked_Access &
377 Exp_File
'Unchecked_Access &
378 Adr_Opt
'Unchecked_Access &
383 Params
:= Map_Opt
'Unchecked_Access & Params
;
386 Utl
.Gnatlink
(L_Afiles
(L_Afiles
'Last).all, Params
);
389 OS_Lib
.Delete_File
(Exp_File
, Success
);
393 OS_Lib
.Delete_File
(Exp_File
, Success
);
395 end Ada_Build_Non_Reloc_DLL
;
398 -- On Windows the binder file must not be in the first position in the
399 -- list. This is due to the way DLL's are built on Windows. We swap the
400 -- first ali with the last one if it is the case.
402 if L_Afiles
'Length > 1 then
404 Filename
: constant String :=
405 Directory_Operations
.Base_Name
(L_Afiles
(1).all);
406 First
: constant Positive := Filename
'First;
409 if Filename
(First
.. First
+ 1) = "b~" then
410 L_Afiles
(L_Afiles
'Last) := Afiles
(1);
411 L_Afiles
(1) := Afiles
(Afiles
'Last);
418 if L_Afiles
'Length = 0 then
425 if L_Afiles
'Length = 0 then
428 Ada_Build_Non_Reloc_DLL
;
431 end Build_Dynamic_Library
;
433 --------------------------
434 -- Build_Import_Library --
435 --------------------------
437 procedure Build_Import_Library
438 (Lib_Filename
: String;
439 Def_Filename
: String)
442 procedure Build_Import_Library
(Lib_Filename
: String);
443 -- Build an import library. This is to build only a .a library to link
446 --------------------------
447 -- Build_Import_Library --
448 --------------------------
450 procedure Build_Import_Library
(Lib_Filename
: String) is
451 Def_File
: String renames Def_Filename
;
452 Dll_File
: constant String := Get_Dll_Name
(Lib_Filename
);
453 Base_Filename
: constant String := MDLL
.Fil
.Ext_To
(Lib_Filename
);
454 Lib_File
: constant String := "lib" & Base_Filename
& ".a";
458 Text_IO
.Put_Line
("Building import library...");
460 ("make " & Lib_File
& " to use dynamic library " & Dll_File
);
464 (Def_File
, Dll_File
, Lib_File
, Build_Import
=> True);
465 end Build_Import_Library
;
467 -- Start of processing for Build_Import_Library
470 -- If the library has the form lib<name>.a then the def file should be
471 -- <name>.def and the DLL to link against <name>.dll. This is a Windows
472 -- convention and we try as much as possible to follow the platform
475 if Lib_Filename
'Length > 3 and then Lib_Filename
(1 .. 3) = "lib" then
476 Build_Import_Library
(Lib_Filename
(4 .. Lib_Filename
'Last));
478 Build_Import_Library
(Lib_Filename
);
480 end Build_Import_Library
;
486 function Get_Dll_Name
(Lib_Filename
: String) return String is
488 if MDLL
.Fil
.Get_Ext
(Lib_Filename
) = "" then
489 return Lib_Filename
& ".dll";