1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- M D L L . T O O L S --
9 -- Copyright (C) 1992-2018, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 -- Interface to externals tools used to build DLL and import libraries
31 with GNAT
.Directory_Operations
;
34 package body MDLL
.Utl
is
39 Dlltool_Name
: constant String := "dlltool";
40 Dlltool_Exec
: OS_Lib
.String_Access
;
42 Gcc_Name
: constant String := "gcc";
43 Gcc_Exec
: OS_Lib
.String_Access
;
45 Gnatbind_Name
: constant String := "gnatbind";
46 Gnatbind_Exec
: OS_Lib
.String_Access
;
48 Gnatlink_Name
: constant String := "gnatlink";
49 Gnatlink_Exec
: OS_Lib
.String_Access
;
51 procedure Print_Command
53 Arguments
: OS_Lib
.Argument_List
);
54 -- display the command run when in Verbose mode
60 procedure Print_Command
62 Arguments
: OS_Lib
.Argument_List
)
66 Text_IO
.Put
(Tool_Name
);
67 for K
in Arguments
'Range loop
68 Text_IO
.Put
(" " & Arguments
(K
).all);
79 (Def_Filename
: String;
82 Exp_Table
: String := "";
83 Base_File
: String := "";
84 Build_Import
: Boolean)
86 Arguments
: OS_Lib
.Argument_List
(1 .. 11);
91 Def_Opt
: aliased String := "--def";
92 Def_V
: aliased String := Def_Filename
;
93 Dll_Opt
: aliased String := "--dllname";
94 Dll_V
: aliased String := DLL_Name
;
95 Lib_Opt
: aliased String := "--output-lib";
96 Lib_V
: aliased String := Library
;
97 Exp_Opt
: aliased String := "--output-exp";
98 Exp_V
: aliased String := Exp_Table
;
99 Bas_Opt
: aliased String := "--base-file";
100 Bas_V
: aliased String := Base_File
;
101 No_Suf_Opt
: aliased String := "-k";
104 Arguments
(1 .. 4) := (1 => Def_Opt
'Unchecked_Access,
105 2 => Def_V
'Unchecked_Access,
106 3 => Dll_Opt
'Unchecked_Access,
107 4 => Dll_V
'Unchecked_Access);
112 Arguments
(A
) := No_Suf_Opt
'Unchecked_Access;
115 if Library
/= "" and then Build_Import
then
117 Arguments
(A
) := Lib_Opt
'Unchecked_Access;
119 Arguments
(A
) := Lib_V
'Unchecked_Access;
122 if Exp_Table
/= "" then
124 Arguments
(A
) := Exp_Opt
'Unchecked_Access;
126 Arguments
(A
) := Exp_V
'Unchecked_Access;
129 if Base_File
/= "" then
131 Arguments
(A
) := Bas_Opt
'Unchecked_Access;
133 Arguments
(A
) := Bas_V
'Unchecked_Access;
136 Print_Command
("dlltool", Arguments
(1 .. A
));
138 OS_Lib
.Spawn
(Dlltool_Exec
.all, Arguments
(1 .. A
), Success
);
141 Exceptions
.Raise_Exception
142 (Tools_Error
'Identity, Dlltool_Name
& " execution error.");
151 (Output_File
: String;
152 Files
: Argument_List
;
153 Options
: Argument_List
;
154 Base_File
: String := "";
155 Build_Lib
: Boolean := False)
159 Arguments
: OS_Lib
.Argument_List
160 (1 .. 5 + Files
'Length + Options
'Length);
164 C_Opt
: aliased String := "-c";
165 Out_Opt
: aliased String := "-o";
166 Out_V
: aliased String := Output_File
;
167 Bas_Opt
: aliased String := "-Wl,--base-file," & Base_File
;
168 Lib_Opt
: aliased String := "-mdll";
169 Lib_Dir
: aliased String := "-L" & Object_Dir_Default_Prefix
;
174 Arguments
(A
) := Lib_Opt
'Unchecked_Access;
176 Arguments
(A
) := C_Opt
'Unchecked_Access;
180 Arguments
(A
.. A
+ 2) := (Out_Opt
'Unchecked_Access,
181 Out_V
'Unchecked_Access,
182 Lib_Dir
'Unchecked_Access);
185 if Base_File
/= "" then
187 Arguments
(A
) := Bas_Opt
'Unchecked_Access;
191 Arguments
(A
.. A
+ Files
'Length - 1) := Files
;
192 A
:= A
+ Files
'Length - 1;
196 Arguments
(A
.. A
+ Options
'Length - 1) := Options
;
197 A
:= A
+ Options
'Length - 1;
200 Largs
: Argument_List
(Options
'Range);
201 L
: Natural := Largs
'First - 1;
203 for K
in Options
'Range loop
204 if Options
(K
) (1 .. 2) /= "-l" then
206 Largs
(L
) := Options
(K
);
210 Arguments
(A
.. A
+ L
- 1) := Largs
(1 .. L
);
215 Print_Command
("gcc", Arguments
(1 .. A
));
217 OS_Lib
.Spawn
(Gcc_Exec
.all, Arguments
(1 .. A
), Success
);
220 Exceptions
.Raise_Exception
221 (Tools_Error
'Identity, Gcc_Name
& " execution error.");
230 (Alis
: Argument_List
;
231 Args
: Argument_List
:= Null_Argument_List
)
233 Arguments
: OS_Lib
.Argument_List
(1 .. 1 + Alis
'Length + Args
'Length);
236 No_Main_Opt
: aliased String := "-n";
239 Arguments
(1) := No_Main_Opt
'Unchecked_Access;
240 Arguments
(2 .. 1 + Alis
'Length) := Alis
;
241 Arguments
(2 + Alis
'Length .. Arguments
'Last) := Args
;
243 Print_Command
("gnatbind", Arguments
);
245 OS_Lib
.Spawn
(Gnatbind_Exec
.all, Arguments
, Success
);
247 -- Delete binder files on failure
251 Base_Name
: constant String :=
252 Directory_Operations
.Base_Name
(Alis
(Alis
'First).all, ".ali");
254 OS_Lib
.Delete_File
("b~" & Base_Name
& ".ads", Success
);
255 OS_Lib
.Delete_File
("b~" & Base_Name
& ".adb", Success
);
258 Exceptions
.Raise_Exception
259 (Tools_Error
'Identity, Gnatbind_Name
& " execution error.");
269 Args
: Argument_List
:= Null_Argument_List
)
271 Arguments
: OS_Lib
.Argument_List
(1 .. 1 + Args
'Length);
274 Ali_Name
: aliased String := Ali
;
277 Arguments
(1) := Ali_Name
'Unchecked_Access;
278 Arguments
(2 .. Arguments
'Last) := Args
;
280 Print_Command
("gnatlink", Arguments
);
282 OS_Lib
.Spawn
(Gnatlink_Exec
.all, Arguments
, Success
);
285 -- Delete binder files
287 Base_Name
: constant String :=
288 Directory_Operations
.Base_Name
(Ali
, ".ali");
290 OS_Lib
.Delete_File
("b~" & Base_Name
& ".ads", Success
);
291 OS_Lib
.Delete_File
("b~" & Base_Name
& ".adb", Success
);
292 OS_Lib
.Delete_File
("b~" & Base_Name
& ".ali", Success
);
293 OS_Lib
.Delete_File
("b~" & Base_Name
& ".o", Success
);
296 Exceptions
.Raise_Exception
297 (Tools_Error
'Identity, Gnatlink_Name
& " execution error.");
306 use type OS_Lib
.String_Access
;
310 if Dlltool_Exec
= null then
311 Dlltool_Exec
:= OS_Lib
.Locate_Exec_On_Path
(Dlltool_Name
);
313 if Dlltool_Exec
= null then
314 Exceptions
.Raise_Exception
315 (Tools_Error
'Identity, Dlltool_Name
& " not found in path");
318 Text_IO
.Put_Line
("using " & Dlltool_Exec
.all);
324 if Gcc_Exec
= null then
325 Gcc_Exec
:= OS_Lib
.Locate_Exec_On_Path
(Gcc_Name
);
327 if Gcc_Exec
= null then
328 Exceptions
.Raise_Exception
329 (Tools_Error
'Identity, Gcc_Name
& " not found in path");
332 Text_IO
.Put_Line
("using " & Gcc_Exec
.all);
338 if Gnatbind_Exec
= null then
339 Gnatbind_Exec
:= OS_Lib
.Locate_Exec_On_Path
(Gnatbind_Name
);
341 if Gnatbind_Exec
= null then
342 Exceptions
.Raise_Exception
343 (Tools_Error
'Identity, Gnatbind_Name
& " not found in path");
346 Text_IO
.Put_Line
("using " & Gnatbind_Exec
.all);
352 if Gnatlink_Exec
= null then
353 Gnatlink_Exec
:= OS_Lib
.Locate_Exec_On_Path
(Gnatlink_Name
);
355 if Gnatlink_Exec
= null then
356 Exceptions
.Raise_Exception
357 (Tools_Error
'Identity, Gnatlink_Name
& " not found in path");
360 Text_IO
.Put_Line
("using " & Gnatlink_Exec
.all);