1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2007, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 -- This package provides the core high level routines used by GNATDLL
27 -- to build Windows DLL.
31 with GNAT
.Directory_Operations
;
40 -- Convention used for the library names on Windows:
42 -- Import library: lib<name>.dll
44 function Get_Dll_Name
(Lib_Filename
: String) return String;
45 -- Returns <Lib_Filename> if it contains a file extension otherwise it
46 -- returns <Lib_Filename>.dll.
48 ---------------------------
49 -- Build_Dynamic_Library --
50 ---------------------------
52 procedure Build_Dynamic_Library
53 (Ofiles
: Argument_List
;
54 Afiles
: Argument_List
;
55 Options
: Argument_List
;
56 Bargs_Options
: Argument_List
;
57 Largs_Options
: Argument_List
;
58 Lib_Filename
: String;
59 Def_Filename
: String;
60 Lib_Address
: String := "";
61 Build_Import
: Boolean := False;
62 Relocatable
: Boolean := False;
63 Map_File
: Boolean := False)
66 use type OS_Lib
.Argument_List
;
68 Base_Filename
: constant String := MDLL
.Fil
.Ext_To
(Lib_Filename
);
70 Def_File
: aliased constant String := Def_Filename
;
71 Jnk_File
: aliased String := Base_Filename
& ".jnk";
72 Bas_File
: aliased constant String := Base_Filename
& ".base";
73 Dll_File
: aliased String := Get_Dll_Name
(Lib_Filename
);
74 Exp_File
: aliased String := Base_Filename
& ".exp";
75 Lib_File
: aliased constant String := "lib" & Base_Filename
& ".dll.a";
77 Bas_Opt
: aliased String := "-Wl,--base-file," & Bas_File
;
78 Lib_Opt
: aliased String := "-mdll";
79 Out_Opt
: aliased String := "-o";
80 Adr_Opt
: aliased String := "-Wl,--image-base=" & Lib_Address
;
81 Map_Opt
: aliased String := "-Wl,-Map," & Lib_Filename
& ".map";
83 L_Afiles
: Argument_List
:= Afiles
;
84 -- Local afiles list. This list can be reordered to ensure that the
85 -- binder ALI file is not the first entry in this list.
87 All_Options
: constant Argument_List
:= Options
& Largs_Options
;
89 procedure Build_Reloc_DLL
;
90 -- Build a relocatable DLL with only objects file specified. This uses
91 -- the well known five step build (see GNAT User's Guide).
93 procedure Ada_Build_Reloc_DLL
;
94 -- Build a relocatable DLL with Ada code. This uses the well known five
95 -- step build (see GNAT User's Guide).
97 procedure Build_Non_Reloc_DLL
;
98 -- Build a non relocatable DLL containing no Ada code
100 procedure Ada_Build_Non_Reloc_DLL
;
101 -- Build a non relocatable DLL with Ada code
103 ---------------------
104 -- Build_Reloc_DLL --
105 ---------------------
107 procedure Build_Reloc_DLL
is
109 Objects_Exp_File
: constant OS_Lib
.Argument_List
:=
110 Exp_File
'Unchecked_Access & Ofiles
;
111 -- Objects plus the export table (.exp) file
117 Text_IO
.Put_Line
("building relocatable DLL...");
118 Text_IO
.Put
("make " & Dll_File
);
121 Text_IO
.Put_Line
(" and " & Lib_File
);
127 -- 1) Build base file with objects files
129 Utl
.Gcc
(Output_File
=> Jnk_File
,
131 Options
=> All_Options
,
132 Base_File
=> Bas_File
,
135 -- 2) Build exp from base file
137 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
138 Base_File
=> Bas_File
,
139 Exp_Table
=> Exp_File
,
140 Build_Import
=> False);
142 -- 3) Build base file with exp file and objects files
144 Utl
.Gcc
(Output_File
=> Jnk_File
,
145 Files
=> Objects_Exp_File
,
146 Options
=> All_Options
,
147 Base_File
=> Bas_File
,
150 -- 4) Build new exp from base file and the lib file (.a)
152 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
153 Base_File
=> Bas_File
,
154 Exp_Table
=> Exp_File
,
155 Build_Import
=> Build_Import
);
157 -- 5) Build the dynamic library
160 Params
: constant OS_Lib
.Argument_List
:=
161 Map_Opt
'Unchecked_Access &
162 Adr_Opt
'Unchecked_Access & All_Options
;
163 First_Param
: Positive := Params
'First + 1;
167 First_Param
:= Params
'First;
171 (Output_File
=> Dll_File
,
172 Files
=> Objects_Exp_File
,
173 Options
=> Params
(First_Param
.. Params
'Last),
177 OS_Lib
.Delete_File
(Exp_File
, Success
);
178 OS_Lib
.Delete_File
(Bas_File
, Success
);
179 OS_Lib
.Delete_File
(Jnk_File
, Success
);
183 OS_Lib
.Delete_File
(Exp_File
, Success
);
184 OS_Lib
.Delete_File
(Bas_File
, Success
);
185 OS_Lib
.Delete_File
(Jnk_File
, Success
);
189 -------------------------
190 -- Ada_Build_Reloc_DLL --
191 -------------------------
193 procedure Ada_Build_Reloc_DLL
is
198 Text_IO
.Put_Line
("Building relocatable DLL...");
199 Text_IO
.Put
("make " & Dll_File
);
202 Text_IO
.Put_Line
(" and " & Lib_File
);
208 -- 1) Build base file with objects files
210 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
213 Params
: constant OS_Lib
.Argument_List
:=
214 Out_Opt
'Unchecked_Access &
215 Jnk_File
'Unchecked_Access &
216 Lib_Opt
'Unchecked_Access &
217 Bas_Opt
'Unchecked_Access &
221 Utl
.Gnatlink
(L_Afiles
(L_Afiles
'Last).all, Params
);
224 -- 2) Build exp from base file
226 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
227 Base_File
=> Bas_File
,
228 Exp_Table
=> Exp_File
,
229 Build_Import
=> False);
231 -- 3) Build base file with exp file and objects files
233 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
236 Params
: constant OS_Lib
.Argument_List
:=
237 Out_Opt
'Unchecked_Access &
238 Jnk_File
'Unchecked_Access &
239 Lib_Opt
'Unchecked_Access &
240 Bas_Opt
'Unchecked_Access &
241 Exp_File
'Unchecked_Access &
245 Utl
.Gnatlink
(L_Afiles
(L_Afiles
'Last).all, Params
);
248 -- 4) Build new exp from base file and the lib file (.a)
250 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
251 Base_File
=> Bas_File
,
252 Exp_Table
=> Exp_File
,
253 Build_Import
=> Build_Import
);
255 -- 5) Build the dynamic library
257 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
260 Params
: constant OS_Lib
.Argument_List
:=
261 Map_Opt
'Unchecked_Access &
262 Out_Opt
'Unchecked_Access &
263 Dll_File
'Unchecked_Access &
264 Lib_Opt
'Unchecked_Access &
265 Exp_File
'Unchecked_Access &
266 Adr_Opt
'Unchecked_Access &
269 First_Param
: Positive := Params
'First + 1;
273 First_Param
:= Params
'First;
277 (L_Afiles
(L_Afiles
'Last).all,
278 Params
(First_Param
.. Params
'Last));
281 OS_Lib
.Delete_File
(Exp_File
, Success
);
282 OS_Lib
.Delete_File
(Bas_File
, Success
);
283 OS_Lib
.Delete_File
(Jnk_File
, Success
);
287 OS_Lib
.Delete_File
(Exp_File
, Success
);
288 OS_Lib
.Delete_File
(Bas_File
, Success
);
289 OS_Lib
.Delete_File
(Jnk_File
, Success
);
291 end Ada_Build_Reloc_DLL
;
293 -------------------------
294 -- Build_Non_Reloc_DLL --
295 -------------------------
297 procedure Build_Non_Reloc_DLL
is
302 Text_IO
.Put_Line
("building non relocatable DLL...");
303 Text_IO
.Put
("make " & Dll_File
&
304 " using address " & Lib_Address
);
307 Text_IO
.Put_Line
(" and " & Lib_File
);
313 -- Build exp table and the lib .a file
315 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
316 Exp_Table
=> Exp_File
,
317 Build_Import
=> Build_Import
);
322 Params
: OS_Lib
.Argument_List
:=
323 Adr_Opt
'Unchecked_Access & All_Options
;
326 Params
:= Map_Opt
'Unchecked_Access & Params
;
329 Utl
.Gcc
(Output_File
=> Dll_File
,
330 Files
=> Exp_File
'Unchecked_Access & Ofiles
,
335 OS_Lib
.Delete_File
(Exp_File
, Success
);
339 OS_Lib
.Delete_File
(Exp_File
, Success
);
341 end Build_Non_Reloc_DLL
;
343 -----------------------------
344 -- Ada_Build_Non_Reloc_DLL --
345 -----------------------------
347 -- Build a non relocatable DLL with Ada code
349 procedure Ada_Build_Non_Reloc_DLL
is
354 Text_IO
.Put_Line
("building non relocatable DLL...");
355 Text_IO
.Put
("make " & Dll_File
&
356 " using address " & Lib_Address
);
359 Text_IO
.Put_Line
(" and " & Lib_File
);
365 -- Build exp table and the lib .a file
367 Utl
.Dlltool
(Def_File
, Dll_File
, Lib_File
,
368 Exp_Table
=> Exp_File
,
369 Build_Import
=> Build_Import
);
373 Utl
.Gnatbind
(L_Afiles
, Options
& Bargs_Options
);
376 Params
: OS_Lib
.Argument_List
:=
377 Out_Opt
'Unchecked_Access &
378 Dll_File
'Unchecked_Access &
379 Lib_Opt
'Unchecked_Access &
380 Exp_File
'Unchecked_Access &
381 Adr_Opt
'Unchecked_Access &
386 Params
:= Map_Opt
'Unchecked_Access & Params
;
389 Utl
.Gnatlink
(L_Afiles
(L_Afiles
'Last).all, Params
);
392 OS_Lib
.Delete_File
(Exp_File
, Success
);
396 OS_Lib
.Delete_File
(Exp_File
, Success
);
398 end Ada_Build_Non_Reloc_DLL
;
400 -- Start of processing for Build_Dynamic_Library
403 -- On Windows the binder file must not be in the first position in the
404 -- list. This is due to the way DLL's are built on Windows. We swap the
405 -- first ali with the last one if it is the case.
407 if L_Afiles
'Length > 1 then
409 Filename
: constant String :=
410 Directory_Operations
.Base_Name
411 (L_Afiles
(L_Afiles
'First).all);
412 First
: constant Positive := Filename
'First;
415 if Filename
(First
.. First
+ 1) = "b~" then
416 L_Afiles
(L_Afiles
'Last) := Afiles
(Afiles
'First);
417 L_Afiles
(L_Afiles
'First) := Afiles
(Afiles
'Last);
424 if L_Afiles
'Length = 0 then
431 if L_Afiles
'Length = 0 then
434 Ada_Build_Non_Reloc_DLL
;
437 end Build_Dynamic_Library
;
439 --------------------------
440 -- Build_Import_Library --
441 --------------------------
443 procedure Build_Import_Library
444 (Lib_Filename
: String;
445 Def_Filename
: String)
447 procedure Build_Import_Library
(Lib_Filename
: String);
448 -- Build an import library. This is to build only a .a library to link
451 --------------------------
452 -- Build_Import_Library --
453 --------------------------
455 procedure Build_Import_Library
(Lib_Filename
: String) is
457 function No_Lib_Prefix
(Filename
: String) return String;
458 -- Return Filename without the lib prefix if present
464 function No_Lib_Prefix
(Filename
: String) return String is
466 if Filename
(Filename
'First .. Filename
'First + 2) = "lib" then
467 return Filename
(Filename
'First + 3 .. Filename
'Last);
475 Def_File
: String renames Def_Filename
;
476 Dll_File
: constant String := Get_Dll_Name
(Lib_Filename
);
477 Base_Filename
: constant String :=
478 MDLL
.Fil
.Ext_To
(No_Lib_Prefix
(Lib_Filename
));
479 Lib_File
: constant String := "lib" & Base_Filename
& ".dll.a";
481 -- Start of processing for Build_Import_Library
485 Text_IO
.Put_Line
("Building import library...");
487 ("make " & Lib_File
& " to use dynamic library " & Dll_File
);
491 (Def_File
, Dll_File
, Lib_File
, Build_Import
=> True);
492 end Build_Import_Library
;
494 -- Start of processing for Build_Import_Library
497 Build_Import_Library
(Lib_Filename
);
498 end Build_Import_Library
;
504 function Get_Dll_Name
(Lib_Filename
: String) return String is
506 if MDLL
.Fil
.Get_Ext
(Lib_Filename
) = "" then
507 return Lib_Filename
& ".dll";