OSDN Git Service

2005-06-15 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / ada / mlib-tgt-vms-alpha.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             M L I B . T G T                              --
6 --                           (Alpha VMS Version)                            --
7 --                                                                          --
8 --                                 B o d y                                  --
9 --                                                                          --
10 --          Copyright (C) 2003-2005, Free Software Foundation, Inc.         --
11 --                                                                          --
12 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
13 -- terms of the  GNU General Public License as published  by the Free Soft- --
14 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
15 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
18 -- for  more details.  You should have  received  a copy of the GNU General --
19 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
20 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
21 -- MA 02111-1307, USA.                                                      --
22 --                                                                          --
23 -- GNAT was originally developed  by the GNAT team at  New York University. --
24 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
25 --                                                                          --
26 ------------------------------------------------------------------------------
27
28 --  This is the Alpha VMS version of the body
29
30 with Ada.Characters.Handling; use Ada.Characters.Handling;
31
32 with GNAT.Directory_Operations; use GNAT.Directory_Operations;
33 with GNAT.OS_Lib;               use GNAT.OS_Lib;
34
35 with MLib.Fil;
36 with MLib.Utl;
37 with Namet;    use Namet;
38 with Opt;      use Opt;
39 with Output;   use Output;
40 with Prj.Com;
41
42 with System;           use System;
43 with System.Case_Util; use System.Case_Util;
44 with System.CRTL;      use System.CRTL;
45
46 package body MLib.Tgt is
47
48    use GNAT;
49
50    Empty_Argument_List : aliased Argument_List := (1 .. 0 => null);
51    Additional_Objects  : Argument_List_Access := Empty_Argument_List'Access;
52    --  Used to add the generated auto-init object files for auto-initializing
53    --  stand-alone libraries.
54
55    Macro_Name : constant String := "mcr gnu:[bin]gcc -c -x assembler";
56    --  The name of the command to invoke the macro-assembler
57
58    VMS_Options : Argument_List := (1 .. 1 => null);
59
60    Gnatsym_Name : constant String := "gnatsym";
61
62    Gnatsym_Path : String_Access;
63
64    Arguments : Argument_List_Access := null;
65    Last_Argument : Natural := 0;
66
67    Success : Boolean := False;
68
69    Shared_Libgcc : aliased String := "-shared-libgcc";
70
71    No_Shared_Libgcc_Switch : aliased Argument_List := (1 .. 0 => null);
72    Shared_Libgcc_Switch    : aliased Argument_List :=
73                                (1 => Shared_Libgcc'Access);
74    Link_With_Shared_Libgcc : Argument_List_Access :=
75                                No_Shared_Libgcc_Switch'Access;
76
77    ---------------------
78    -- Archive_Builder --
79    ---------------------
80
81    function Archive_Builder return String is
82    begin
83       return "ar";
84    end Archive_Builder;
85
86    -----------------------------
87    -- Archive_Builder_Options --
88    -----------------------------
89
90    function Archive_Builder_Options return String_List_Access is
91    begin
92       return new String_List'(1 => new String'("cr"));
93    end Archive_Builder_Options;
94
95    -----------------
96    -- Archive_Ext --
97    -----------------
98
99    function Archive_Ext return String is
100    begin
101       return "olb";
102    end Archive_Ext;
103
104    ---------------------
105    -- Archive_Indexer --
106    ---------------------
107
108    function Archive_Indexer return String is
109    begin
110       return "ranlib";
111    end Archive_Indexer;
112
113    -----------------------------
114    -- Archive_Indexer_Options --
115    -----------------------------
116
117    function Archive_Indexer_Options return String_List_Access is
118    begin
119       return new String_List (1 .. 0);
120    end Archive_Indexer_Options;
121
122    ---------------------------
123    -- Build_Dynamic_Library --
124    ---------------------------
125
126    procedure Build_Dynamic_Library
127      (Ofiles       : Argument_List;
128       Foreign      : Argument_List;
129       Afiles       : Argument_List;
130       Options      : Argument_List;
131       Options_2    : Argument_List;
132       Interfaces   : Argument_List;
133       Lib_Filename : String;
134       Lib_Dir      : String;
135       Symbol_Data  : Symbol_Record;
136       Driver_Name  : Name_Id := No_Name;
137       Lib_Version  : String  := "";
138       Auto_Init    : Boolean := False)
139    is
140       pragma Unreferenced (Foreign);
141       pragma Unreferenced (Afiles);
142
143       Lib_File : constant String :=
144                    Lib_Dir & Directory_Separator & "lib" &
145                    Fil.Ext_To (Lib_Filename, DLL_Ext);
146
147       Opts      : Argument_List := Options;
148       Last_Opt  : Natural       := Opts'Last;
149       Opts2     : Argument_List (Options'Range);
150       Last_Opt2 : Natural       := Opts2'First - 1;
151
152       Inter : constant Argument_List := Interfaces;
153
154       function Is_Interface (Obj_File : String) return Boolean;
155       --  For a Stand-Alone Library, returns True if Obj_File is the object
156       --  file name of an interface of the SAL. For other libraries, always
157       --  return True.
158
159       function Option_File_Name return String;
160       --  Returns Symbol_File, if not empty. Otherwise, returns "symvec.opt"
161
162       function Version_String return String;
163       --  Returns Lib_Version if not empty and if Symbol_Data.Symbol_Policy is
164       --  not Autonomous, otherwise returns "".
165       --  When Symbol_Data.Symbol_Policy is Autonomous, fails gnatmake if
166       --  Lib_Version is not the image of a positive number.
167
168       ------------------
169       -- Is_Interface --
170       ------------------
171
172       function Is_Interface (Obj_File : String) return Boolean is
173          ALI : constant String :=
174                  Fil.Ext_To
175                   (Filename => To_Lower (Base_Name (Obj_File)),
176                    New_Ext  => "ali");
177
178       begin
179          if Inter'Length = 0 then
180             return True;
181
182          elsif ALI'Length > 2 and then
183                ALI (ALI'First .. ALI'First + 1) = "b$"
184          then
185             return True;
186
187          else
188             for J in Inter'Range loop
189                if Inter (J).all = ALI then
190                   return True;
191                end if;
192             end loop;
193
194             return False;
195          end if;
196       end Is_Interface;
197
198       ----------------------
199       -- Option_File_Name --
200       ----------------------
201
202       function Option_File_Name return String is
203       begin
204          if Symbol_Data.Symbol_File = No_Name then
205             return "symvec.opt";
206          else
207             Get_Name_String (Symbol_Data.Symbol_File);
208             To_Lower (Name_Buffer (1 .. Name_Len));
209             return Name_Buffer (1 .. Name_Len);
210          end if;
211       end Option_File_Name;
212
213       --------------------
214       -- Version_String --
215       --------------------
216
217       function Version_String return String is
218          Version : Integer := 0;
219       begin
220          if Lib_Version = ""
221            or else Symbol_Data.Symbol_Policy /= Autonomous
222          then
223             return "";
224
225          else
226             begin
227                Version := Integer'Value (Lib_Version);
228
229                if Version <= 0 then
230                   raise Constraint_Error;
231                end if;
232
233                return Lib_Version;
234
235             exception
236                when Constraint_Error =>
237                   Fail ("illegal version """, Lib_Version,
238                         """ (on VMS version must be a positive number)");
239                   return "";
240             end;
241          end if;
242       end Version_String;
243
244       Opt_File_Name  : constant String := Option_File_Name;
245       Version        : constant String := Version_String;
246       For_Linker_Opt : String_Access;
247
248    --  Start of processing for Build_Dynamic_Library
249
250    begin
251       --  Invoke gcc with -shared-libgcc, but only for GCC 3 or higher
252
253       if GCC_Version >= 3 then
254          Link_With_Shared_Libgcc := Shared_Libgcc_Switch'Access;
255       else
256          Link_With_Shared_Libgcc := No_Shared_Libgcc_Switch'Access;
257       end if;
258
259       --  If option file name does not ends with ".opt", append "/OPTIONS"
260       --  to its specification for the VMS linker.
261
262       if Opt_File_Name'Length > 4
263         and then
264           Opt_File_Name (Opt_File_Name'Last - 3 .. Opt_File_Name'Last) = ".opt"
265       then
266          For_Linker_Opt := new String'("--for-linker=" & Opt_File_Name);
267       else
268          For_Linker_Opt :=
269            new String'("--for-linker=" & Opt_File_Name & "/OPTIONS");
270       end if;
271
272       VMS_Options (VMS_Options'First) := For_Linker_Opt;
273
274       for J in Inter'Range loop
275          To_Lower (Inter (J).all);
276       end loop;
277
278       --  "gnatsym" is necessary for building the option file
279
280       if Gnatsym_Path = null then
281          Gnatsym_Path := OS_Lib.Locate_Exec_On_Path (Gnatsym_Name);
282
283          if Gnatsym_Path = null then
284             Fail (Gnatsym_Name, " not found in path");
285          end if;
286       end if;
287
288       --  For auto-initialization of a stand-alone library, we create
289       --  a macro-assembly file and we invoke the macro-assembler.
290
291       if Auto_Init then
292          declare
293             Macro_File_Name : constant String := Lib_Filename & "$init.asm";
294             Macro_File      : File_Descriptor;
295             Init_Proc       : String := Lib_Filename & "INIT";
296             Popen_Result    : System.Address;
297             Pclose_Result   : Integer;
298             Len             : Natural;
299             OK              : Boolean := True;
300
301             command  : constant String :=
302                          Macro_Name & " " & Macro_File_Name & ASCII.NUL;
303             --  The command to invoke the assembler on the generated auto-init
304             --  assembly file.
305
306             mode : constant String := "r" & ASCII.NUL;
307             --  The mode for the invocation of Popen
308
309          begin
310             To_Upper (Init_Proc);
311
312             if Verbose_Mode then
313                Write_Str ("Creating auto-init assembly file """);
314                Write_Str (Macro_File_Name);
315                Write_Line ("""");
316             end if;
317
318             --  Create and write the auto-init assembly file
319
320             declare
321                First_Line : constant String :=
322                               ASCII.HT & ".section LIB$INITIALIZE,GBL,NOWRT" &
323                ASCII.LF;
324                Second_Line : constant String :=
325                                ASCII.HT & ".long " & Init_Proc & ASCII.LF;
326                --  First and second lines of the auto-init assembly file
327
328             begin
329                Macro_File := Create_File (Macro_File_Name, Text);
330                OK := Macro_File /= Invalid_FD;
331
332                if OK then
333                   Len := Write
334                     (Macro_File, First_Line (First_Line'First)'Address,
335                      First_Line'Length);
336                   OK := Len = First_Line'Length;
337                end if;
338
339                if OK then
340                   Len := Write
341                     (Macro_File, Second_Line (Second_Line'First)'Address,
342                      Second_Line'Length);
343                   OK := Len = Second_Line'Length;
344                end if;
345
346                if OK then
347                   Close (Macro_File, OK);
348                end if;
349
350                if not OK then
351                   Fail ("creation of auto-init assembly file """,
352                         Macro_File_Name, """ failed");
353                end if;
354             end;
355
356             --  Invoke the macro-assembler
357
358             if Verbose_Mode then
359                Write_Str ("Assembling auto-init assembly file """);
360                Write_Str (Macro_File_Name);
361                Write_Line ("""");
362             end if;
363
364             Popen_Result := popen (command (command'First)'Address,
365                                    mode (mode'First)'Address);
366
367             if Popen_Result = Null_Address then
368                Fail ("assembly of auto-init assembly file """,
369                      Macro_File_Name, """ failed");
370             end if;
371
372             --  Wait for the end of execution of the macro-assembler
373
374             Pclose_Result := pclose (Popen_Result);
375
376             if Pclose_Result < 0 then
377                Fail ("assembly of auto init assembly file """,
378                      Macro_File_Name, """ failed");
379             end if;
380
381             --  Add the generated object file to the list of objects to be
382             --  included in the library.
383
384             Additional_Objects :=
385               new Argument_List'
386                 (1 => new String'(Lib_Filename & "$init.obj"));
387          end;
388       end if;
389
390       --  Allocate the argument list and put the symbol file name, the
391       --  reference (if any) and the policy (if not autonomous).
392
393       Arguments := new Argument_List (1 .. Ofiles'Length + 8);
394
395       Last_Argument := 0;
396
397       --  Verbosity
398
399       if Verbose_Mode then
400          Last_Argument := Last_Argument + 1;
401          Arguments (Last_Argument) := new String'("-v");
402       end if;
403
404       --  Version number (major ID)
405
406       if Lib_Version /= "" then
407          Last_Argument := Last_Argument + 1;
408          Arguments (Last_Argument) := new String'("-V");
409          Last_Argument := Last_Argument + 1;
410          Arguments (Last_Argument) := new String'(Version);
411       end if;
412
413       --  Symbol file
414
415       Last_Argument := Last_Argument + 1;
416       Arguments (Last_Argument) := new String'("-s");
417       Last_Argument := Last_Argument + 1;
418       Arguments (Last_Argument) := new String'(Opt_File_Name);
419
420       --  Reference Symbol File
421
422       if Symbol_Data.Reference /= No_Name then
423          Last_Argument := Last_Argument + 1;
424          Arguments (Last_Argument) := new String'("-r");
425          Last_Argument := Last_Argument + 1;
426          Arguments (Last_Argument) :=
427            new String'(Get_Name_String (Symbol_Data.Reference));
428       end if;
429
430       --  Policy
431
432       case Symbol_Data.Symbol_Policy is
433          when Autonomous =>
434             null;
435
436          when Compliant =>
437             Last_Argument := Last_Argument + 1;
438             Arguments (Last_Argument) := new String'("-c");
439
440          when Controlled =>
441             Last_Argument := Last_Argument + 1;
442             Arguments (Last_Argument) := new String'("-C");
443
444          when Restricted =>
445             Last_Argument := Last_Argument + 1;
446             Arguments (Last_Argument) := new String'("-R");
447       end case;
448
449       --  Add each relevant object file
450
451       for Index in Ofiles'Range loop
452          if Is_Interface (Ofiles (Index).all) then
453             Last_Argument := Last_Argument + 1;
454             Arguments (Last_Argument) := new String'(Ofiles (Index).all);
455          end if;
456       end loop;
457
458       --  Spawn gnatsym
459
460       Spawn (Program_Name => Gnatsym_Path.all,
461              Args         => Arguments (1 .. Last_Argument),
462              Success      => Success);
463
464       if not Success then
465          Fail ("unable to create symbol file for library """,
466                Lib_Filename, """");
467       end if;
468
469       Free (Arguments);
470
471       --  Move all the -l switches from Opts to Opts2
472
473       declare
474          Index : Natural := Opts'First;
475          Opt   : String_Access;
476
477       begin
478          while Index <= Last_Opt loop
479             Opt := Opts (Index);
480
481             if Opt'Length > 2 and then
482               Opt (Opt'First .. Opt'First + 1) = "-l"
483             then
484                if Index < Last_Opt then
485                   Opts (Index .. Last_Opt - 1) :=
486                     Opts (Index + 1 .. Last_Opt);
487                end if;
488
489                Last_Opt := Last_Opt - 1;
490
491                Last_Opt2 := Last_Opt2 + 1;
492                Opts2 (Last_Opt2) := Opt;
493
494             else
495                Index := Index + 1;
496             end if;
497          end loop;
498       end;
499
500       --  Invoke gcc to build the library
501
502       Utl.Gcc
503         (Output_File => Lib_File,
504          Objects     => Ofiles & Additional_Objects.all,
505          Options     => VMS_Options,
506          Options_2   => Link_With_Shared_Libgcc.all &
507                         Opts (Opts'First .. Last_Opt) &
508                         Opts2 (Opts2'First .. Last_Opt2) & Options_2,
509          Driver_Name => Driver_Name);
510
511       --  The auto-init object file need to be deleted, so that it will not
512       --  be included in the library as a regular object file, otherwise
513       --  it will be included twice when the library will be built next
514       --  time, which may lead to errors.
515
516       if Auto_Init then
517          declare
518             Auto_Init_Object_File_Name : constant String :=
519                                            Lib_Filename & "$init.obj";
520             Disregard : Boolean;
521
522          begin
523             if Verbose_Mode then
524                Write_Str ("deleting auto-init object file """);
525                Write_Str (Auto_Init_Object_File_Name);
526                Write_Line ("""");
527             end if;
528
529             Delete_File (Auto_Init_Object_File_Name, Success => Disregard);
530          end;
531       end if;
532    end Build_Dynamic_Library;
533
534    -------------
535    -- DLL_Ext --
536    -------------
537
538    function DLL_Ext return String is
539    begin
540       return "exe";
541    end DLL_Ext;
542
543    --------------------
544    -- Dynamic_Option --
545    --------------------
546
547    function Dynamic_Option return String is
548    begin
549       return "-shared";
550    end Dynamic_Option;
551
552    -------------------
553    -- Is_Object_Ext --
554    -------------------
555
556    function Is_Object_Ext (Ext : String) return Boolean is
557    begin
558       return Ext = ".obj";
559    end Is_Object_Ext;
560
561    --------------
562    -- Is_C_Ext --
563    --------------
564
565    function Is_C_Ext (Ext : String) return Boolean is
566    begin
567       return Ext = ".c";
568    end Is_C_Ext;
569
570    --------------------
571    -- Is_Archive_Ext --
572    --------------------
573
574    function Is_Archive_Ext (Ext : String) return Boolean is
575    begin
576       return Ext = ".olb" or else Ext = ".exe";
577    end Is_Archive_Ext;
578
579    -------------
580    -- Libgnat --
581    -------------
582
583    function Libgnat return String is
584       Libgnat_A : constant String := "libgnat.a";
585       Libgnat_Olb : constant String := "libgnat.olb";
586
587    begin
588       Name_Len := Libgnat_A'Length;
589       Name_Buffer (1 .. Name_Len) := Libgnat_A;
590
591       if Osint.Find_File (Name_Enter, Osint.Library) /= No_File then
592          return Libgnat_A;
593
594       else
595          return Libgnat_Olb;
596       end if;
597    end Libgnat;
598
599    ------------------------
600    -- Library_Exists_For --
601    ------------------------
602
603    function Library_Exists_For
604      (Project : Project_Id; In_Tree : Project_Tree_Ref) return Boolean
605    is
606    begin
607       if not In_Tree.Projects.Table (Project).Library then
608          Fail ("INTERNAL ERROR: Library_Exists_For called " &
609                "for non library project");
610          return False;
611
612       else
613          declare
614             Lib_Dir : constant String :=
615               Get_Name_String
616                 (In_Tree.Projects.Table (Project).Library_Dir);
617             Lib_Name : constant String :=
618               Get_Name_String
619                 (In_Tree.Projects.Table (Project).Library_Name);
620
621          begin
622             if In_Tree.Projects.Table (Project).Library_Kind =
623               Static
624             then
625                return Is_Regular_File
626                  (Lib_Dir & Directory_Separator & "lib" &
627                   Fil.Ext_To (Lib_Name, Archive_Ext));
628
629             else
630                return Is_Regular_File
631                  (Lib_Dir & Directory_Separator & "lib" &
632                   Fil.Ext_To (Lib_Name, DLL_Ext));
633             end if;
634          end;
635       end if;
636    end Library_Exists_For;
637
638    ---------------------------
639    -- Library_File_Name_For --
640    ---------------------------
641
642    function Library_File_Name_For
643      (Project : Project_Id;
644       In_Tree : Project_Tree_Ref) return Name_Id
645    is
646    begin
647       if not In_Tree.Projects.Table (Project).Library then
648          Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
649                        "for non library project");
650          return No_Name;
651
652       else
653          declare
654             Lib_Name : constant String :=
655               Get_Name_String
656                 (In_Tree.Projects.Table (Project).Library_Name);
657
658          begin
659             Name_Len := 3;
660             Name_Buffer (1 .. Name_Len) := "lib";
661
662             if In_Tree.Projects.Table (Project).Library_Kind =
663               Static
664             then
665                Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
666
667             else
668                Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
669             end if;
670
671             return Name_Find;
672          end;
673       end if;
674    end Library_File_Name_For;
675
676    ----------------
677    -- Object_Ext --
678    ----------------
679
680    function Object_Ext return String is
681    begin
682       return "obj";
683    end Object_Ext;
684
685    ----------------
686    -- PIC_Option --
687    ----------------
688
689    function PIC_Option return String is
690    begin
691       return "";
692    end PIC_Option;
693
694    -----------------------------------------------
695    -- Standalone_Library_Auto_Init_Is_Supported --
696    -----------------------------------------------
697
698    function Standalone_Library_Auto_Init_Is_Supported return Boolean is
699    begin
700       return True;
701    end Standalone_Library_Auto_Init_Is_Supported;
702
703    ---------------------------
704    -- Support_For_Libraries --
705    ---------------------------
706
707    function Support_For_Libraries return Library_Support is
708    begin
709       return Full;
710    end Support_For_Libraries;
711
712 end MLib.Tgt;