OSDN Git Service

Nathanael Nerode <neroden@gcc.gnu.org>
[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 --                                                                          --
10 --          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
11 --                                                                          --
12 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
13 -- terms of the  GNU General Public License as published  by the Free Soft- --
14 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
15 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
18 -- for  more details.  You should have  received  a copy of the GNU General --
19 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
20 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
21 -- MA 02111-1307, USA.                                                      --
22 --                                                                          --
23 -- GNAT was originally developed  by the GNAT team at  New York University. --
24 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
25 --                                                                          --
26 ------------------------------------------------------------------------------
27
28 --  This package provides the core high level routines used by GNATDLL
29 --  to build Windows DLL
30
31 with Ada.Text_IO;
32
33 with MDLL.Utl;
34 with MDLL.Fil;
35
36 package body MDLL is
37
38    use Ada;
39    use GNAT;
40
41    ---------------------------
42    -- Build_Dynamic_Library --
43    ---------------------------
44
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)
56    is
57
58       use type OS_Lib.Argument_List;
59
60       Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
61
62       Def_File : aliased String := Def_Filename;
63       Jnk_File : aliased String := Base_Filename & ".jnk";
64       Bas_File : aliased String := Base_Filename & ".base";
65       Dll_File : aliased String := Base_Filename & ".dll";
66       Exp_File : aliased String := Base_Filename & ".exp";
67       Lib_File : aliased String := "lib" & Base_Filename & ".a";
68
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;
73
74       All_Options : constant Argument_List := Options & Largs_Options;
75
76       procedure Build_Reloc_DLL;
77       --  Build a relocatable DLL with only objects file specified.
78       --  this use the well known 5 steps build. (see GNAT User's Guide).
79
80       procedure Ada_Build_Reloc_DLL;
81       --  Build a relocatable DLL with Ada code.
82       --  this use the well known 5 steps build. (see GNAT User's Guide).
83
84       procedure Build_Non_Reloc_DLL;
85       --  Build a non relocatable DLL containing no Ada code.
86
87       procedure Ada_Build_Non_Reloc_DLL;
88       --  Build a non relocatable DLL with Ada code.
89
90       ---------------------
91       -- Build_Reloc_DLL --
92       ---------------------
93
94       procedure Build_Reloc_DLL is
95          --  Objects plus the export table (.exp) file
96
97          Objects_Exp_File : constant OS_Lib.Argument_List
98            := Exp_File'Unchecked_Access & Ofiles;
99
100          Success : Boolean;
101
102       begin
103          if not Quiet then
104             Text_IO.Put_Line ("building relocatable DLL...");
105             Text_IO.Put ("make " & Dll_File);
106
107             if Build_Import then
108                Text_IO.Put_Line (" and " & Lib_File);
109             else
110                Text_IO.New_Line;
111             end if;
112          end if;
113
114          --  1) Build base file with objects files.
115
116          Utl.Gcc (Output_File => Jnk_File,
117                   Files       => Ofiles,
118                   Options     => All_Options,
119                   Base_File   => Bas_File,
120                   Build_Lib   => True);
121
122          --  2) Build exp from base file.
123
124          Utl.Dlltool (Def_File, Dll_File, Lib_File,
125                       Base_File    => Bas_File,
126                       Exp_Table    => Exp_File,
127                       Build_Import => False);
128
129          --  3) Build base file with exp file and objects files.
130
131          Utl.Gcc (Output_File => Jnk_File,
132                   Files       => Objects_Exp_File,
133                   Options     => All_Options,
134                   Base_File   => Bas_File,
135                   Build_Lib   => True);
136
137          --  4) Build new exp from base file and the lib file (.a)
138
139          Utl.Dlltool (Def_File, Dll_File, Lib_File,
140                       Base_File    => Bas_File,
141                       Exp_Table    => Exp_File,
142                       Build_Import => Build_Import);
143
144          --  5) Build the dynamic library
145
146          Utl.Gcc (Output_File => Dll_File,
147                   Files       => Objects_Exp_File,
148                   Options     => Adr_Opt'Unchecked_Access & All_Options,
149                   Build_Lib   => True);
150
151          OS_Lib.Delete_File (Exp_File, Success);
152          OS_Lib.Delete_File (Bas_File, Success);
153          OS_Lib.Delete_File (Jnk_File, Success);
154
155       exception
156          when others =>
157             OS_Lib.Delete_File (Exp_File, Success);
158             OS_Lib.Delete_File (Bas_File, Success);
159             OS_Lib.Delete_File (Jnk_File, Success);
160             raise;
161       end Build_Reloc_DLL;
162
163       -------------------------
164       -- Ada_Build_Reloc_DLL --
165       -------------------------
166
167       procedure Ada_Build_Reloc_DLL is
168          Success : Boolean;
169       begin
170          if not Quiet then
171             Text_IO.Put_Line ("Building relocatable DLL...");
172             Text_IO.Put ("make " & Dll_File);
173
174             if Build_Import then
175                Text_IO.Put_Line (" and " & Lib_File);
176             else
177                Text_IO.New_Line;
178             end if;
179          end if;
180
181          --  1) Build base file with objects files.
182
183          Utl.Gnatbind (Afiles, Options & Bargs_Options);
184
185          declare
186             Params : OS_Lib.Argument_List :=
187               Out_Opt'Unchecked_Access & Jnk_File'Unchecked_Access &
188               Lib_Opt'Unchecked_Access &
189               Bas_Opt'Unchecked_Access & Ofiles & All_Options;
190          begin
191             Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
192          end;
193
194          --  2) Build exp from base file.
195
196          Utl.Dlltool (Def_File, Dll_File, Lib_File,
197                       Base_File    => Bas_File,
198                       Exp_Table    => Exp_File,
199                       Build_Import => False);
200
201          --  3) Build base file with exp file and objects files.
202
203          Utl.Gnatbind (Afiles, Options & Bargs_Options);
204
205          declare
206             Params : OS_Lib.Argument_List :=
207               Out_Opt'Unchecked_Access & Jnk_File'Unchecked_Access &
208               Lib_Opt'Unchecked_Access &
209               Bas_Opt'Unchecked_Access &
210               Exp_File'Unchecked_Access &
211               Ofiles &
212               All_Options;
213          begin
214             Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
215          end;
216
217          --  4) Build new exp from base file and the lib file (.a)
218
219          Utl.Dlltool (Def_File, Dll_File, Lib_File,
220                       Base_File    => Bas_File,
221                       Exp_Table    => Exp_File,
222                       Build_Import => Build_Import);
223
224          --  5) Build the dynamic library
225
226          Utl.Gnatbind (Afiles, Options & Bargs_Options);
227
228          declare
229             Params : OS_Lib.Argument_List :=
230               Out_Opt'Unchecked_Access & Dll_File'Unchecked_Access &
231               Lib_Opt'Unchecked_Access &
232               Exp_File'Unchecked_Access &
233               Adr_Opt'Unchecked_Access &
234               Ofiles &
235               All_Options;
236          begin
237             Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
238          end;
239
240          OS_Lib.Delete_File (Exp_File, Success);
241          OS_Lib.Delete_File (Bas_File, Success);
242          OS_Lib.Delete_File (Jnk_File, Success);
243
244       exception
245          when others =>
246             OS_Lib.Delete_File (Exp_File, Success);
247             OS_Lib.Delete_File (Bas_File, Success);
248             OS_Lib.Delete_File (Jnk_File, Success);
249             raise;
250       end Ada_Build_Reloc_DLL;
251
252       -------------------------
253       -- Build_Non_Reloc_DLL --
254       -------------------------
255
256       procedure Build_Non_Reloc_DLL is
257          Success : Boolean;
258       begin
259          if not Quiet then
260             Text_IO.Put_Line ("building non relocatable DLL...");
261             Text_IO.Put ("make " & Dll_File &
262                          " using address " & Lib_Address);
263
264             if Build_Import then
265                Text_IO.Put_Line (" and " & Lib_File);
266             else
267                Text_IO.New_Line;
268             end if;
269          end if;
270
271          --  Build exp table and the lib .a file.
272
273          Utl.Dlltool (Def_File, Dll_File, Lib_File,
274                       Exp_Table    => Exp_File,
275                       Build_Import => Build_Import);
276
277          --  Build the DLL
278
279          Utl.Gcc (Output_File => Dll_File,
280                   Files       => Exp_File'Unchecked_Access & Ofiles,
281                   Options     => Adr_Opt'Unchecked_Access & All_Options,
282                   Build_Lib   => True);
283
284          OS_Lib.Delete_File (Exp_File, Success);
285
286       exception
287          when others =>
288             OS_Lib.Delete_File (Exp_File, Success);
289             raise;
290       end Build_Non_Reloc_DLL;
291
292       -----------------------------
293       -- Ada_Build_Non_Reloc_DLL --
294       -----------------------------
295
296       --  Build a non relocatable DLL with Ada code.
297
298       procedure Ada_Build_Non_Reloc_DLL is
299          Success : Boolean;
300       begin
301          if not Quiet then
302             Text_IO.Put_Line ("building non relocatable DLL...");
303             Text_IO.Put ("make " & Dll_File &
304                          " using address " & Lib_Address);
305
306             if Build_Import then
307                Text_IO.Put_Line (" and " & Lib_File);
308             else
309                Text_IO.New_Line;
310             end if;
311          end if;
312
313          --  Build exp table and the lib .a file.
314
315          Utl.Dlltool (Def_File, Dll_File, Lib_File,
316                       Exp_Table    => Exp_File,
317                       Build_Import => Build_Import);
318
319          --  Build the DLL
320
321          Utl.Gnatbind (Afiles, Options & Bargs_Options);
322
323          declare
324             Params : OS_Lib.Argument_List :=
325               Out_Opt'Unchecked_Access & Dll_File'Unchecked_Access &
326               Lib_Opt'Unchecked_Access &
327               Exp_File'Unchecked_Access &
328               Adr_Opt'Unchecked_Access &
329               Ofiles &
330               All_Options;
331          begin
332             Utl.Gnatlink (Afiles (Afiles'Last).all, Params);
333          end;
334
335          OS_Lib.Delete_File (Exp_File, Success);
336
337       exception
338          when others =>
339             OS_Lib.Delete_File (Exp_File, Success);
340             raise;
341       end Ada_Build_Non_Reloc_DLL;
342
343    begin
344       case Relocatable is
345
346          when True =>
347             if Afiles'Length = 0 then
348                Build_Reloc_DLL;
349             else
350                Ada_Build_Reloc_DLL;
351             end if;
352
353          when False =>
354             if Afiles'Length = 0 then
355                Build_Non_Reloc_DLL;
356             else
357                Ada_Build_Non_Reloc_DLL;
358             end if;
359
360       end case;
361    end Build_Dynamic_Library;
362
363    --------------------------
364    -- Build_Import_Library --
365    --------------------------
366
367    procedure Build_Import_Library
368      (Lib_Filename : String;
369       Def_Filename : String)
370    is
371
372       procedure Build_Import_Library (Def_Base_Filename : String);
373       --  Build an import library.
374       --  this is to build only a .a library to link against a DLL.
375
376       Base_Filename : constant String := MDLL.Fil.Ext_To (Lib_Filename);
377
378       --------------------------
379       -- Build_Import_Library --
380       --------------------------
381
382       procedure Build_Import_Library (Def_Base_Filename : String) is
383
384          Def_File : String renames Def_Filename;
385          Dll_File : constant String := Def_Base_Filename & ".dll";
386          Lib_File : constant String := "lib" & Base_Filename & ".a";
387
388       begin
389
390          if not Quiet then
391             Text_IO.Put_Line ("Building import library...");
392             Text_IO.Put_Line ("make " & Lib_File &
393                               " to use dynamic library " & Dll_File);
394          end if;
395
396          Utl.Dlltool (Def_File, Dll_File, Lib_File,
397                       Build_Import => True);
398       end Build_Import_Library;
399
400    begin
401       --  If the library has the form lib<name>.a then the def file should
402       --  be <name>.def and the DLL to link against <name>.dll
403       --  this is a Windows convention and we try as much as possible to
404       --  follow the platform convention.
405
406       if Lib_Filename'Length > 3 and then Lib_Filename (1 .. 3) = "lib" then
407          Build_Import_Library (Base_Filename (4 .. Base_Filename'Last));
408       else
409          Build_Import_Library (Base_Filename);
410       end if;
411    end Build_Import_Library;
412
413 end MDLL;