2003-05-31 Bud Davis <bdavis9659@comcast.net>
[official-gcc.git] / gcc / ada / mdll.adb
blobb542eeef2a94181f35546d69c162d2e4f5ec9725
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- M D L L --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
10 -- --
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. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 -- This package provides the core high level routines used by GNATDLL
28 -- to build Windows DLL
30 with Ada.Text_IO;
32 with MDLL.Utl;
33 with MDLL.Fil;
35 package body MDLL is
37 use Ada;
38 use GNAT;
40 ---------------------------
41 -- Build_Dynamic_Library --
42 ---------------------------
44 procedure Build_Dynamic_Library
45 (Ofiles : Argument_List;
46 Afiles : Argument_List;
47 Options : Argument_List;
48 Bargs_Options : Argument_List;
49 Largs_Options : Argument_List;
50 Lib_Filename : String;
51 Def_Filename : String;
52 Lib_Address : String := "";
53 Build_Import : Boolean := False;
54 Relocatable : Boolean := False)
57 use type OS_Lib.Argument_List;
59 Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
61 Def_File : aliased String := Def_Filename;
62 Jnk_File : aliased String := Base_Filename & ".jnk";
63 Bas_File : aliased String := Base_Filename & ".base";
64 Dll_File : aliased String := Base_Filename & ".dll";
65 Exp_File : aliased String := Base_Filename & ".exp";
66 Lib_File : aliased String := "lib" & Base_Filename & ".a";
68 Bas_Opt : aliased String := "-Wl,--base-file," & Bas_File;
69 Lib_Opt : aliased String := "-mdll";
70 Out_Opt : aliased String := "-o";
71 Adr_Opt : aliased String := "-Wl,--image-base=" & Lib_Address;
73 All_Options : constant Argument_List := Options & Largs_Options;
75 procedure Build_Reloc_DLL;
76 -- Build a relocatable DLL with only objects file specified.
77 -- this use the well known 5 steps build. (see GNAT User's Guide).
79 procedure Ada_Build_Reloc_DLL;
80 -- Build a relocatable DLL with Ada code.
81 -- this use the well known 5 steps build. (see GNAT User's Guide).
83 procedure Build_Non_Reloc_DLL;
84 -- Build a non relocatable DLL containing no Ada code.
86 procedure Ada_Build_Non_Reloc_DLL;
87 -- Build a non relocatable DLL with Ada code.
89 ---------------------
90 -- Build_Reloc_DLL --
91 ---------------------
93 procedure Build_Reloc_DLL is
94 -- Objects plus the export table (.exp) file
96 Objects_Exp_File : constant OS_Lib.Argument_List
97 := Exp_File'Unchecked_Access & Ofiles;
99 Success : Boolean;
101 begin
102 if not Quiet then
103 Text_IO.Put_Line ("building relocatable DLL...");
104 Text_IO.Put ("make " & Dll_File);
106 if Build_Import then
107 Text_IO.Put_Line (" and " & Lib_File);
108 else
109 Text_IO.New_Line;
110 end if;
111 end if;
113 -- 1) Build base file with objects files.
115 Utl.Gcc (Output_File => Jnk_File,
116 Files => Ofiles,
117 Options => All_Options,
118 Base_File => Bas_File,
119 Build_Lib => True);
121 -- 2) Build exp from base file.
123 Utl.Dlltool (Def_File, Dll_File, Lib_File,
124 Base_File => Bas_File,
125 Exp_Table => Exp_File,
126 Build_Import => False);
128 -- 3) Build base file with exp file and objects files.
130 Utl.Gcc (Output_File => Jnk_File,
131 Files => Objects_Exp_File,
132 Options => All_Options,
133 Base_File => Bas_File,
134 Build_Lib => True);
136 -- 4) Build new exp from base file and the lib file (.a)
138 Utl.Dlltool (Def_File, Dll_File, Lib_File,
139 Base_File => Bas_File,
140 Exp_Table => Exp_File,
141 Build_Import => Build_Import);
143 -- 5) Build the dynamic library
145 Utl.Gcc (Output_File => Dll_File,
146 Files => Objects_Exp_File,
147 Options => Adr_Opt'Unchecked_Access & All_Options,
148 Build_Lib => True);
150 OS_Lib.Delete_File (Exp_File, Success);
151 OS_Lib.Delete_File (Bas_File, Success);
152 OS_Lib.Delete_File (Jnk_File, Success);
154 exception
155 when others =>
156 OS_Lib.Delete_File (Exp_File, Success);
157 OS_Lib.Delete_File (Bas_File, Success);
158 OS_Lib.Delete_File (Jnk_File, Success);
159 raise;
160 end Build_Reloc_DLL;
162 -------------------------
163 -- Ada_Build_Reloc_DLL --
164 -------------------------
166 procedure Ada_Build_Reloc_DLL is
167 Success : Boolean;
168 begin
169 if not Quiet then
170 Text_IO.Put_Line ("Building relocatable DLL...");
171 Text_IO.Put ("make " & Dll_File);
173 if Build_Import then
174 Text_IO.Put_Line (" and " & Lib_File);
175 else
176 Text_IO.New_Line;
177 end if;
178 end if;
180 -- 1) Build base file with objects files.
182 Utl.Gnatbind (Afiles, Options & Bargs_Options);
184 declare
185 Params : OS_Lib.Argument_List :=
186 Out_Opt'Unchecked_Access & Jnk_File'Unchecked_Access &
187 Lib_Opt'Unchecked_Access &
188 Bas_Opt'Unchecked_Access & Ofiles & All_Options;
189 begin
190 Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
191 end;
193 -- 2) Build exp from base file.
195 Utl.Dlltool (Def_File, Dll_File, Lib_File,
196 Base_File => Bas_File,
197 Exp_Table => Exp_File,
198 Build_Import => False);
200 -- 3) Build base file with exp file and objects files.
202 Utl.Gnatbind (Afiles, Options & Bargs_Options);
204 declare
205 Params : OS_Lib.Argument_List :=
206 Out_Opt'Unchecked_Access & Jnk_File'Unchecked_Access &
207 Lib_Opt'Unchecked_Access &
208 Bas_Opt'Unchecked_Access &
209 Exp_File'Unchecked_Access &
210 Ofiles &
211 All_Options;
212 begin
213 Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
214 end;
216 -- 4) Build new exp from base file and the lib file (.a)
218 Utl.Dlltool (Def_File, Dll_File, Lib_File,
219 Base_File => Bas_File,
220 Exp_Table => Exp_File,
221 Build_Import => Build_Import);
223 -- 5) Build the dynamic library
225 Utl.Gnatbind (Afiles, Options & Bargs_Options);
227 declare
228 Params : OS_Lib.Argument_List :=
229 Out_Opt'Unchecked_Access & Dll_File'Unchecked_Access &
230 Lib_Opt'Unchecked_Access &
231 Exp_File'Unchecked_Access &
232 Adr_Opt'Unchecked_Access &
233 Ofiles &
234 All_Options;
235 begin
236 Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
237 end;
239 OS_Lib.Delete_File (Exp_File, Success);
240 OS_Lib.Delete_File (Bas_File, Success);
241 OS_Lib.Delete_File (Jnk_File, Success);
243 exception
244 when others =>
245 OS_Lib.Delete_File (Exp_File, Success);
246 OS_Lib.Delete_File (Bas_File, Success);
247 OS_Lib.Delete_File (Jnk_File, Success);
248 raise;
249 end Ada_Build_Reloc_DLL;
251 -------------------------
252 -- Build_Non_Reloc_DLL --
253 -------------------------
255 procedure Build_Non_Reloc_DLL is
256 Success : Boolean;
257 begin
258 if not Quiet then
259 Text_IO.Put_Line ("building non relocatable DLL...");
260 Text_IO.Put ("make " & Dll_File &
261 " using address " & Lib_Address);
263 if Build_Import then
264 Text_IO.Put_Line (" and " & Lib_File);
265 else
266 Text_IO.New_Line;
267 end if;
268 end if;
270 -- Build exp table and the lib .a file.
272 Utl.Dlltool (Def_File, Dll_File, Lib_File,
273 Exp_Table => Exp_File,
274 Build_Import => Build_Import);
276 -- Build the DLL
278 Utl.Gcc (Output_File => Dll_File,
279 Files => Exp_File'Unchecked_Access & Ofiles,
280 Options => Adr_Opt'Unchecked_Access & All_Options,
281 Build_Lib => True);
283 OS_Lib.Delete_File (Exp_File, Success);
285 exception
286 when others =>
287 OS_Lib.Delete_File (Exp_File, Success);
288 raise;
289 end Build_Non_Reloc_DLL;
291 -----------------------------
292 -- Ada_Build_Non_Reloc_DLL --
293 -----------------------------
295 -- Build a non relocatable DLL with Ada code.
297 procedure Ada_Build_Non_Reloc_DLL is
298 Success : Boolean;
299 begin
300 if not Quiet then
301 Text_IO.Put_Line ("building non relocatable DLL...");
302 Text_IO.Put ("make " & Dll_File &
303 " using address " & Lib_Address);
305 if Build_Import then
306 Text_IO.Put_Line (" and " & Lib_File);
307 else
308 Text_IO.New_Line;
309 end if;
310 end if;
312 -- Build exp table and the lib .a file.
314 Utl.Dlltool (Def_File, Dll_File, Lib_File,
315 Exp_Table => Exp_File,
316 Build_Import => Build_Import);
318 -- Build the DLL
320 Utl.Gnatbind (Afiles, Options & Bargs_Options);
322 declare
323 Params : OS_Lib.Argument_List :=
324 Out_Opt'Unchecked_Access & Dll_File'Unchecked_Access &
325 Lib_Opt'Unchecked_Access &
326 Exp_File'Unchecked_Access &
327 Adr_Opt'Unchecked_Access &
328 Ofiles &
329 All_Options;
330 begin
331 Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
332 end;
334 OS_Lib.Delete_File (Exp_File, Success);
336 exception
337 when others =>
338 OS_Lib.Delete_File (Exp_File, Success);
339 raise;
340 end Ada_Build_Non_Reloc_DLL;
342 begin
343 case Relocatable is
345 when True =>
346 if Afiles'Length = 0 then
347 Build_Reloc_DLL;
348 else
349 Ada_Build_Reloc_DLL;
350 end if;
352 when False =>
353 if Afiles'Length = 0 then
354 Build_Non_Reloc_DLL;
355 else
356 Ada_Build_Non_Reloc_DLL;
357 end if;
359 end case;
360 end Build_Dynamic_Library;
362 --------------------------
363 -- Build_Import_Library --
364 --------------------------
366 procedure Build_Import_Library
367 (Lib_Filename : String;
368 Def_Filename : String)
371 procedure Build_Import_Library (Def_Base_Filename : String);
372 -- Build an import library.
373 -- this is to build only a .a library to link against a DLL.
375 Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
377 --------------------------
378 -- Build_Import_Library --
379 --------------------------
381 procedure Build_Import_Library (Def_Base_Filename : String) is
383 Def_File : String renames Def_Filename;
384 Dll_File : constant String := Def_Base_Filename & ".dll";
385 Lib_File : constant String := "lib" & Base_Filename & ".a";
387 begin
389 if not Quiet then
390 Text_IO.Put_Line ("Building import library...");
391 Text_IO.Put_Line ("make " & Lib_File &
392 " to use dynamic library " & Dll_File);
393 end if;
395 Utl.Dlltool (Def_File, Dll_File, Lib_File,
396 Build_Import => True);
397 end Build_Import_Library;
399 begin
400 -- If the library has the form lib<name>.a then the def file should
401 -- be <name>.def and the DLL to link against <name>.dll
402 -- this is a Windows convention and we try as much as possible to
403 -- follow the platform convention.
405 if Lib_Filename'Length > 3 and then Lib_Filename (1 .. 3) = "lib" then
406 Build_Import_Library (Base_Filename (4 .. Base_Filename'Last));
407 else
408 Build_Import_Library (Base_Filename);
409 end if;
410 end Build_Import_Library;
412 end MDLL;