OSDN Git Service

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