OSDN Git Service

* 1aexcept.adb, 1aexcept.ads, 1ic.ads, 1ssecsta.adb,
[pf3gnuchains/gcc-fork.git] / gcc / ada / mdll.adb
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 ------------------------------------------------------------------------------
26
27 --  This package provides the core high level routines used by GNATDLL
28 --  to build Windows DLL
29
30 with Ada.Text_IO;
31
32 with MDLL.Utl;
33 with MDLL.Fil;
34
35 package body MDLL is
36
37    use Ada;
38    use GNAT;
39
40    ---------------------------
41    -- Build_Dynamic_Library --
42    ---------------------------
43
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)
55    is
56
57       use type OS_Lib.Argument_List;
58
59       Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
60
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";
67
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;
72
73       All_Options : constant Argument_List := Options & Largs_Options;
74
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).
78
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).
82
83       procedure Build_Non_Reloc_DLL;
84       --  Build a non relocatable DLL containing no Ada code.
85
86       procedure Ada_Build_Non_Reloc_DLL;
87       --  Build a non relocatable DLL with Ada code.
88
89       ---------------------
90       -- Build_Reloc_DLL --
91       ---------------------
92
93       procedure Build_Reloc_DLL is
94          --  Objects plus the export table (.exp) file
95
96          Objects_Exp_File : constant OS_Lib.Argument_List
97            := Exp_File'Unchecked_Access & Ofiles;
98
99          Success : Boolean;
100
101       begin
102          if not Quiet then
103             Text_IO.Put_Line ("building relocatable DLL...");
104             Text_IO.Put ("make " & Dll_File);
105
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;
112
113          --  1) Build base file with objects files.
114
115          Utl.Gcc (Output_File => Jnk_File,
116                   Files       => Ofiles,
117                   Options     => All_Options,
118                   Base_File   => Bas_File,
119                   Build_Lib   => True);
120
121          --  2) Build exp from base file.
122
123          Utl.Dlltool (Def_File, Dll_File, Lib_File,
124                       Base_File    => Bas_File,
125                       Exp_Table    => Exp_File,
126                       Build_Import => False);
127
128          --  3) Build base file with exp file and objects files.
129
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);
135
136          --  4) Build new exp from base file and the lib file (.a)
137
138          Utl.Dlltool (Def_File, Dll_File, Lib_File,
139                       Base_File    => Bas_File,
140                       Exp_Table    => Exp_File,
141                       Build_Import => Build_Import);
142
143          --  5) Build the dynamic library
144
145          Utl.Gcc (Output_File => Dll_File,
146                   Files       => Objects_Exp_File,
147                   Options     => Adr_Opt'Unchecked_Access & All_Options,
148                   Build_Lib   => True);
149
150          OS_Lib.Delete_File (Exp_File, Success);
151          OS_Lib.Delete_File (Bas_File, Success);
152          OS_Lib.Delete_File (Jnk_File, Success);
153
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;
161
162       -------------------------
163       -- Ada_Build_Reloc_DLL --
164       -------------------------
165
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);
172
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;
179
180          --  1) Build base file with objects files.
181
182          Utl.Gnatbind (Afiles, Options & Bargs_Options);
183
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;
192
193          --  2) Build exp from base file.
194
195          Utl.Dlltool (Def_File, Dll_File, Lib_File,
196                       Base_File    => Bas_File,
197                       Exp_Table    => Exp_File,
198                       Build_Import => False);
199
200          --  3) Build base file with exp file and objects files.
201
202          Utl.Gnatbind (Afiles, Options & Bargs_Options);
203
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;
215
216          --  4) Build new exp from base file and the lib file (.a)
217
218          Utl.Dlltool (Def_File, Dll_File, Lib_File,
219                       Base_File    => Bas_File,
220                       Exp_Table    => Exp_File,
221                       Build_Import => Build_Import);
222
223          --  5) Build the dynamic library
224
225          Utl.Gnatbind (Afiles, Options & Bargs_Options);
226
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;
238
239          OS_Lib.Delete_File (Exp_File, Success);
240          OS_Lib.Delete_File (Bas_File, Success);
241          OS_Lib.Delete_File (Jnk_File, Success);
242
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;
250
251       -------------------------
252       -- Build_Non_Reloc_DLL --
253       -------------------------
254
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);
262
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;
269
270          --  Build exp table and the lib .a file.
271
272          Utl.Dlltool (Def_File, Dll_File, Lib_File,
273                       Exp_Table    => Exp_File,
274                       Build_Import => Build_Import);
275
276          --  Build the DLL
277
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);
282
283          OS_Lib.Delete_File (Exp_File, Success);
284
285       exception
286          when others =>
287             OS_Lib.Delete_File (Exp_File, Success);
288             raise;
289       end Build_Non_Reloc_DLL;
290
291       -----------------------------
292       -- Ada_Build_Non_Reloc_DLL --
293       -----------------------------
294
295       --  Build a non relocatable DLL with Ada code.
296
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);
304
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;
311
312          --  Build exp table and the lib .a file.
313
314          Utl.Dlltool (Def_File, Dll_File, Lib_File,
315                       Exp_Table    => Exp_File,
316                       Build_Import => Build_Import);
317
318          --  Build the DLL
319
320          Utl.Gnatbind (Afiles, Options & Bargs_Options);
321
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;
333
334          OS_Lib.Delete_File (Exp_File, Success);
335
336       exception
337          when others =>
338             OS_Lib.Delete_File (Exp_File, Success);
339             raise;
340       end Ada_Build_Non_Reloc_DLL;
341
342    begin
343       case Relocatable is
344
345          when True =>
346             if Afiles'Length = 0 then
347                Build_Reloc_DLL;
348             else
349                Ada_Build_Reloc_DLL;
350             end if;
351
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;
358
359       end case;
360    end Build_Dynamic_Library;
361
362    --------------------------
363    -- Build_Import_Library --
364    --------------------------
365
366    procedure Build_Import_Library
367      (Lib_Filename : String;
368       Def_Filename : String)
369    is
370
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.
374
375       Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
376
377       --------------------------
378       -- Build_Import_Library --
379       --------------------------
380
381       procedure Build_Import_Library (Def_Base_Filename : String) is
382
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";
386
387       begin
388
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;
394
395          Utl.Dlltool (Def_File, Dll_File, Lib_File,
396                       Build_Import => True);
397       end Build_Import_Library;
398
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.
404
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;
411
412 end MDLL;