b79efa15e4f8763ac0eee7199c12ba58cd1bdf39
[platform/upstream/gcc.git] / gcc / ada / gnatlbr.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              G N A T L B R                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1997-2003 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 --  Program to create, set, or delete an alternate runtime library.
28
29 --  Works by calling an appropriate target specific Makefile residing
30 --  in the default library object (e.g. adalib) directory from the context
31 --  of the new library objects directory.
32
33 --  Command line arguments are:
34 --  1st:  --[create | set | delete]=<directory_spec>
35 --    --create : Build a library
36 --    --set    : Set environment variables to point to a library
37 --    --delete : Delete a library
38
39 --  2nd:  --config=<file_spec>
40 --  A -gnatg valid file containing desired configuration pragmas
41
42 --  This program is currently used only on Alpha/VMS
43
44 with Ada.Command_Line;     use Ada.Command_Line;
45 with Ada.Text_IO;          use Ada.Text_IO;
46 with GNAT.OS_Lib;          use GNAT.OS_Lib;
47 with Gnatvsn;              use Gnatvsn;
48 with Interfaces.C_Streams; use Interfaces.C_Streams;
49 with Osint;                use Osint;
50 with System;
51
52 procedure GnatLbr is
53    pragma Ident (Gnat_Version_String);
54
55    type Lib_Mode is (None, Create, Set, Delete);
56    Next_Arg  : Integer;
57    Mode      : Lib_Mode := None;
58    ADC_File  : String_Access := null;
59    Lib_Dir   : String_Access := null;
60    Make      : constant String := "make";
61    Make_Path : String_Access;
62
63    procedure Create_Directory (Name : System.Address; Mode : Integer);
64    pragma Import (C, Create_Directory, "mkdir");
65
66 begin
67    if Argument_Count = 0 then
68       Put ("Usage: ");
69       Put_Line
70         ("gnatlbr --[create|set|delete]=<directory> [--config=<file>]");
71       Exit_Program (E_Fatal);
72    end if;
73
74    Next_Arg := 1;
75
76    loop
77       exit when Next_Arg > Argument_Count;
78
79       Process_One_Arg : declare
80          Arg : String := Argument (Next_Arg);
81
82       begin
83
84          if Arg'Length > 9 and then Arg (1 .. 9) = "--create=" then
85             if Mode = None then
86                Mode := Create;
87                Lib_Dir := new String'(Arg (10 .. Arg'Last));
88             else
89                Put_Line (Standard_Error, "Error: Multiple modes specified");
90                Exit_Program (E_Fatal);
91             end if;
92
93          elsif Arg'Length > 6 and then Arg (1 .. 6) = "--set=" then
94             if Mode = None then
95                Mode := Set;
96                Lib_Dir := new String'(Arg (7 .. Arg'Last));
97             else
98                Put_Line (Standard_Error, "Error: Multiple modes specified");
99                Exit_Program (E_Fatal);
100             end if;
101
102          elsif Arg'Length > 9 and then Arg (1 .. 9) = "--delete=" then
103             if Mode = None then
104                Mode := Delete;
105                Lib_Dir := new String'(Arg (10 .. Arg'Last));
106             else
107                Put_Line (Standard_Error, "Error: Multiple modes specified");
108                Exit_Program (E_Fatal);
109             end if;
110
111          elsif Arg'Length > 9 and then Arg (1 .. 9) = "--config=" then
112             if ADC_File /= null then
113                Put_Line (Standard_Error,
114                          "Error: Multiple gnat.adc files specified");
115                Exit_Program (E_Fatal);
116             end if;
117
118             ADC_File := new String'(Arg (10 .. Arg'Last));
119
120          else
121             Put_Line (Standard_Error, "Error: Unrecognized option: " & Arg);
122             Exit_Program (E_Fatal);
123
124          end if;
125       end Process_One_Arg;
126
127       Next_Arg := Next_Arg + 1;
128    end loop;
129
130    case Mode is
131       when Create =>
132
133          --  Validate arguments
134
135          if Lib_Dir = null then
136             Put_Line (Standard_Error, "Error: No library directory specified");
137             Exit_Program (E_Fatal);
138          end if;
139
140          if Is_Directory (Lib_Dir.all) then
141             Put_Line (Standard_Error,
142                       "Error:" & Lib_Dir.all & " already exists");
143             Exit_Program (E_Fatal);
144          end if;
145
146          if ADC_File = null then
147             Put_Line (Standard_Error,
148                       "Error: No configuration file specified");
149             Exit_Program (E_Fatal);
150          end if;
151
152          if not Is_Regular_File (ADC_File.all) then
153             Put_Line (Standard_Error,
154                       "Error: " & ADC_File.all & " doesn't exist");
155             Exit_Program (E_Fatal);
156          end if;
157
158          Create_Block : declare
159             Success        : Boolean;
160             Make_Args      : Argument_List (1 .. 9);
161             C_Lib_Dir      : String := Lib_Dir.all & ASCII.Nul;
162             C_ADC_File     : String := ADC_File.all & ASCII.Nul;
163             F_ADC_File     : String (1 .. max_path_len);
164             F_ADC_File_Len : Integer := max_path_len;
165             Include_Dirs   : Integer;
166             Object_Dirs    : Integer;
167             Include_Dir    : array (Integer range 1 .. 256) of String_Access;
168             Object_Dir     : array (Integer range 1 .. 256) of String_Access;
169             Include_Dir_Name : String_Access;
170             Object_Dir_Name  : String_Access;
171
172          begin
173             --  Create the new top level library directory
174
175             if not Is_Directory (Lib_Dir.all) then
176                Create_Directory (C_Lib_Dir'Address, 8#755#);
177             end if;
178
179             full_name (C_ADC_File'Address, F_ADC_File'Address);
180
181             for I in 1 .. max_path_len loop
182                if F_ADC_File (I) = ASCII.Nul then
183                   F_ADC_File_Len := I - 1;
184                   exit;
185                end if;
186             end loop;
187
188             --
189             --  Make a list of the default library source and object
190             --  directories.  Usually only one, except on VMS where
191             --  there are two.
192             --
193             Include_Dirs := 0;
194             Include_Dir_Name := new String'(Include_Dir_Default_Prefix);
195             Get_Next_Dir_In_Path_Init (String_Access (Include_Dir_Name));
196
197             loop
198                declare
199                   Dir : String_Access := String_Access
200                     (Get_Next_Dir_In_Path (String_Access (Include_Dir_Name)));
201                begin
202                   exit when Dir = null;
203                   Include_Dirs := Include_Dirs + 1;
204                   Include_Dir (Include_Dirs)
205                     := String_Access (Normalize_Directory_Name (Dir.all));
206                end;
207             end loop;
208
209             Object_Dirs := 0;
210             Object_Dir_Name := new String'(Object_Dir_Default_Prefix);
211             Get_Next_Dir_In_Path_Init (String_Access (Object_Dir_Name));
212
213             loop
214                declare
215                   Dir : String_Access := String_Access
216                     (Get_Next_Dir_In_Path (String_Access (Object_Dir_Name)));
217                begin
218                   exit when Dir = null;
219                   Object_Dirs := Object_Dirs + 1;
220                   Object_Dir (Object_Dirs)
221                     := String_Access (Normalize_Directory_Name (Dir.all));
222                end;
223             end loop;
224
225             --  "Make" an alternate sublibrary for each default sublibrary.
226
227             for Dirs in 1 .. Object_Dirs loop
228
229                Make_Args (1) :=
230                  new String'("-C");
231
232                Make_Args (2) :=
233                  new String'(Lib_Dir.all);
234
235                --  Resolve /gnu on VMS by converting to host format and then
236                --  convert resolved path back to canonical format for the
237                --  make program. This fixes the problem that can occur when
238                --  GNU: is a search path pointing to multiple versions of GNAT.
239
240                Make_Args (3) :=
241                  new String'("ADA_INCLUDE_PATH=" &
242                    To_Canonical_Dir_Spec
243                      (To_Host_Dir_Spec
244                        (Include_Dir (Dirs).all, True).all, True).all);
245
246                Make_Args (4) :=
247                  new String'("ADA_OBJECTS_PATH=" &
248                    To_Canonical_Dir_Spec
249                      (To_Host_Dir_Spec
250                        (Object_Dir (Dirs).all, True).all, True).all);
251
252                Make_Args (5) :=
253                  new String'("GNAT_ADC_FILE="
254                              & F_ADC_File (1 .. F_ADC_File_Len));
255
256                Make_Args (6) :=
257                  new String'("LIBRARY_VERSION=" & '"' & Library_Version & '"');
258
259                Make_Args (7) :=
260                  new String'("-f");
261
262                Make_Args (8) :=
263                  new String'(Object_Dir (Dirs).all & "Makefile.lib");
264
265                Make_Args (9) :=
266                  new String'("create");
267
268                Make_Path := Locate_Exec_On_Path (Make);
269                Put (Make);
270
271                for I in 1 .. Make_Args'Last loop
272                   Put (" ");
273                   Put (Make_Args (I).all);
274                end loop;
275
276                New_Line;
277                Spawn (Make_Path.all, Make_Args, Success);
278                if not Success then
279                   Put_Line (Standard_Error, "Error: Make failed");
280                   Exit_Program (E_Fatal);
281                end if;
282             end loop;
283          end Create_Block;
284
285       when Set =>
286
287          --  Validate arguments.
288
289          if Lib_Dir = null then
290             Put_Line (Standard_Error,
291                       "Error: No library directory specified");
292             Exit_Program (E_Fatal);
293          end if;
294
295          if not Is_Directory (Lib_Dir.all) then
296             Put_Line (Standard_Error,
297                       "Error: " & Lib_Dir.all & " doesn't exist");
298             Exit_Program (E_Fatal);
299          end if;
300
301          if ADC_File = null then
302             Put_Line (Standard_Error,
303                       "Error: No configuration file specified");
304             Exit_Program (E_Fatal);
305          end if;
306
307          if not Is_Regular_File (ADC_File.all) then
308             Put_Line (Standard_Error,
309                       "Error: " & ADC_File.all & " doesn't exist");
310             Exit_Program (E_Fatal);
311          end if;
312
313          --  Give instructions.
314
315          Put_Line ("Copy the contents of "
316            & ADC_File.all & " into your GNAT.ADC file");
317          Put_Line ("and use GNAT Make qualifier /OBJECT_SEARCH=("
318            & To_Host_Dir_Spec
319                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/declib", False).all
320            & ","
321            & To_Host_Dir_Spec
322                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/adalib", False).all
323            & ")");
324          Put_Line ("or else define ADA_OBJECTS_PATH as " & '"'
325            & To_Host_Dir_Spec
326                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/declib", False).all
327            & ','
328            & To_Host_Dir_Spec
329                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/adalib", False).all
330            & '"');
331
332       when Delete =>
333
334          --  Give instructions.
335
336          Put_Line ("GNAT Librarian DELETE not yet implemented.");
337          Put_Line ("Use appropriate system tools to remove library");
338
339       when None =>
340          Put_Line (Standard_Error,
341                    "Error: No mode (create|set|delete) specified");
342          Exit_Program (E_Fatal);
343
344    end case;
345
346 end GnatLbr;