]>
Commit | Line | Data |
---|---|---|
84481f76 RK |
1 | ------------------------------------------------------------------------------ |
2 | -- -- | |
3 | -- GNAT COMPILER COMPONENTS -- | |
4 | -- -- | |
5 | -- M L I B . U T L -- | |
6 | -- -- | |
7 | -- B o d y -- | |
8 | -- -- | |
5950a3ac | 9 | -- Copyright (C) 2002-2004, Ada Core Technologies, Inc. -- |
84481f76 RK |
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. -- | |
fbf5a39b | 23 | -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
84481f76 RK |
24 | -- -- |
25 | ------------------------------------------------------------------------------ | |
26 | ||
fbf5a39b AC |
27 | with MLib.Fil; use MLib.Fil; |
28 | with MLib.Tgt; use MLib.Tgt; | |
84481f76 | 29 | |
fbf5a39b AC |
30 | with Namet; use Namet; |
31 | with Opt; | |
32 | with Osint; | |
33 | with Output; use Output; | |
84481f76 | 34 | |
fbf5a39b | 35 | with GNAT; use GNAT; |
84481f76 | 36 | |
fbf5a39b | 37 | package body MLib.Utl is |
84481f76 | 38 | |
c4820158 | 39 | Initialized : Boolean := False; |
84481f76 | 40 | |
c4820158 NS |
41 | Gcc_Name : constant String := "gcc"; |
42 | Gcc_Exec : OS_Lib.String_Access; | |
84481f76 | 43 | |
c4820158 NS |
44 | Ar_Name : OS_Lib.String_Access; |
45 | Ar_Exec : OS_Lib.String_Access; | |
46 | Ar_Options : OS_Lib.String_List_Access; | |
84481f76 | 47 | |
c4820158 NS |
48 | Ranlib_Name : OS_Lib.String_Access; |
49 | Ranlib_Exec : OS_Lib.String_Access := null; | |
50 | Ranlib_Options : OS_Lib.String_List_Access := null; | |
84481f76 RK |
51 | |
52 | procedure Initialize; | |
53 | -- Look for the tools in the path and record the full path for each one | |
54 | ||
55 | -------- | |
56 | -- Ar -- | |
57 | -------- | |
58 | ||
59 | procedure Ar (Output_File : String; Objects : Argument_List) is | |
84481f76 | 60 | Full_Output_File : constant String := |
fbf5a39b AC |
61 | Ext_To (Output_File, Archive_Ext); |
62 | ||
63 | Arguments : OS_Lib.Argument_List_Access; | |
84481f76 | 64 | |
84481f76 RK |
65 | Success : Boolean; |
66 | ||
fbf5a39b | 67 | Line_Length : Natural := 0; |
fbf5a39b | 68 | |
84481f76 | 69 | begin |
35ae2ed8 | 70 | Utl.Initialize; |
84481f76 | 71 | |
fbf5a39b AC |
72 | Arguments := |
73 | new String_List (1 .. 1 + Ar_Options'Length + Objects'Length); | |
74 | Arguments (1 .. Ar_Options'Length) := Ar_Options.all; -- "ar cr ..." | |
75 | Arguments (Ar_Options'Length + 1) := new String'(Full_Output_File); | |
76 | Arguments (Ar_Options'Length + 2 .. Arguments'Last) := Objects; | |
84481f76 RK |
77 | |
78 | Delete_File (Full_Output_File); | |
79 | ||
80 | if not Opt.Quiet_Output then | |
fbf5a39b AC |
81 | Write_Str (Ar_Name.all); |
82 | Line_Length := Ar_Name'Length; | |
84481f76 RK |
83 | |
84 | for J in Arguments'Range loop | |
5950a3ac | 85 | |
fbf5a39b AC |
86 | -- Make sure the Output buffer does not overflow |
87 | ||
5950a3ac AC |
88 | if Line_Length + 1 + Arguments (J)'Length > |
89 | Integer (Opt.Max_Line_Length) | |
90 | then | |
fbf5a39b AC |
91 | Write_Eol; |
92 | Line_Length := 0; | |
93 | end if; | |
94 | ||
84481f76 RK |
95 | Write_Char (' '); |
96 | Write_Str (Arguments (J).all); | |
fbf5a39b | 97 | Line_Length := Line_Length + 1 + Arguments (J)'Length; |
84481f76 RK |
98 | end loop; |
99 | ||
100 | Write_Eol; | |
101 | end if; | |
102 | ||
fbf5a39b | 103 | OS_Lib.Spawn (Ar_Exec.all, Arguments.all, Success); |
84481f76 RK |
104 | |
105 | if not Success then | |
fbf5a39b | 106 | Fail (Ar_Name.all, " execution error."); |
84481f76 RK |
107 | end if; |
108 | ||
109 | -- If we have found ranlib, run it over the library | |
110 | ||
111 | if Ranlib_Exec /= null then | |
112 | if not Opt.Quiet_Output then | |
fbf5a39b | 113 | Write_Str (Ranlib_Name.all); |
84481f76 | 114 | Write_Char (' '); |
fbf5a39b | 115 | Write_Line (Arguments (Ar_Options'Length + 1).all); |
84481f76 RK |
116 | end if; |
117 | ||
fbf5a39b AC |
118 | OS_Lib.Spawn |
119 | (Ranlib_Exec.all, | |
c4820158 | 120 | Ranlib_Options.all & (Arguments (Ar_Options'Length + 1)), |
fbf5a39b | 121 | Success); |
84481f76 RK |
122 | |
123 | if not Success then | |
fbf5a39b | 124 | Fail (Ranlib_Name.all, " execution error."); |
84481f76 RK |
125 | end if; |
126 | end if; | |
127 | end Ar; | |
128 | ||
129 | ----------------- | |
130 | -- Delete_File -- | |
131 | ----------------- | |
132 | ||
133 | procedure Delete_File (Filename : in String) is | |
134 | File : constant String := Filename & ASCII.Nul; | |
135 | Success : Boolean; | |
136 | ||
137 | begin | |
138 | OS_Lib.Delete_File (File'Address, Success); | |
139 | ||
140 | if Opt.Verbose_Mode then | |
141 | if Success then | |
142 | Write_Str ("deleted "); | |
143 | ||
144 | else | |
145 | Write_Str ("could not delete "); | |
146 | end if; | |
147 | ||
148 | Write_Line (Filename); | |
149 | end if; | |
150 | end Delete_File; | |
151 | ||
152 | --------- | |
153 | -- Gcc -- | |
154 | --------- | |
155 | ||
156 | procedure Gcc | |
157 | (Output_File : String; | |
158 | Objects : Argument_List; | |
fbf5a39b | 159 | Options : Argument_List; |
51004cb5 VC |
160 | Options_2 : Argument_List; |
161 | Driver_Name : Name_Id := No_Name) | |
84481f76 | 162 | is |
fbf5a39b AC |
163 | Arguments : |
164 | OS_Lib.Argument_List | |
165 | (1 .. 7 + Objects'Length + Options'Length + Options_2'Length); | |
84481f76 | 166 | |
fbf5a39b AC |
167 | A : Natural := 0; |
168 | Success : Boolean; | |
84481f76 | 169 | |
fbf5a39b AC |
170 | Out_Opt : constant OS_Lib.String_Access := |
171 | new String'("-o"); | |
172 | Out_V : constant OS_Lib.String_Access := | |
173 | new String'(Output_File); | |
174 | Lib_Dir : constant OS_Lib.String_Access := | |
175 | new String'("-L" & Lib_Directory); | |
176 | Lib_Opt : constant OS_Lib.String_Access := | |
177 | new String'(Dynamic_Option); | |
178 | ||
179 | Driver : String_Access; | |
84481f76 | 180 | begin |
35ae2ed8 | 181 | Utl.Initialize; |
84481f76 | 182 | |
fbf5a39b AC |
183 | if Driver_Name = No_Name then |
184 | Driver := Gcc_Exec; | |
185 | ||
186 | else | |
187 | Driver := OS_Lib.Locate_Exec_On_Path (Get_Name_String (Driver_Name)); | |
188 | ||
189 | if Driver = null then | |
190 | Fail (Get_Name_String (Driver_Name), " not found in path"); | |
191 | end if; | |
192 | end if; | |
193 | ||
84481f76 RK |
194 | if Lib_Opt'Length /= 0 then |
195 | A := A + 1; | |
196 | Arguments (A) := Lib_Opt; | |
197 | end if; | |
198 | ||
199 | A := A + 1; | |
200 | Arguments (A) := Out_Opt; | |
07fc65c4 | 201 | |
84481f76 RK |
202 | A := A + 1; |
203 | Arguments (A) := Out_V; | |
204 | ||
205 | A := A + 1; | |
206 | Arguments (A) := Lib_Dir; | |
207 | ||
208 | A := A + Options'Length; | |
209 | Arguments (A - Options'Length + 1 .. A) := Options; | |
210 | ||
211 | A := A + Objects'Length; | |
212 | Arguments (A - Objects'Length + 1 .. A) := Objects; | |
213 | ||
fbf5a39b AC |
214 | A := A + Options_2'Length; |
215 | Arguments (A - Options_2'Length + 1 .. A) := Options_2; | |
216 | ||
84481f76 | 217 | if not Opt.Quiet_Output then |
fbf5a39b | 218 | Write_Str (Driver.all); |
84481f76 RK |
219 | |
220 | for J in 1 .. A loop | |
221 | Write_Char (' '); | |
222 | Write_Str (Arguments (J).all); | |
223 | end loop; | |
224 | ||
225 | Write_Eol; | |
226 | end if; | |
227 | ||
fbf5a39b | 228 | OS_Lib.Spawn (Driver.all, Arguments (1 .. A), Success); |
84481f76 RK |
229 | |
230 | if not Success then | |
fbf5a39b AC |
231 | if Driver_Name = No_Name then |
232 | Fail (Gcc_Name, " execution error"); | |
233 | ||
234 | else | |
235 | Fail (Get_Name_String (Driver_Name), " execution error"); | |
236 | end if; | |
84481f76 RK |
237 | end if; |
238 | end Gcc; | |
239 | ||
240 | ---------------- | |
241 | -- Initialize -- | |
242 | ---------------- | |
243 | ||
244 | procedure Initialize is | |
84481f76 RK |
245 | begin |
246 | if not Initialized then | |
247 | Initialized := True; | |
248 | ||
249 | -- gcc | |
250 | ||
251 | Gcc_Exec := OS_Lib.Locate_Exec_On_Path (Gcc_Name); | |
252 | ||
253 | if Gcc_Exec = null then | |
84481f76 RK |
254 | Fail (Gcc_Name, " not found in path"); |
255 | ||
256 | elsif Opt.Verbose_Mode then | |
257 | Write_Str ("found "); | |
258 | Write_Line (Gcc_Exec.all); | |
259 | end if; | |
260 | ||
261 | -- ar | |
262 | ||
fbf5a39b AC |
263 | Ar_Name := new String'(Archive_Builder); |
264 | Ar_Exec := OS_Lib.Locate_Exec_On_Path (Ar_Name.all); | |
84481f76 RK |
265 | |
266 | if Ar_Exec = null then | |
fbf5a39b | 267 | Fail (Ar_Name.all, " not found in path"); |
84481f76 RK |
268 | |
269 | elsif Opt.Verbose_Mode then | |
270 | Write_Str ("found "); | |
271 | Write_Line (Ar_Exec.all); | |
272 | end if; | |
273 | ||
fbf5a39b AC |
274 | Ar_Options := Archive_Builder_Options; |
275 | ||
84481f76 RK |
276 | -- ranlib |
277 | ||
fbf5a39b | 278 | Ranlib_Name := new String'(Archive_Indexer); |
84481f76 | 279 | |
fbf5a39b AC |
280 | if Ranlib_Name'Length > 0 then |
281 | Ranlib_Exec := OS_Lib.Locate_Exec_On_Path (Ranlib_Name.all); | |
84481f76 | 282 | |
fbf5a39b AC |
283 | if Ranlib_Exec /= null and then Opt.Verbose_Mode then |
284 | Write_Str ("found "); | |
285 | Write_Line (Ranlib_Exec.all); | |
286 | end if; | |
287 | end if; | |
c4820158 NS |
288 | |
289 | Ranlib_Options := Archive_Indexer_Options; | |
84481f76 | 290 | end if; |
84481f76 RK |
291 | end Initialize; |
292 | ||
293 | ------------------- | |
294 | -- Lib_Directory -- | |
295 | ------------------- | |
296 | ||
297 | function Lib_Directory return String is | |
fbf5a39b | 298 | Libgnat : constant String := Tgt.Libgnat; |
84481f76 RK |
299 | |
300 | begin | |
301 | Name_Len := Libgnat'Length; | |
302 | Name_Buffer (1 .. Name_Len) := Libgnat; | |
fbf5a39b | 303 | Get_Name_String (Osint.Find_File (Name_Enter, Osint.Library)); |
84481f76 RK |
304 | |
305 | -- Remove libgnat.a | |
306 | ||
307 | return Name_Buffer (1 .. Name_Len - Libgnat'Length); | |
308 | end Lib_Directory; | |
309 | ||
310 | end MLib.Utl; |