OSDN Git Service

./:
[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-2005, 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,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, 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_Static_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, "decc$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 : constant String := Argument (Next_Arg);
81
82       begin
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 := new String'(Include_Dir_Default_Prefix);
194             Get_Next_Dir_In_Path_Init (Include_Dir_Name);
195
196             loop
197                declare
198                   Dir : constant String_Access := String_Access
199                     (Get_Next_Dir_In_Path (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 := new String'(Object_Dir_Default_Prefix);
210             Get_Next_Dir_In_Path_Init (Object_Dir_Name);
211
212             loop
213                declare
214                   Dir : constant String_Access :=
215                           String_Access
216                             (Get_Next_Dir_In_Path (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                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=" & '"' &
257                              Verbose_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 J in 1 .. Make_Args'Last loop
272                   Put (" ");
273                   Put (Make_Args (J).all);
274                end loop;
275
276                New_Line;
277                Spawn (Make_Path.all, Make_Args, Success);
278
279                if not Success then
280                   Put_Line (Standard_Error, "Error: Make failed");
281                   Exit_Program (E_Fatal);
282                end if;
283             end loop;
284          end Create_Block;
285
286       when Set =>
287
288          --  Validate arguments
289
290          if Lib_Dir = null then
291             Put_Line (Standard_Error,
292                       "Error: No library directory specified");
293             Exit_Program (E_Fatal);
294          end if;
295
296          if not Is_Directory (Lib_Dir.all) then
297             Put_Line (Standard_Error,
298                       "Error: " & Lib_Dir.all & " doesn't exist");
299             Exit_Program (E_Fatal);
300          end if;
301
302          if ADC_File = null then
303             Put_Line (Standard_Error,
304                       "Error: No configuration file specified");
305             Exit_Program (E_Fatal);
306          end if;
307
308          if not Is_Regular_File (ADC_File.all) then
309             Put_Line (Standard_Error,
310                       "Error: " & ADC_File.all & " doesn't exist");
311             Exit_Program (E_Fatal);
312          end if;
313
314          --  Give instructions
315
316          Put_Line ("Copy the contents of "
317            & ADC_File.all & " into your GNAT.ADC file");
318          Put_Line ("and use GNAT Make qualifier /OBJECT_SEARCH=("
319            & To_Host_Dir_Spec
320                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/declib", False).all
321            & ","
322            & To_Host_Dir_Spec
323                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/adalib", False).all
324            & ")");
325          Put_Line ("or else define ADA_OBJECTS_PATH as " & '"'
326            & To_Host_Dir_Spec
327                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/declib", False).all
328            & ','
329            & To_Host_Dir_Spec
330                (Lib_Dir (Lib_Dir'First .. Lib_Dir'Last) & "/adalib", False).all
331            & '"');
332
333       when Delete =>
334
335          --  Give instructions
336
337          Put_Line ("GNAT Librarian DELETE not yet implemented.");
338          Put_Line ("Use appropriate system tools to remove library");
339
340       when None =>
341          Put_Line (Standard_Error,
342                    "Error: No mode (create|set|delete) specified");
343          Exit_Program (E_Fatal);
344
345    end case;
346
347 end GnatLbr;