1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2003 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, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, 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 ---------------------------
42 -- Build_Dynamic_Library --
43 ---------------------------
45 procedure Build_Dynamic_Library
46 (Ofiles : Argument_List;
47 Afiles : Argument_List;
48 Options : Argument_List;
49 Bargs_Options : Argument_List;
50 Largs_Options : Argument_List;
51 Lib_Filename : String;
52 Def_Filename : String;
53 Lib_Address : String := "";
54 Build_Import : Boolean := False;
55 Relocatable : Boolean := False)
58 use type OS_Lib.Argument_List;
60 Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
62 Def_File : aliased constant String := Def_Filename;
63 Jnk_File : aliased String := Base_Filename & ".jnk";
64 Bas_File : aliased constant String := Base_Filename & ".base";
65 Dll_File : aliased String := Base_Filename & ".dll";
66 Exp_File : aliased String := Base_Filename & ".exp";
67 Lib_File : aliased constant String := "lib" & Base_Filename & ".a";
69 Bas_Opt : aliased String := "-Wl,--base-file," & Bas_File;
70 Lib_Opt : aliased String := "-mdll";
71 Out_Opt : aliased String := "-o";
72 Adr_Opt : aliased String := "-Wl,--image-base=" & Lib_Address;
74 L_Afiles : Argument_List := Afiles;
75 -- Local afiles list. This list can be reordered to ensure that the
76 -- binder ali file is not the first entry in this list.
78 All_Options : constant Argument_List := Options & Largs_Options;
80 procedure Build_Reloc_DLL;
81 -- Build a relocatable DLL with only objects file specified.
82 -- this use the well known 5 steps build. (see GNAT User's Guide).
84 procedure Ada_Build_Reloc_DLL;
85 -- Build a relocatable DLL with Ada code.
86 -- this use the well known 5 steps build. (see GNAT User's Guide).
88 procedure Build_Non_Reloc_DLL;
89 -- Build a non relocatable DLL containing no Ada code.
91 procedure Ada_Build_Non_Reloc_DLL;
92 -- Build a non relocatable DLL with Ada code.
98 procedure Build_Reloc_DLL is
99 -- Objects plus the export table (.exp) file
101 Objects_Exp_File : constant OS_Lib.Argument_List
102 := Exp_File'Unchecked_Access & Ofiles;
108 Text_IO.Put_Line ("building relocatable DLL...");
109 Text_IO.Put ("make " & Dll_File);
112 Text_IO.Put_Line (" and " & Lib_File);
118 -- 1) Build base file with objects files.
120 Utl.Gcc (Output_File => Jnk_File,
122 Options => All_Options,
123 Base_File => Bas_File,
126 -- 2) Build exp from base file.
128 Utl.Dlltool (Def_File, Dll_File, Lib_File,
129 Base_File => Bas_File,
130 Exp_Table => Exp_File,
131 Build_Import => False);
133 -- 3) Build base file with exp file and objects files.
135 Utl.Gcc (Output_File => Jnk_File,
136 Files => Objects_Exp_File,
137 Options => All_Options,
138 Base_File => Bas_File,
141 -- 4) Build new exp from base file and the lib file (.a)
143 Utl.Dlltool (Def_File, Dll_File, Lib_File,
144 Base_File => Bas_File,
145 Exp_Table => Exp_File,
146 Build_Import => Build_Import);
148 -- 5) Build the dynamic library
150 Utl.Gcc (Output_File => Dll_File,
151 Files => Objects_Exp_File,
152 Options => Adr_Opt'Unchecked_Access & All_Options,
155 OS_Lib.Delete_File (Exp_File, Success);
156 OS_Lib.Delete_File (Bas_File, Success);
157 OS_Lib.Delete_File (Jnk_File, Success);
161 OS_Lib.Delete_File (Exp_File, Success);
162 OS_Lib.Delete_File (Bas_File, Success);
163 OS_Lib.Delete_File (Jnk_File, Success);
167 -------------------------
168 -- Ada_Build_Reloc_DLL --
169 -------------------------
171 procedure Ada_Build_Reloc_DLL is
175 Text_IO.Put_Line ("Building relocatable DLL...");
176 Text_IO.Put ("make " & Dll_File);
179 Text_IO.Put_Line (" and " & Lib_File);
185 -- 1) Build base file with objects files.
187 Utl.Gnatbind (L_Afiles, Options & Bargs_Options);
190 Params : constant OS_Lib.Argument_List :=
191 Out_Opt'Unchecked_Access &
192 Jnk_File'Unchecked_Access &
193 Lib_Opt'Unchecked_Access &
194 Bas_Opt'Unchecked_Access &
198 Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
201 -- 2) Build exp from base file.
203 Utl.Dlltool (Def_File, Dll_File, Lib_File,
204 Base_File => Bas_File,
205 Exp_Table => Exp_File,
206 Build_Import => False);
208 -- 3) Build base file with exp file and 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 &
218 Exp_File'Unchecked_Access &
222 Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
225 -- 4) Build new exp from base file and the lib file (.a)
227 Utl.Dlltool (Def_File, Dll_File, Lib_File,
228 Base_File => Bas_File,
229 Exp_Table => Exp_File,
230 Build_Import => Build_Import);
232 -- 5) Build the dynamic library
234 Utl.Gnatbind (L_Afiles, Options & Bargs_Options);
237 Params : constant OS_Lib.Argument_List :=
238 Out_Opt'Unchecked_Access &
239 Dll_File'Unchecked_Access &
240 Lib_Opt'Unchecked_Access &
241 Exp_File'Unchecked_Access &
242 Adr_Opt'Unchecked_Access &
246 Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
249 OS_Lib.Delete_File (Exp_File, Success);
250 OS_Lib.Delete_File (Bas_File, Success);
251 OS_Lib.Delete_File (Jnk_File, Success);
255 OS_Lib.Delete_File (Exp_File, Success);
256 OS_Lib.Delete_File (Bas_File, Success);
257 OS_Lib.Delete_File (Jnk_File, Success);
259 end Ada_Build_Reloc_DLL;
261 -------------------------
262 -- Build_Non_Reloc_DLL --
263 -------------------------
265 procedure Build_Non_Reloc_DLL is
269 Text_IO.Put_Line ("building non relocatable DLL...");
270 Text_IO.Put ("make " & Dll_File &
271 " using address " & Lib_Address);
274 Text_IO.Put_Line (" and " & Lib_File);
280 -- Build exp table and the lib .a file.
282 Utl.Dlltool (Def_File, Dll_File, Lib_File,
283 Exp_Table => Exp_File,
284 Build_Import => Build_Import);
288 Utl.Gcc (Output_File => Dll_File,
289 Files => Exp_File'Unchecked_Access & Ofiles,
290 Options => Adr_Opt'Unchecked_Access & All_Options,
293 OS_Lib.Delete_File (Exp_File, Success);
297 OS_Lib.Delete_File (Exp_File, Success);
299 end Build_Non_Reloc_DLL;
301 -----------------------------
302 -- Ada_Build_Non_Reloc_DLL --
303 -----------------------------
305 -- Build a non relocatable DLL with Ada code.
307 procedure Ada_Build_Non_Reloc_DLL is
311 Text_IO.Put_Line ("building non relocatable DLL...");
312 Text_IO.Put ("make " & Dll_File &
313 " using address " & Lib_Address);
316 Text_IO.Put_Line (" and " & Lib_File);
322 -- Build exp table and the lib .a file.
324 Utl.Dlltool (Def_File, Dll_File, Lib_File,
325 Exp_Table => Exp_File,
326 Build_Import => Build_Import);
330 Utl.Gnatbind (L_Afiles, Options & Bargs_Options);
333 Params : constant OS_Lib.Argument_List :=
334 Out_Opt'Unchecked_Access &
335 Dll_File'Unchecked_Access &
336 Lib_Opt'Unchecked_Access &
337 Exp_File'Unchecked_Access &
338 Adr_Opt'Unchecked_Access &
342 Utl.Gnatlink (L_Afiles (L_Afiles'Last).all, Params);
345 OS_Lib.Delete_File (Exp_File, Success);
349 OS_Lib.Delete_File (Exp_File, Success);
351 end Ada_Build_Non_Reloc_DLL;
354 -- On Windows the binder file must not be in the first position
355 -- in the list. This is due to the way DLL's are built on Windows.
356 -- We swap the first ali with the last one if it is the case.
358 if L_Afiles'Length > 1 then
360 Filename : constant String :=
361 Directory_Operations.Base_Name (L_Afiles (1).all);
362 First : constant Positive := Filename'First;
365 if Filename (First .. First + 1) = "b~" then
366 L_Afiles (L_Afiles'Last) := Afiles (1);
367 L_Afiles (1) := Afiles (Afiles'Last);
375 if L_Afiles'Length = 0 then
382 if L_Afiles'Length = 0 then
385 Ada_Build_Non_Reloc_DLL;
389 end Build_Dynamic_Library;
391 --------------------------
392 -- Build_Import_Library --
393 --------------------------
395 procedure Build_Import_Library
396 (Lib_Filename : String;
397 Def_Filename : String)
400 procedure Build_Import_Library (Def_Base_Filename : String);
401 -- Build an import library.
402 -- this is to build only a .a library to link against a DLL.
404 Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
406 --------------------------
407 -- Build_Import_Library --
408 --------------------------
410 procedure Build_Import_Library (Def_Base_Filename : String) is
412 Def_File : String renames Def_Filename;
413 Dll_File : constant String := Def_Base_Filename & ".dll";
414 Lib_File : constant String := "lib" & Base_Filename & ".a";
419 Text_IO.Put_Line ("Building import library...");
420 Text_IO.Put_Line ("make " & Lib_File &
421 " to use dynamic library " & Dll_File);
424 Utl.Dlltool (Def_File, Dll_File, Lib_File,
425 Build_Import => True);
426 end Build_Import_Library;
429 -- If the library has the form lib<name>.a then the def file should
430 -- be <name>.def and the DLL to link against <name>.dll
431 -- this is a Windows convention and we try as much as possible to
432 -- follow the platform convention.
434 if Lib_Filename'Length > 3 and then Lib_Filename (1 .. 3) = "lib" then
435 Build_Import_Library (Base_Filename (4 .. Base_Filename'Last));
437 Build_Import_Library (Base_Filename);
439 end Build_Import_Library;