OSDN Git Service

c07768d7380f89c7b91d6240d5cfa3dfd6b74467
[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 --                            $Revision$
10 --                                                                          --
11 --          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
12 --                                                                          --
13 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
14 -- terms of the  GNU General Public License as published  by the Free Soft- --
15 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
16 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
19 -- for  more details.  You should have  received  a copy of the GNU General --
20 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
21 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
22 -- MA 02111-1307, USA.                                                      --
23 --                                                                          --
24 -- GNAT was originally developed  by the GNAT team at  New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
26 --                                                                          --
27 ------------------------------------------------------------------------------
28
29 --  This package provides the core high level routines used by GNATDLL
30 --  to build Windows DLL
31
32 with Ada.Text_IO;
33
34 with MDLL.Tools;
35 with MDLL.Files;
36
37 package body MDLL is
38
39    use Ada;
40    use GNAT;
41
42    ---------------------------
43    -- Build_Dynamic_Library --
44    ---------------------------
45
46    procedure Build_Dynamic_Library
47      (Ofiles        : Argument_List;
48       Afiles        : Argument_List;
49       Options       : Argument_List;
50       Bargs_Options : Argument_List;
51       Largs_Options : Argument_List;
52       Lib_Filename  : String;
53       Def_Filename  : String;
54       Lib_Address   : String  := "";
55       Build_Import  : Boolean := False;
56       Relocatable   : Boolean := False)
57    is
58
59       use type OS_Lib.Argument_List;
60
61       Base_Filename : constant String := MDLL.Files.Ext_To (Lib_Filename);
62
63       Def_File : aliased String := Def_Filename;
64       Jnk_File : aliased String := Base_Filename & ".jnk";
65       Bas_File : aliased String := Base_Filename & ".base";
66       Dll_File : aliased String := Base_Filename & ".dll";
67       Exp_File : aliased String := Base_Filename & ".exp";
68       Lib_File : aliased String := "lib" & Base_Filename & ".a";
69
70       Bas_Opt  : aliased String := "-Wl,--base-file," & Bas_File;
71       Lib_Opt  : aliased String := "-mdll";
72       Out_Opt  : aliased String := "-o";
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
96          --  Objects plus the export table (.exp) file
97
98          Objects_Exp_File : OS_Lib.Argument_List
99            := Exp_File'Unchecked_Access & Ofiles;
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          Tools.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          Tools.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          Tools.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          Tools.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          Tools.Gcc (Output_File => Dll_File,
146                     Files       => Objects_Exp_File,
147                     Options     => All_Options,
148                     Build_Lib   => True);
149
150          Tools.Delete_File (Exp_File);
151          Tools.Delete_File (Bas_File);
152          Tools.Delete_File (Jnk_File);
153
154       exception
155          when others =>
156             Tools.Delete_File (Exp_File);
157             Tools.Delete_File (Bas_File);
158             Tools.Delete_File (Jnk_File);
159             raise;
160       end Build_Reloc_DLL;
161
162       -------------------------
163       -- Ada_Build_Reloc_DLL --
164       -------------------------
165
166       procedure Ada_Build_Reloc_DLL is
167       begin
168          if not Quiet then
169             Text_IO.Put_Line ("Building relocatable DLL...");
170             Text_IO.Put ("make " & Dll_File);
171
172             if Build_Import then
173                Text_IO.Put_Line (" and " & Lib_File);
174             else
175                Text_IO.New_Line;
176             end if;
177          end if;
178
179          --  1) Build base file with objects files.
180
181          Tools.Gnatbind (Afiles, Options & Bargs_Options);
182
183          declare
184             Params : OS_Lib.Argument_List :=
185               Out_Opt'Unchecked_Access & Jnk_File'Unchecked_Access &
186               Lib_Opt'Unchecked_Access &
187               Bas_Opt'Unchecked_Access & Ofiles & All_Options;
188          begin
189             Tools.Gnatlink (Afiles (Afiles'Last).all,
190                             Params);
191          end;
192
193          --  2) Build exp from base file.
194
195          Tools.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          Tools.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             Tools.Gnatlink (Afiles (Afiles'Last).all,
214                             Params);
215          end;
216
217          --  4) Build new exp from base file and the lib file (.a)
218
219          Tools.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          Tools.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               Ofiles &
234               All_Options;
235          begin
236             Tools.Gnatlink (Afiles (Afiles'Last).all,
237                             Params);
238          end;
239
240          Tools.Delete_File (Exp_File);
241          Tools.Delete_File (Bas_File);
242          Tools.Delete_File (Jnk_File);
243
244       exception
245          when others =>
246             Tools.Delete_File (Exp_File);
247             Tools.Delete_File (Bas_File);
248             Tools.Delete_File (Jnk_File);
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       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          Tools.Dlltool (Def_File, Dll_File, Lib_File,
273                         Exp_Table    => Exp_File,
274                         Build_Import => Build_Import);
275
276          --  Build the DLL
277
278          Tools.Gcc (Output_File => Dll_File,
279                     Files       => Exp_File'Unchecked_Access & Ofiles,
280                     Options     => All_Options,
281                     Build_Lib   => True);
282
283          Tools.Delete_File (Exp_File);
284
285       exception
286          when others =>
287             Tools.Delete_File (Exp_File);
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       begin
299          if not Quiet then
300             Text_IO.Put_Line ("building non relocatable DLL...");
301             Text_IO.Put ("make " & Dll_File &
302                          " using address " & Lib_Address);
303
304             if Build_Import then
305                Text_IO.Put_Line (" and " & Lib_File);
306             else
307                Text_IO.New_Line;
308             end if;
309          end if;
310
311          --  Build exp table and the lib .a file.
312
313          Tools.Dlltool (Def_File, Dll_File, Lib_File,
314                         Exp_Table    => Exp_File,
315                         Build_Import => Build_Import);
316
317          --  Build the DLL
318
319          Tools.Gnatbind (Afiles, Options & Bargs_Options);
320
321          declare
322             Params : OS_Lib.Argument_List :=
323               Out_Opt'Unchecked_Access & Dll_File'Unchecked_Access &
324               Lib_Opt'Unchecked_Access &
325               Exp_File'Unchecked_Access &
326               Ofiles &
327               All_Options;
328          begin
329             Tools.Gnatlink (Afiles (Afiles'Last).all,
330                             Params);
331          end;
332
333          Tools.Delete_File (Exp_File);
334
335       exception
336          when others =>
337             Tools.Delete_File (Exp_File);
338             raise;
339       end Ada_Build_Non_Reloc_DLL;
340
341    begin
342       case Relocatable is
343
344          when True =>
345             if Afiles'Length = 0 then
346                Build_Reloc_DLL;
347             else
348                Ada_Build_Reloc_DLL;
349             end if;
350
351          when False =>
352             if Afiles'Length = 0 then
353                Build_Non_Reloc_DLL;
354             else
355                Ada_Build_Non_Reloc_DLL;
356             end if;
357
358       end case;
359    end Build_Dynamic_Library;
360
361    --------------------------
362    -- Build_Import_Library --
363    --------------------------
364
365    procedure Build_Import_Library
366      (Lib_Filename : String;
367       Def_Filename : String)
368    is
369
370       procedure Build_Import_Library (Def_Base_Filename : String);
371       --  Build an import library.
372       --  this is to build only a .a library to link against a DLL.
373
374       Base_Filename : constant String := MDLL.Files.Ext_To (Lib_Filename);
375
376       --------------------------
377       -- Build_Import_Library --
378       --------------------------
379
380       procedure Build_Import_Library (Def_Base_Filename : String) is
381
382          Def_File : String renames Def_Filename;
383          Dll_File : constant String := Def_Base_Filename & ".dll";
384          Lib_File : constant String := "lib" & Base_Filename & ".a";
385
386       begin
387
388          if not Quiet then
389             Text_IO.Put_Line ("Building import library...");
390             Text_IO.Put_Line ("make " & Lib_File &
391                               " to use dynamic library " & Dll_File);
392          end if;
393
394          Tools.Dlltool (Def_File, Dll_File, Lib_File,
395                         Build_Import => True);
396       end Build_Import_Library;
397
398    begin
399       --  If the library has the form lib<name>.a then the def file should
400       --  be <name>.def and the DLL to link against <name>.dll
401       --  this is a Windows convention and we try as much as possible to
402       --  follow the platform convention.
403
404       if Lib_Filename'Length > 3 and then Lib_Filename (1 .. 3) = "lib" then
405          Build_Import_Library (Base_Filename (4 .. Base_Filename'Last));
406       else
407          Build_Import_Library (Base_Filename);
408       end if;
409    end Build_Import_Library;
410
411 end MDLL;