OSDN Git Service

2010-10-08 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / mlib-prj.adb
index 4b82ffa..8c0d4e1 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---              Copyright (C) 2001-2004, Ada Core Technologies, Inc.        --
+--                     Copyright (C) 2001-2010, AdaCore                     --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 
 with ALI;      use ALI;
 with Gnatvsn;  use Gnatvsn;
-with Hostparm;
 with MLib.Fil; use MLib.Fil;
 with MLib.Tgt; use MLib.Tgt;
 with MLib.Utl; use MLib.Utl;
-with Namet;    use Namet;
 with Opt;
-with Osint;    use Osint;
 with Output;   use Output;
 with Prj.Com;  use Prj.Com;
 with Prj.Env;  use Prj.Env;
@@ -41,13 +37,14 @@ with Sinput.P;
 with Snames;   use Snames;
 with Switch;   use Switch;
 with Table;
+with Targparm; use Targparm;
+with Tempdir;
 with Types;    use Types;
 
 with Ada.Characters.Handling;
 
 with GNAT.Directory_Operations; use GNAT.Directory_Operations;
 with GNAT.HTable;
-with GNAT.OS_Lib;               use GNAT.OS_Lib;
 with Interfaces.C_Streams;      use Interfaces.C_Streams;
 with System;                    use System;
 with System.Case_Util;          use System.Case_Util;
@@ -58,21 +55,22 @@ package body MLib.Prj is
    pragma Import (C, Prj_Add_Obj_Files, "__gnat_prj_add_obj_files");
    Add_Object_Files : constant Boolean := Prj_Add_Obj_Files /= 0;
    --  Indicates if object files in pragmas Linker_Options (found in the
-   --  binder generated file) should be taken when linking aq stand-alone
-   --  library.
-   --  False for Windows, True for other platforms.
+   --  binder generated file) should be taken when linking a stand-alone
+   --  library. False for Windows, True for other platforms.
 
    ALI_Suffix : constant String := ".ali";
-   B_Start    : String := "b~";
 
-   S_Osinte_Ads : Name_Id := No_Name;
+   B_Start : String_Ptr := new String'("b~");
+   --  Prefix of bind file, changed to b__ for VMS
+
+   S_Osinte_Ads : File_Name_Type := No_File;
    --  Name_Id for "s-osinte.ads"
 
-   S_Dec_Ads : Name_Id := No_Name;
+   S_Dec_Ads : File_Name_Type := No_File;
    --  Name_Id for "dec.ads"
 
-   No_Argument_List : aliased String_List := (1 .. 0 => null);
-   No_Argument      : constant String_List_Access := No_Argument_List'Access;
+   G_Trasym_Ads : File_Name_Type := No_File;
+   --  Name_Id for "g-trasym.ads"
 
    Arguments : String_List_Access := No_Argument;
    --  Used to accumulate arguments for the invocation of gnatbind and of
@@ -93,6 +91,8 @@ package body MLib.Prj is
    Compile_Switch_String : aliased String := "-c";
    Compile_Switch : constant String_Access := Compile_Switch_String'Access;
 
+   Auto_Initialize : constant String := "-a";
+
    --  List of objects to put inside the library
 
    Object_Files : Argument_List_Access;
@@ -106,25 +106,13 @@ package body MLib.Prj is
       Table_Increment      => 100);
 
    package Objects_Htable is new GNAT.HTable.Simple_HTable
-     (Header_Num => Com.Header_Num,
+     (Header_Num => Header_Num,
       Element    => Boolean,
       No_Element => False,
       Key        => Name_Id,
-      Hash       => Com.Hash,
+      Hash       => Hash,
       Equal      => "=");
 
-   --  List of non-Ada object files
-
-   Foreign_Objects : Argument_List_Access;
-
-   package Foreigns is new Table.Table
-     (Table_Name           => "Mlib.Prj.Foreigns",
-      Table_Component_Type => String_Access,
-      Table_Index_Type     => Natural,
-      Table_Low_Bound      => 1,
-      Table_Initial        => 20,
-      Table_Increment      => 100);
-
    --  List of ALI files
 
    Ali_Files : Argument_List_Access;
@@ -137,7 +125,7 @@ package body MLib.Prj is
       Table_Initial        => 50,
       Table_Increment      => 100);
 
-   --  List of options set in the command line.
+   --  List of options set in the command line
 
    Options : Argument_List_Access;
 
@@ -152,45 +140,45 @@ package body MLib.Prj is
    --  All the ALI file in the library
 
    package Library_ALIs is new GNAT.HTable.Simple_HTable
-     (Header_Num => Com.Header_Num,
+     (Header_Num => Header_Num,
       Element    => Boolean,
       No_Element => False,
-      Key        => Name_Id,
-      Hash       => Com.Hash,
+      Key        => File_Name_Type,
+      Hash       => Hash,
       Equal      => "=");
 
    --  The ALI files in the interface sets
 
    package Interface_ALIs is new GNAT.HTable.Simple_HTable
-     (Header_Num => Com.Header_Num,
+     (Header_Num => Header_Num,
       Element    => Boolean,
       No_Element => False,
-      Key        => Name_Id,
-      Hash       => Com.Hash,
+      Key        => File_Name_Type,
+      Hash       => Hash,
       Equal      => "=");
 
    --  The ALI files that have been processed to check if the corresponding
    --  library unit is in the interface set.
 
    package Processed_ALIs is new GNAT.HTable.Simple_HTable
-     (Header_Num => Com.Header_Num,
+     (Header_Num => Header_Num,
       Element    => Boolean,
       No_Element => False,
-      Key        => Name_Id,
-      Hash       => Com.Hash,
+      Key        => File_Name_Type,
+      Hash       => Hash,
       Equal      => "=");
 
-   --  The projects imported directly or indirectly.
+   --  The projects imported directly or indirectly
 
    package Processed_Projects is new GNAT.HTable.Simple_HTable
-     (Header_Num => Com.Header_Num,
+     (Header_Num => Header_Num,
       Element    => Boolean,
       No_Element => False,
       Key        => Name_Id,
-      Hash       => Com.Hash,
+      Hash       => Hash,
       Equal      => "=");
 
-   --  The library projects imported directly or indirectly.
+   --  The library projects imported directly or indirectly
 
    package Library_Projs is new Table.Table (
      Table_Component_Type => Project_Id,
@@ -203,39 +191,43 @@ package body MLib.Prj is
    type Build_Mode_State is (None, Static, Dynamic, Relocatable);
 
    procedure Add_Argument (S : String);
-   --  Add one argument to the array Arguments.
-   --  If Arguments is full, double its size.
+   --  Add one argument to Arguments array, if array is full, double its size
 
    function ALI_File_Name (Source : String) return String;
-   --  Return the ALI file name corresponding to a source.
+   --  Return the ALI file name corresponding to a source
 
    procedure Check (Filename : String);
-   --  Check if filename is a regular file. Fail if it is not.
+   --  Check if filename is a regular file. Fail if it is not
 
    procedure Check_Context;
    --  Check each object files in table Object_Files
    --  Fail if any of them is not a regular file
 
-   procedure Clean (Directory : Name_Id);
-   --  Attempt to delete all files in Directory, but not subdirectories
-
    procedure Copy_Interface_Sources
      (For_Project : Project_Id;
+      In_Tree     : Project_Tree_Ref;
       Interfaces  : Argument_List;
-      To_Dir      : Name_Id);
+      To_Dir      : Path_Name_Type);
    --  Copy the interface sources of a SAL to directory To_Dir
 
    procedure Display (Executable : String);
    --  Display invocation of gnatbind and of the compiler with the arguments
    --  in Arguments, except when Quiet_Output is True.
 
+   function Index (S, Pattern : String) return Natural;
+   --  Return the last occurrence of Pattern in S, or 0 if none
+
    procedure Process_Binder_File (Name : String);
    --  For Stand-Alone libraries, get the Linker Options in the binder
    --  generated file.
 
    procedure Reset_Tables;
    --  Make sure that all the above tables are empty
-   --  (Objects, Foreign_Objects, Ali_Files, Options).
+   --  (Objects, Ali_Files, Options).
+
+   function SALs_Use_Constructors return Boolean;
+   --  Indicate if Stand-Alone Libraries are automatically initialized using
+   --  the constructor mechanism.
 
    ------------------
    -- Add_Argument --
@@ -291,6 +283,7 @@ package body MLib.Prj is
 
    procedure Build_Library
      (For_Project   : Project_Id;
+      In_Tree       : Project_Tree_Ref;
       Gnatbind      : String;
       Gnatbind_Path : String_Access;
       Gcc           : String;
@@ -298,27 +291,37 @@ package body MLib.Prj is
       Bind          : Boolean := True;
       Link          : Boolean := True)
    is
+      Maximum_Size : Integer;
+      pragma Import (C, Maximum_Size, "__gnat_link_max");
+      --  Maximum number of bytes to put in an invocation of the
+      --  gnatbind.
+
+      Size : Integer;
+      --  The number of bytes for the invocation of the gnatbind
+
       Warning_For_Library : Boolean := False;
       --  Set to True for the first warning about a unit missing from the
       --  interface set.
 
-      Libgnarl_Needed   : Boolean := False;
+      Current_Proj : Project_Id;
+
+      Libgnarl_Needed   : Yes_No_Unknown := For_Project.Libgnarl_Needed;
       --  Set to True if library needs to be linked with libgnarl
 
       Libdecgnat_Needed : Boolean := False;
       --  On OpenVMS, set to True if library needs to be linked with libdecgnat
 
-      Data : Project_Data := Projects.Table (For_Project);
+      Gtrasymobj_Needed : Boolean := False;
+      --  On OpenVMS, set to True if library needs to be linked with
+      --  g-trasym.obj.
 
       Object_Directory_Path : constant String :=
-                          Get_Name_String (Data.Object_Directory);
+                                Get_Name_String
+                                  (For_Project.Object_Directory.Display_Name);
 
-      Standalone   : constant Boolean := Data.Standalone_Library;
+      Standalone   : constant Boolean := For_Project.Standalone_Library;
 
-      Project_Name : constant String := Get_Name_String (Data.Name);
-
-      DLL_Address  : constant String_Access :=
-                       new String'(Default_DLL_Address);
+      Project_Name : constant String := Get_Name_String (For_Project.Name);
 
       Current_Dir  : constant String := Get_Current_Dir;
 
@@ -332,12 +335,12 @@ package body MLib.Prj is
 
       Library_Options : Variable_Value := Nil_Variable_Value;
 
-      Library_GCC     : Variable_Value := Nil_Variable_Value;
-
       Driver_Name : Name_Id := No_Name;
 
       In_Main_Object_Directory : Boolean := True;
 
+      Foreign_Sources : Boolean;
+
       Rpath : String_Access := null;
       --  Allocated only if Path Option is supported
 
@@ -351,13 +354,10 @@ package body MLib.Prj is
       --  If null, Path Option is not supported.
       --  Not a constant so that it can be deallocated.
 
-      Copy_Dir : Name_Id;
-      --  Directory where to copy ALI files and possibly interface sources
-
-      First_ALI : Name_Id := No_Name;
+      First_ALI : File_Name_Type := No_File;
       --  Store the ALI file name of a source of the library (the first found)
 
-      procedure Add_ALI_For (Source : Name_Id);
+      procedure Add_ALI_For (Source : File_Name_Type);
       --  Add the name of the ALI file corresponding to Source to the
       --  Arguments.
 
@@ -367,12 +367,13 @@ package body MLib.Prj is
       function Check_Project (P : Project_Id) return Boolean;
       --  Returns True if P is For_Project or a project extended by For_Project
 
-      procedure Check_Libs (ALI_File : String);
+      procedure Check_Libs (ALI_File : String; Main_Project : Boolean);
       --  Set Libgnarl_Needed if the ALI_File indicates that there is a need
       --  to link with -lgnarl (this is the case when there is a dependency
       --  on s-osinte.ads). On OpenVMS, set Libdecgnat_Needed if the ALI file
       --  indicates that there is a need to link with -ldecgnat (this is the
-      --  case when there is a dependency on dec.ads).
+      --  case when there is a dependency on dec.ads), and set
+      --  Gtrasymobj_Needed if there is a dependency on g-trasym.ads.
 
       procedure Process (The_ALI : File_Name_Type);
       --  Check if the closure of a library unit which is or should be in the
@@ -388,9 +389,9 @@ package body MLib.Prj is
       -- Add_ALI_For --
       -----------------
 
-      procedure Add_ALI_For (Source : Name_Id) is
+      procedure Add_ALI_For (Source : File_Name_Type) is
          ALI    : constant String := ALI_File_Name (Get_Name_String (Source));
-         ALI_Id : Name_Id;
+         ALI_Id : File_Name_Type;
 
       begin
          if Bind then
@@ -409,7 +410,7 @@ package body MLib.Prj is
 
          --  Set First_ALI, if not already done
 
-         if First_ALI = No_Name then
+         if First_ALI = No_File then
             First_ALI := ALI_Id;
          end if;
       end Add_ALI_For;
@@ -439,7 +440,7 @@ package body MLib.Prj is
       --  Start of processing for Add_Rpath
 
       begin
-         --  If firt path, allocate initial Rpath
+         --  If first path, allocate initial Rpath
 
          if Rpath = null then
             Rpath := new String (1 .. Initial_Rpath_Length);
@@ -479,15 +480,16 @@ package body MLib.Prj is
 
          elsif P /= No_Project then
             declare
-               Data : Project_Data := Projects.Table (For_Project);
+               Proj : Project_Id;
 
             begin
-               while Data.Extends /= No_Project loop
-                  if P = Data.Extends then
+               Proj := For_Project;
+               while Proj.Extends /= No_Project loop
+                  if P = Proj.Extends then
                      return True;
                   end if;
 
-                  Data := Projects.Table (Data.Extends);
+                  Proj := Proj.Extends;
                end loop;
             end;
          end if;
@@ -499,17 +501,17 @@ package body MLib.Prj is
       -- Check_Libs --
       ----------------
 
-      procedure Check_Libs (ALI_File : String) is
-         Lib_File : Name_Id;
+      procedure Check_Libs (ALI_File : String; Main_Project : Boolean) is
+         Lib_File : File_Name_Type;
          Text     : Text_Buffer_Ptr;
          Id       : ALI.ALI_Id;
 
-         pragma Warnings (Off, Id);
-         --  Comment needed ???
-
       begin
-         if not Libgnarl_Needed or
-           (Hostparm.OpenVMS and then (not Libdecgnat_Needed))
+         if Libgnarl_Needed /= Yes
+           or else
+            (Main_Project
+              and then OpenVMS_On_Target
+              and then ((not Libdecgnat_Needed) or (not Gtrasymobj_Needed)))
          then
             --  Scan the ALI file
 
@@ -518,12 +520,12 @@ package body MLib.Prj is
             Lib_File := Name_Find;
             Text := Read_Library_Info (Lib_File, True);
 
-            Id  := ALI.Scan_ALI
-                         (F          => Lib_File,
-                          T          => Text,
-                          Ignore_ED  => False,
-                          Err        => True,
-                          Read_Lines => "D");
+            Id := ALI.Scan_ALI
+                    (F          => Lib_File,
+                     T          => Text,
+                     Ignore_ED  => False,
+                     Err        => True,
+                     Read_Lines => "D");
             Free (Text);
 
             --  Look for s-osinte.ads in the dependencies
@@ -532,12 +534,21 @@ package body MLib.Prj is
                          ALI.ALIs.Table (Id).Last_Sdep
             loop
                if ALI.Sdep.Table (Index).Sfile = S_Osinte_Ads then
-                  Libgnarl_Needed := True;
+                  Libgnarl_Needed := Yes;
 
-               elsif Hostparm.OpenVMS and then
-                     ALI.Sdep.Table (Index).Sfile = S_Dec_Ads
-               then
-                  Libdecgnat_Needed := True;
+                  if Main_Project then
+                     For_Project.Libgnarl_Needed := Yes;
+                  else
+                     exit;
+                  end if;
+
+               elsif OpenVMS_On_Target then
+                  if ALI.Sdep.Table (Index).Sfile = S_Dec_Ads then
+                     Libdecgnat_Needed := True;
+
+                  elsif ALI.Sdep.Table (Index).Sfile = G_Trasym_Ads then
+                     Gtrasymobj_Needed := True;
+                  end if;
                end if;
             end loop;
          end if;
@@ -596,13 +607,13 @@ package body MLib.Prj is
                      for W in Unit_Data.First_With .. Unit_Data.Last_With loop
                         Afile := Withs.Table (W).Afile;
 
-                        if Afile /= No_Name and then Library_ALIs.Get (Afile)
+                        if Afile /= No_File and then Library_ALIs.Get (Afile)
                           and then not Processed_ALIs.Get (Afile)
                         then
                            if not Interface_ALIs.Get (Afile) then
                               if not Warning_For_Library then
                                  Write_Str ("Warning: In library project """);
-                                 Get_Name_String (Data.Name);
+                                 Get_Name_String (Current_Proj.Name);
                                  To_Mixed (Name_Buffer (1 .. Name_Len));
                                  Write_Str (Name_Buffer (1 .. Name_Len));
                                  Write_Line ("""");
@@ -661,37 +672,101 @@ package body MLib.Prj is
          ---------------------
 
          procedure Process_Project (Project : Project_Id) is
-            Data     : constant Project_Data := Projects.Table (Project);
-            Imported : Project_List := Data.Imported_Projects;
-            Element  : Project_Element;
+            Imported : Project_List;
 
          begin
             --  Nothing to do if process has already been processed
 
-            if not Processed_Projects.Get (Data.Name) then
-               Processed_Projects.Set (Data.Name, True);
+            if not Processed_Projects.Get (Project.Name) then
+               Processed_Projects.Set (Project.Name, True);
 
                --  Call Process_Project recursively for any imported project.
                --  We first process the imported projects to guarantee that
                --  we have a proper reverse order for the libraries.
 
-               while Imported /= Empty_Project_List loop
-                  Element := Project_Lists.Table (Imported);
-
-                  if Element.Project /= No_Project then
-                     Process_Project (Element.Project);
+               Imported := Project.Imported_Projects;
+               while Imported /= null loop
+                  if Imported.Project /= No_Project then
+                     Process_Project (Imported.Project);
                   end if;
 
-                  Imported := Element.Next;
+                  Imported := Imported.Next;
                end loop;
 
                --  If it is a library project, add it to Library_Projs
 
-               if Project /= For_Project and then Data.Library then
+               if Project /= For_Project and then Project.Library then
                   Library_Projs.Increment_Last;
                   Library_Projs.Table (Library_Projs.Last) := Project;
-               end if;
 
+                  --  Check if because of this library we need to use libgnarl
+
+                  if Libgnarl_Needed = Unknown then
+                     if Project.Libgnarl_Needed = Unknown
+                       and then Project.Object_Directory /= No_Path_Information
+                     then
+                        --  Check if libgnarl is needed for this library
+
+                        declare
+                           Object_Dir_Path : constant String :=
+                                               Get_Name_String
+                                                 (Project.Object_Directory.
+                                                    Display_Name);
+                           Object_Dir      : Dir_Type;
+                           Filename        : String (1 .. 255);
+                           Last            : Natural;
+
+                        begin
+                           Open (Object_Dir, Object_Dir_Path);
+
+                           --  For all entries in the object directory
+
+                           loop
+                              Read (Object_Dir, Filename, Last);
+                              exit when Last = 0;
+
+                              --  Check if it is an object file
+
+                              if Is_Obj (Filename (1 .. Last)) then
+                                 declare
+                                    Object_Path : constant String :=
+                                                    Normalize_Pathname
+                                                      (Object_Dir_Path &
+                                                       Directory_Separator &
+                                                       Filename (1 .. Last));
+                                    ALI_File    : constant String :=
+                                                    Ext_To
+                                                      (Object_Path, "ali");
+
+                                 begin
+                                    if Is_Regular_File (ALI_File) then
+
+                                       --  Find out if for this ALI file,
+                                       --  libgnarl is necessary.
+
+                                       Check_Libs
+                                         (ALI_File, Main_Project => False);
+
+                                       if Libgnarl_Needed = Yes then
+                                          Project.Libgnarl_Needed := Yes;
+                                          For_Project.Libgnarl_Needed := Yes;
+                                          exit;
+                                       end if;
+                                    end if;
+                                 end;
+                              end if;
+                           end loop;
+
+                           Close (Object_Dir);
+                        end;
+                     end if;
+
+                     if Project.Libgnarl_Needed = Yes then
+                        Libgnarl_Needed := Yes;
+                        For_Project.Libgnarl_Needed := Yes;
+                     end if;
+                  end if;
+               end if;
             end if;
          end Process_Project;
 
@@ -704,14 +779,13 @@ package body MLib.Prj is
          Process_Project (For_Project);
 
          --  Add the -L and -l switches and, if the Rpath option is supported,
-         --  add the directory to the Rpath.
-         --  As the library projects are in the wrong order, process from the
-         --  last to the first.
+         --  add the directory to the Rpath. As the library projects are in the
+         --  wrong order, process from the last to the first.
 
          for Index in reverse 1 .. Library_Projs.Last loop
             Current := Library_Projs.Table (Index);
 
-            Get_Name_String (Projects.Table (Current).Library_Dir);
+            Get_Name_String (Current.Library_Dir.Display_Name);
             Opts.Increment_Last;
             Opts.Table (Opts.Last) :=
               new String'("-L" & Name_Buffer (1 .. Name_Len));
@@ -722,10 +796,7 @@ package body MLib.Prj is
 
             Opts.Increment_Last;
             Opts.Table (Opts.Last) :=
-              new String'
-                ("-l" &
-                 Get_Name_String
-                   (Projects.Table (Current).Library_Name));
+              new String'("-l" & Get_Name_String (Current.Library_Name));
          end loop;
       end Process_Imported_Libraries;
 
@@ -736,39 +807,52 @@ package body MLib.Prj is
 
       --  Fail if project is not a library project
 
-      if not Data.Library then
-         Com.Fail ("project """, Project_Name, """ has no library");
+      if not For_Project.Library then
+         Com.Fail ("project """ & Project_Name & """ has no library");
+      end if;
+
+      --  Do not attempt to build the library if it is externally built
+
+      if For_Project.Externally_Built then
+         return;
       end if;
 
       --  If this is the first time Build_Library is called, get the Name_Id
       --  of "s-osinte.ads".
 
-      if S_Osinte_Ads = No_Name then
-         Name_Len := 12;
-         Name_Buffer (1 .. Name_Len) := "s-osinte.ads";
+      if S_Osinte_Ads = No_File then
+         Name_Len := 0;
+         Add_Str_To_Name_Buffer ("s-osinte.ads");
          S_Osinte_Ads := Name_Find;
       end if;
 
-      if S_Dec_Ads = No_Name then
-         Name_Len := 7;
-         Name_Buffer (1 .. Name_Len) := "dec.ads";
+      if S_Dec_Ads = No_File then
+         Name_Len := 0;
+         Add_Str_To_Name_Buffer ("dec.ads");
          S_Dec_Ads := Name_Find;
       end if;
 
+      if G_Trasym_Ads = No_File then
+         Name_Len := 0;
+         Add_Str_To_Name_Buffer ("g-trasym.ads");
+         G_Trasym_Ads := Name_Find;
+      end if;
+
       --  We work in the object directory
 
       Change_Dir (Object_Directory_Path);
 
       if Standalone then
+
          --  Call gnatbind only if Bind is True
 
          if Bind then
             if Gnatbind_Path = null then
-               Com.Fail ("unable to locate ", Gnatbind);
+               Com.Fail ("unable to locate " & Gnatbind);
             end if;
 
             if Gcc_Path = null then
-               Com.Fail ("unable to locate ", Gcc);
+               Com.Fail ("unable to locate " & Gcc);
             end if;
 
             --  Allocate Arguments, if it is the first time we see a standalone
@@ -778,28 +862,34 @@ package body MLib.Prj is
                Arguments := new String_List (1 .. Initial_Argument_Max);
             end if;
 
-            --  Add "-n -o b~<lib>.adb (b$<lib>.adb on VMS) -L<lib>"
+            --  Add "-n -o b~<lib>.adb (b__<lib>.adb on VMS) -L<lib>"
 
             Argument_Number := 2;
             Arguments (1) := No_Main;
             Arguments (2) := Output_Switch;
 
-            if Hostparm.OpenVMS then
-               B_Start (B_Start'Last) := '$';
+            if OpenVMS_On_Target then
+               B_Start := new String'("b__");
             end if;
 
             Add_Argument
-              (B_Start & Get_Name_String (Data.Library_Name) & ".adb");
-            Add_Argument ("-L" & Get_Name_String (Data.Library_Name));
+              (B_Start.all
+               & Get_Name_String (For_Project.Library_Name) & ".adb");
+            Add_Argument ("-L" & Get_Name_String (For_Project.Library_Name));
+
+            if For_Project.Lib_Auto_Init and then SALs_Use_Constructors then
+               Add_Argument (Auto_Initialize);
+            end if;
 
-            --  Check if Binder'Default_Switches ("Ada) is defined. If it is,
+            --  Check if Binder'Default_Switches ("Ada") is defined. If it is,
             --  add these switches to call gnatbind.
 
             declare
                Binder_Package : constant Package_Id :=
                                   Value_Of
                                     (Name        => Name_Binder,
-                                     In_Packages => Data.Decl.Packages);
+                                     In_Packages => For_Project.Decl.Packages,
+                                     In_Tree     => In_Tree);
 
             begin
                if Binder_Package /= No_Package then
@@ -808,8 +898,9 @@ package body MLib.Prj is
                                   Value_Of
                                     (Name      => Name_Default_Switches,
                                      In_Arrays =>
-                                       Packages.Table
-                                         (Binder_Package).Decl.Arrays);
+                                       In_Tree.Packages.Table
+                                         (Binder_Package).Decl.Arrays,
+                                     In_Tree   => In_Tree);
                      Switches : Variable_Value := Nil_Variable_Value;
 
                      Switch : String_List_Id := Nil_String;
@@ -818,7 +909,10 @@ package body MLib.Prj is
                      if Defaults /= No_Array_Element then
                         Switches :=
                           Value_Of
-                            (Index => Name_Ada, In_Array => Defaults);
+                            (Index     => Name_Ada,
+                             Src_Index => 0,
+                             In_Array  => Defaults,
+                             In_Tree   => In_Tree);
 
                         if not Switches.Default then
                            Switch := Switches.Values;
@@ -826,8 +920,10 @@ package body MLib.Prj is
                            while Switch /= Nil_String loop
                               Add_Argument
                                 (Get_Name_String
-                                   (String_Elements.Table (Switch).Value));
-                              Switch := String_Elements.Table (Switch).Next;
+                                   (In_Tree.String_Elements.Table
+                                      (Switch).Value));
+                              Switch := In_Tree.String_Elements.
+                                          Table (Switch).Next;
                            end loop;
                         end if;
                      end if;
@@ -840,57 +936,53 @@ package body MLib.Prj is
          --  Bind is False, so that First_ALI is set.
 
          declare
-            Unit : Unit_Data;
+            Unit : Unit_Index;
 
          begin
             Library_ALIs.Reset;
             Interface_ALIs.Reset;
             Processed_ALIs.Reset;
 
-            for Source in 1 .. Com.Units.Last loop
-               Unit := Com.Units.Table (Source);
-
-               if Unit.File_Names (Body_Part).Name /= No_Name
-                 and then Unit.File_Names (Body_Part).Path /= Slash
+            Unit := Units_Htable.Get_First (In_Tree.Units_HT);
+            while Unit /= No_Unit_Index loop
+               if Unit.File_Names (Impl) /= null
+                 and then not Unit.File_Names (Impl).Locally_Removed
                then
-                  if
-                    Check_Project (Unit.File_Names (Body_Part).Project)
-                  then
-                     if Unit.File_Names (Specification).Name = No_Name then
+                  if Check_Project (Unit.File_Names (Impl).Project) then
+                     if Unit.File_Names (Spec) = null then
                         declare
                            Src_Ind : Source_File_Index;
 
                         begin
                            Src_Ind := Sinput.P.Load_Project_File
-                             (Get_Name_String
-                                (Unit.File_Names
-                                   (Body_Part).Path));
+                                        (Get_Name_String
+                                          (Unit.File_Names (Impl).Path.Name));
 
                            --  Add the ALI file only if it is not a subunit
 
-                           if
-                           not Sinput.P.Source_File_Is_Subunit (Src_Ind)
+                           if not
+                             Sinput.P.Source_File_Is_Subunit (Src_Ind)
                            then
-                              Add_ALI_For
-                                (Unit.File_Names (Body_Part).Name);
+                              Add_ALI_For (Unit.File_Names (Impl).File);
                               exit when not Bind;
                            end if;
                         end;
 
                      else
-                        Add_ALI_For (Unit.File_Names (Body_Part).Name);
+                        Add_ALI_For (Unit.File_Names (Impl).File);
                         exit when not Bind;
                      end if;
                   end if;
 
-               elsif Unit.File_Names (Specification).Name /= No_Name
-                 and then Unit.File_Names (Specification).Path /= Slash
-                 and then Check_Project
-                   (Unit.File_Names (Specification).Project)
+               elsif Unit.File_Names (Spec) /= null
+                 and then not Unit.File_Names (Spec).Locally_Removed
+                 and then Check_Project (Unit.File_Names (Spec).Project)
                then
-                  Add_ALI_For (Unit.File_Names (Specification).Name);
+                  Add_ALI_For (Unit.File_Names (Spec).File);
                   exit when not Bind;
                end if;
+
+               Unit := Units_Htable.Get_Next (In_Tree.Units_HT);
             end loop;
          end;
 
@@ -900,9 +992,8 @@ package body MLib.Prj is
 
             --  Get an eventual --RTS from the ALI file
 
-            if First_ALI /= No_Name then
+            if First_ALI /= No_File then
                declare
-                  use Types;
                   T : Text_Buffer_Ptr;
                   A : ALI_Id;
 
@@ -923,14 +1014,13 @@ package body MLib.Prj is
                        ALI.Units.Table
                          (ALI.ALIs.Table (A).First_Unit).Last_Arg
                      loop
-                        --  Look for --RTS. If found, add the switch to call
-                        --  gnatbind.
+                        --  If --RTS found, add switch to call gnatbind
 
                         declare
                            Arg : String_Ptr renames Args.Table (Index);
                         begin
-                           if
-                             Arg (Arg'First + 2 .. Arg'First + 5) = "RTS="
+                           if Arg'Length >= 6 and then
+                              Arg (Arg'First + 2 .. Arg'First + 5) = "RTS="
                            then
                               Add_Argument (Arg.all);
                               exit;
@@ -944,32 +1034,139 @@ package body MLib.Prj is
             --  Set the paths
 
             Set_Ada_Paths
-              (Project => For_Project, Including_Libraries => True);
+              (Project             => For_Project,
+               In_Tree             => In_Tree,
+               Including_Libraries => True);
 
             --  Display the gnatbind command, if not in quiet output
 
             Display (Gnatbind);
 
-            --  Invoke gnatbind
+            Size := 0;
+            for J in 1 .. Argument_Number loop
+               Size := Size + Arguments (J)'Length + 1;
+            end loop;
+
+            --  Invoke gnatbind with the arguments if the size is not too large
+
+            if Size <= Maximum_Size then
+               Spawn
+                 (Gnatbind_Path.all,
+                  Arguments (1 .. Argument_Number),
+                  Success);
+
+            else
+               --  Otherwise create a temporary response file
+
+               declare
+                  FD            : File_Descriptor;
+                  Path          : Path_Name_Type;
+                  Args          : Argument_List (1 .. 1);
+                  EOL           : constant String (1 .. 1) := (1 => ASCII.LF);
+                  Status        : Integer;
+                  Succ          : Boolean;
+                  Quotes_Needed : Boolean;
+                  Last_Char     : Natural;
+                  Ch            : Character;
+
+               begin
+                  Tempdir.Create_Temp_File (FD, Path);
+                  Args (1) := new String'("@" & Get_Name_String (Path));
+
+                  for J in 1 .. Argument_Number loop
+
+                     --  Check if the argument should be quoted
 
-            GNAT.OS_Lib.Spawn
-              (Gnatbind_Path.all, Arguments (1 .. Argument_Number), Success);
+                     Quotes_Needed := False;
+                     Last_Char     := Arguments (J)'Length;
+
+                     for K in Arguments (J)'Range loop
+                        Ch := Arguments (J) (K);
+
+                        if Ch = ' ' or else Ch = ASCII.HT or else Ch = '"' then
+                           Quotes_Needed := True;
+                           exit;
+                        end if;
+                     end loop;
+
+                     if Quotes_Needed then
+
+                        --  Quote the argument, doubling '"'
+
+                        declare
+                           Arg : String (1 .. Arguments (J)'Length * 2 + 2);
+
+                        begin
+                           Arg (1) := '"';
+                           Last_Char := 1;
+
+                           for K in Arguments (J)'Range loop
+                              Ch := Arguments (J) (K);
+                              Last_Char := Last_Char + 1;
+                              Arg (Last_Char) := Ch;
+
+                              if Ch = '"' then
+                                 Last_Char := Last_Char + 1;
+                                 Arg (Last_Char) := '"';
+                              end if;
+                           end loop;
+
+                           Last_Char := Last_Char + 1;
+                           Arg (Last_Char) := '"';
+
+                           Status := Write (FD, Arg'Address, Last_Char);
+                        end;
+
+                     else
+                        Status := Write
+                          (FD,
+                           Arguments (J) (Arguments (J)'First)'Address,
+                           Last_Char);
+                     end if;
+
+                     if Status /= Last_Char then
+                        Fail ("disk full");
+                     end if;
+
+                     Status := Write (FD, EOL (1)'Address, 1);
+
+                     if Status /= 1 then
+                        Fail ("disk full");
+                     end if;
+                  end loop;
+
+                  Close (FD);
+
+                  --  And invoke gnatbind with this response file
+
+                  Spawn (Gnatbind_Path.all, Args, Success);
+
+                  Delete_File (Get_Name_String (Path), Succ);
+
+                  if not Succ then
+                     null;
+                  end if;
+               end;
+            end if;
 
             if not Success then
-               Com.Fail ("could not bind standalone library ",
-                         Get_Name_String (Data.Library_Name));
+               Com.Fail ("could not bind standalone library "
+                         & Get_Name_String (For_Project.Library_Name));
             end if;
          end if;
 
          --  Compile the binder generated file only if Link is true
 
          if Link then
+
             --  Set the paths
 
             Set_Ada_Paths
-              (Project => For_Project, Including_Libraries => True);
+              (Project             => For_Project,
+               In_Tree             => In_Tree,
+               Including_Libraries => True);
 
-            --  Invoke <gcc> -c b$$<lib>.adb
+            --  Invoke <gcc> -c b__<lib>.adb
 
             --  Allocate Arguments, if it is the first time we see a standalone
             --  library.
@@ -981,12 +1178,13 @@ package body MLib.Prj is
             Argument_Number := 1;
             Arguments (1) := Compile_Switch;
 
-            if Hostparm.OpenVMS then
-               B_Start (B_Start'Last) := '$';
+            if OpenVMS_On_Target then
+               B_Start := new String'("b__");
             end if;
 
             Add_Argument
-              (B_Start & Get_Name_String (Data.Library_Name) & ".adb");
+              (B_Start.all
+               & Get_Name_String (For_Project.Library_Name) & ".adb");
 
             --  If necessary, add the PIC option
 
@@ -996,9 +1194,8 @@ package body MLib.Prj is
 
             --  Get the back-end switches and --RTS from the ALI file
 
-            if First_ALI /= No_Name then
+            if First_ALI /= No_File then
                declare
-                  use Types;
                   T : Text_Buffer_Ptr;
                   A : ALI_Id;
 
@@ -1009,8 +1206,8 @@ package body MLib.Prj is
 
                   --  Read it
 
-                  A := Scan_ALI
-                         (First_ALI, T, Ignore_ED => False, Err => False);
+                  A :=
+                    Scan_ALI (First_ALI, T, Ignore_ED => False, Err => False);
 
                   if A /= No_ALI_Id then
                      for Index in
@@ -1041,13 +1238,13 @@ package body MLib.Prj is
             --  generated file.
 
             Display (Gcc);
-            GNAT.OS_Lib.Spawn
+            Spawn
               (Gcc_Path.all, Arguments (1 .. Argument_Number), Success);
 
             if not Success then
                Com.Fail
-                 ("could not compile binder generated file for library ",
-                  Get_Name_String (Data.Library_Name));
+                ("could not compile binder generated file for library "
+                  & Get_Name_String (For_Project.Library_Name));
             end if;
 
             --  Process binder generated file for pragmas Linker_Options
@@ -1059,28 +1256,29 @@ package body MLib.Prj is
       --  Build the library only if Link is True
 
       if Link then
-         --  If attribute Library_GCC was specified, get the driver name
 
-         Library_GCC := Value_Of (Name_Library_GCC, Data.Decl.Attributes);
+         --  If attributes Library_GCC or Linker'Driver were specified, get the
+         --  driver name.
 
-         if not Library_GCC.Default then
-            Driver_Name := Library_GCC.Value;
+         if For_Project.Config.Shared_Lib_Driver /= No_File then
+            Driver_Name := Name_Id (For_Project.Config.Shared_Lib_Driver);
          end if;
 
          --  If attribute Library_Options was specified, add these additional
          --  options.
 
-         Library_Options :=
-           Value_Of (Name_Library_Options, Data.Decl.Attributes);
+         Library_Options := Value_Of
+           (Name_Library_Options, For_Project.Decl.Attributes, In_Tree);
 
          if not Library_Options.Default then
             declare
-               Current : String_List_Id := Library_Options.Values;
+               Current : String_List_Id;
                Element : String_Element;
 
             begin
+               Current := Library_Options.Values;
                while Current /= Nil_String loop
-                  Element := String_Elements.Table (Current);
+                  Element := In_Tree.String_Elements.Table (Current);
                   Get_Name_String (Element.Value);
 
                   if Name_Len /= 0 then
@@ -1094,10 +1292,12 @@ package body MLib.Prj is
             end;
          end if;
 
-         Lib_Dirpath  := new String'(Get_Name_String (Data.Library_Dir));
-         Lib_Filename := new String'(Get_Name_String (Data.Library_Name));
+         Lib_Dirpath  :=
+           new String'(Get_Name_String (For_Project.Library_Dir.Display_Name));
+         Lib_Filename := new String'
+           (Get_Name_String (For_Project.Library_Name));
 
-         case Data.Library_Kind is
+         case For_Project.Library_Kind is
             when Static =>
                The_Build_Mode := Static;
 
@@ -1115,117 +1315,222 @@ package body MLib.Prj is
 
          --  Get the library version, if any
 
-         if Data.Lib_Internal_Name /= No_Name then
+         if For_Project.Lib_Internal_Name /= No_Name then
             Lib_Version :=
-              new String'(Get_Name_String (Data.Lib_Internal_Name));
+              new String'(Get_Name_String (For_Project.Lib_Internal_Name));
          end if;
 
          --  Add the objects found in the object directory and the object
          --  directories of the extended files, if any, except for generated
-         --  object files (b~.. or B$..) from extended projects.
+         --  object files (b~.. or B__..) from extended projects.
          --  When there are one or more extended files, only add an object file
          --  if no object file with the same name have already been added.
 
          In_Main_Object_Directory := True;
 
-         loop
-            declare
-               Object_Dir_Path : constant String :=
-                                   Get_Name_String (Data.Object_Directory);
-               Object_Dir      : Dir_Type;
-               Filename        : String (1 .. 255);
-               Last            : Natural;
-               Id              : Name_Id;
-
-            begin
-               Open (Dir => Object_Dir, Dir_Name => Object_Dir_Path);
-
-               --  For all entries in the object directory
-
-               loop
-                  Read (Object_Dir, Filename, Last);
+         --  For gnatmake, when the project specifies more than just Ada as a
+         --  language (even if course we could not find any source file for
+         --  the other languages), we will take all object files found in the
+         --  object directories. Since we know the project supports at least
+         --  Ada, we just have to test whether it has at least two languages,
+         --  and not care about the sources.
 
-                  exit when Last = 0;
-
-                  --  Check if it is an object file
-
-                  if Is_Obj (Filename (1 .. Last)) then
-                     declare
-                        Object_Path : String :=
-                          Normalize_Pathname
-                            (Object_Dir_Path & Directory_Separator &
-                             Filename (1 .. Last));
-
-                     begin
-                        Canonical_Case_File_Name (Object_Path);
-                        Canonical_Case_File_Name (Filename (1 .. Last));
+         Foreign_Sources := For_Project.Languages.Next /= null;
+         Current_Proj := For_Project;
+         loop
+            if Current_Proj.Object_Directory /= No_Path_Information then
 
-                        --  If in the object directory of an extended project,
-                        --  do not consider generated object files.
+               --  The following code gets far too indented, I suggest some
+               --  procedural abstraction here. How about making this declare
+               --  block a named procedure???
 
-                        if In_Main_Object_Directory
-                          or else Last < 5
-                          or else Filename (1 .. B_Start'Length) /= B_Start
-                        then
-                           Name_Len := Last;
-                           Name_Buffer (1 .. Name_Len) := Filename (1 .. Last);
-                           Id := Name_Find;
+               declare
+                  Object_Dir_Path : constant String :=
+                                      Get_Name_String
+                                        (Current_Proj.Object_Directory
+                                         .Display_Name);
 
-                           if not Objects_Htable.Get (Id) then
+                  Object_Dir : Dir_Type;
+                  Filename   : String (1 .. 255);
+                  Last       : Natural;
+                  Id         : Name_Id;
 
-                              --  Record this object file
+               begin
+                  Open (Dir => Object_Dir, Dir_Name => Object_Dir_Path);
 
-                              Objects_Htable.Set (Id, True);
-                              Objects.Increment_Last;
-                              Objects.Table (Objects.Last) :=
-                                new String'(Object_Path);
+                  --  For all entries in the object directory
 
-                              declare
-                                 ALI_File : constant String :=
-                                              Ext_To (Object_Path, "ali");
+                  loop
+                     Read (Object_Dir, Filename, Last);
 
-                              begin
-                                 if Is_Regular_File (ALI_File) then
+                     exit when Last = 0;
 
-                                    --  Record the ALI file
+                     --  Check if it is an object file
 
-                                    ALIs.Increment_Last;
-                                    ALIs.Table (ALIs.Last) :=
-                                      new String'(ALI_File);
+                     if Is_Obj (Filename (1 .. Last)) then
+                        declare
+                           Object_Path  : constant String :=
+                                            Normalize_Pathname
+                                              (Object_Dir_Path
+                                               & Directory_Separator
+                                               & Filename (1 .. Last));
+                           Object_File  : constant String :=
+                                            Filename (1 .. Last);
 
-                                    --  Find out if for this ALI file,
-                                    --  libgnarl or libdecgnat (on OpenVMS)
-                                    --  is necessary.
+                           C_Filename    : String := Object_File;
 
-                                    Check_Libs (ALI_File);
+                        begin
+                           Canonical_Case_File_Name (C_Filename);
 
-                                 else
-                                    --  Object file is a foreign object file
+                           --  If in the object directory of an extended
+                           --  project, do not consider generated object files.
 
-                                    Foreigns.Increment_Last;
-                                    Foreigns.Table (Foreigns.Last) :=
-                                      new String'(Object_Path);
-                                 end if;
-                              end;
+                           if In_Main_Object_Directory
+                             or else Last < 5
+                             or else
+                               C_Filename (1 .. B_Start'Length) /= B_Start.all
+                           then
+                              Name_Len := 0;
+                              Add_Str_To_Name_Buffer (C_Filename);
+                              Id := Name_Find;
+
+                              if not Objects_Htable.Get (Id) then
+                                 declare
+                                    ALI_File : constant String :=
+                                                 Ext_To (C_Filename, "ali");
+
+                                    ALI_Path : constant String :=
+                                                 Ext_To (Object_Path, "ali");
+
+                                    Add_It : Boolean;
+                                    Fname  : File_Name_Type;
+                                    Proj   : Project_Id;
+                                    Index  : Unit_Index;
+
+                                 begin
+                                    --  The following assignment could use
+                                    --  a comment ???
+
+                                    Add_It :=
+                                      Foreign_Sources
+                                        or else
+                                          (Last >= 5
+                                             and then
+                                               C_Filename (1 .. B_Start'Length)
+                                                 = B_Start.all);
+
+                                    if Is_Regular_File (ALI_Path) then
+
+                                       --  If there is an ALI file, check if
+                                       --  the object file should be added to
+                                       --  the library. If there are foreign
+                                       --  sources we put all object files in
+                                       --  the library.
+
+                                       if not Add_It then
+                                          Index :=
+                                            Units_Htable.Get_First
+                                             (In_Tree.Units_HT);
+                                          while Index /= null loop
+                                             if Index.File_Names (Impl) /=
+                                               null
+                                             then
+                                                Proj :=
+                                                  Index.File_Names (Impl)
+                                                  .Project;
+                                                Fname :=
+                                                  Index.File_Names (Impl).File;
+
+                                             elsif Index.File_Names (Spec) /=
+                                               null
+                                             then
+                                                Proj :=
+                                                  Index.File_Names (Spec)
+                                                  .Project;
+                                                Fname :=
+                                                  Index.File_Names (Spec).File;
+
+                                             else
+                                                Proj := No_Project;
+                                             end if;
+
+                                             Add_It := Proj /= No_Project;
+
+                                             --  If the source is in the
+                                             --  project or a project it
+                                             --  extends, we may put it in
+                                             --  the library.
+
+                                             if Add_It then
+                                                Add_It := Check_Project (Proj);
+                                             end if;
+
+                                             --  But we don't, if the ALI file
+                                             --  does not correspond to the
+                                             --  unit.
+
+                                             if Add_It then
+                                                declare
+                                                   F : constant String :=
+                                                         Ext_To
+                                                           (Get_Name_String
+                                                              (Fname), "ali");
+                                                begin
+                                                   Add_It := F = ALI_File;
+                                                end;
+                                             end if;
+
+                                             exit when Add_It;
+
+                                             Index :=
+                                               Units_Htable.Get_Next
+                                                 (In_Tree.Units_HT);
+                                          end loop;
+                                       end if;
+
+                                       if Add_It then
+                                          Objects_Htable.Set (Id, True);
+                                          Objects.Append
+                                            (new String'(Object_Path));
+
+                                          --  Record the ALI file
+
+                                          ALIs.Append (new String'(ALI_Path));
+
+                                          --  Find out if for this ALI file,
+                                          --  libgnarl or libdecgnat or
+                                          --  g-trasym.obj (on OpenVMS) is
+                                          --  necessary.
+
+                                          Check_Libs (ALI_Path, True);
+                                       end if;
+
+                                    elsif Foreign_Sources then
+                                       Objects.Append
+                                         (new String'(Object_Path));
+                                    end if;
+                                 end;
+                              end if;
                            end if;
-                        end if;
-                     end;
-                  end if;
-               end loop;
+                        end;
+                     end if;
+                  end loop;
 
-               Close (Dir => Object_Dir);
+                  Close (Dir => Object_Dir);
 
-            exception
-               when Directory_Error =>
-                  Com.Fail ("cannot find object directory """,
-                            Get_Name_String (Data.Object_Directory),
-                            """");
-            end;
+               exception
+                  when Directory_Error =>
+                     Com.Fail ("cannot find object directory """
+                               & Get_Name_String
+                                  (Current_Proj.Object_Directory.Display_Name)
+                               & """");
+               end;
+            end if;
 
-            exit when Data.Extends = No_Project;
+            exit when Current_Proj.Extends = No_Project;
 
             In_Main_Object_Directory  := False;
-            Data := Projects.Table (Data.Extends);
+            Current_Proj := Current_Proj.Extends;
          end loop;
 
          --  Add the -L and -l switches for the imported Library Project Files,
@@ -1243,10 +1548,34 @@ package body MLib.Prj is
          --  Rpath.
 
          if Path_Option /= null then
-            Add_Rpath (Lib_Directory);
+            declare
+               Libdir    : constant String := Lib_Directory;
+               GCC_Index : Natural := 0;
+
+            begin
+               Add_Rpath (Libdir);
+
+               --  For shared libraries, add to the Path Option the directory
+               --  of the shared version of libgcc.
+
+               if The_Build_Mode /= Static then
+                  GCC_Index := Index (Libdir, "/lib/");
+
+                  if GCC_Index = 0 then
+                     GCC_Index :=
+                       Index
+                         (Libdir,
+                          Directory_Separator & "lib" & Directory_Separator);
+                  end if;
+
+                  if GCC_Index /= 0 then
+                     Add_Rpath (Libdir (Libdir'First .. GCC_Index + 3));
+                  end if;
+               end if;
+            end;
          end if;
 
-         if Libgnarl_Needed then
+         if Libgnarl_Needed = Yes then
             Opts.Increment_Last;
 
             if The_Build_Mode = Static then
@@ -1256,12 +1585,25 @@ package body MLib.Prj is
             end if;
          end if;
 
+         if Gtrasymobj_Needed then
+            Opts.Increment_Last;
+            Opts.Table (Opts.Last) :=
+              new String'(Lib_Directory & "/g-trasym.obj");
+         end if;
+
          if Libdecgnat_Needed then
             Opts.Increment_Last;
+
             Opts.Table (Opts.Last) :=
               new String'("-L" & Lib_Directory & "/../declib");
+
             Opts.Increment_Last;
-            Opts.Table (Opts.Last) := new String'("-ldecgnat");
+
+            if The_Build_Mode = Static then
+               Opts.Table (Opts.Last) := new String'("-ldecgnat");
+            else
+               Opts.Table (Opts.Last) := new String'(Shared_Lib ("decgnat"));
+            end if;
          end if;
 
          Opts.Increment_Last;
@@ -1288,10 +1630,6 @@ package body MLib.Prj is
            new Argument_List'
              (Argument_List (Objects.Table (1 .. Objects.Last)));
 
-         Foreign_Objects :=
-           new Argument_List'(Argument_List
-                                (Foreigns.Table (1 .. Foreigns.Last)));
-
          Ali_Files :=
            new Argument_List'(Argument_List (ALIs.Table (1 .. ALIs.Last)));
 
@@ -1314,47 +1652,51 @@ package body MLib.Prj is
             Write_Str  (" library for project ");
             Write_Line (Project_Name);
 
-            Write_Eol;
+            --  Only output list of object files and ALI files in verbose mode
 
-            Write_Line ("object files:");
+            if Opt.Verbose_Mode then
+               Write_Eol;
 
-            for Index in Object_Files'Range loop
-               Write_Str  ("   ");
-               Write_Line (Object_Files (Index).all);
-            end loop;
+               Write_Line ("object files:");
 
-            Write_Eol;
+               for Index in Object_Files'Range loop
+                  Write_Str  ("   ");
+                  Write_Line (Object_Files (Index).all);
+               end loop;
 
-            if Ali_Files'Length = 0 then
-               Write_Line ("NO ALI files");
+               Write_Eol;
 
-            else
-               Write_Line ("ALI files:");
+               if Ali_Files'Length = 0 then
+                  Write_Line ("NO ALI files");
 
-               for Index in Ali_Files'Range loop
-                  Write_Str  ("   ");
-                  Write_Line (Ali_Files (Index).all);
-               end loop;
-            end if;
+               else
+                  Write_Line ("ALI files:");
 
-            Write_Eol;
+                  for Index in Ali_Files'Range loop
+                     Write_Str  ("   ");
+                     Write_Line (Ali_Files (Index).all);
+                  end loop;
+               end if;
+
+               Write_Eol;
+            end if;
          end if;
 
          --  We check that all object files are regular files
 
          Check_Context;
 
-         --  Delete the existing library file, if it exists.
-         --  Fail if the library file is not writable, or if it is not possible
-         --  to delete the file.
+         --  Delete the existing library file, if it exists. Fail if the
+         --  library file is not writable, or if it is not possible to delete
+         --  the file.
 
          declare
             DLL_Name : aliased String :=
-                         Lib_Dirpath.all & "/lib" &
+                         Lib_Dirpath.all & Directory_Separator & DLL_Prefix &
                            Lib_Filename.all & "." & DLL_Ext;
 
             Archive_Name : aliased String :=
-                             Lib_Dirpath.all & "/lib" &
+                             Lib_Dirpath.all & Directory_Separator & "lib" &
                                Lib_Filename.all & "." & Archive_Ext;
 
             type Str_Ptr is access all String;
@@ -1365,7 +1707,8 @@ package body MLib.Prj is
             --  Designates the full library path name. Either DLL_Name or
             --  Archive_Name, depending on the library kind.
 
-            Success : Boolean := False;
+            Success : Boolean;
+            pragma Warnings (Off, Success);
             --  Used to call Delete_File
 
          begin
@@ -1395,22 +1738,25 @@ package body MLib.Prj is
          --  the library directory (by Copy_ALI_Files, below).
 
          if Standalone then
-            Data := Projects.Table (For_Project);
+            Current_Proj := For_Project;
 
             declare
-               Interface : String_List_Id := Data.Lib_Interface_ALIs;
-               ALI       : File_Name_Type;
+               Iface : String_List_Id := For_Project.Lib_Interface_ALIs;
+               ALI   : File_Name_Type;
 
             begin
-               while Interface /= Nil_String loop
-                  ALI := String_Elements.Table (Interface).Value;
+               while Iface /= Nil_String loop
+                  ALI :=
+                    File_Name_Type
+                      (In_Tree.String_Elements.Table (Iface).Value);
                   Interface_ALIs.Set (ALI, True);
-                  Get_Name_String (String_Elements.Table (Interface).Value);
+                  Get_Name_String
+                    (In_Tree.String_Elements.Table (Iface).Value);
                   Add_Argument (Name_Buffer (1 .. Name_Len));
-                  Interface := String_Elements.Table (Interface).Next;
+                  Iface := In_Tree.String_Elements.Table (Iface).Next;
                end loop;
 
-               Interface := Data.Lib_Interface_ALIs;
+               Iface := For_Project.Lib_Interface_ALIs;
 
                if not Opt.Quiet_Output then
 
@@ -1418,22 +1764,144 @@ package body MLib.Prj is
                   --  library that is needed by an interface should also be an
                   --  interface. If it is not the case, output a warning.
 
-                  while Interface /= Nil_String loop
-                     ALI := String_Elements.Table (Interface).Value;
+                  while Iface /= Nil_String loop
+                     ALI :=
+                       File_Name_Type
+                         (In_Tree.String_Elements.Table (Iface).Value);
                      Process (ALI);
-                     Interface := String_Elements.Table (Interface).Next;
+                     Iface := In_Tree.String_Elements.Table (Iface).Next;
                   end loop;
                end if;
             end;
          end if;
 
-         --  Clean the library directory, if it is also the directory where
-         --  the ALI files are copied, either because there is no interface
-         --  copy directory or because the interface copy directory is the
-         --  same as the library directory.
+         declare
+            Current_Dir  : constant String := Get_Current_Dir;
+            Dir          : Dir_Type;
+
+            Name : String (1 .. 200);
+            Last : Natural;
+
+            Disregard : Boolean;
+            pragma Warnings (Off, Disregard);
+
+            DLL_Name : aliased constant String :=
+                         Lib_Filename.all & "." & DLL_Ext;
+
+            Archive_Name : aliased constant String :=
+                             Lib_Filename.all & "." & Archive_Ext;
+
+            Delete : Boolean := False;
+
+         begin
+            --  Clean the library directory: remove any file with the name of
+            --  the library file and any ALI file of a source of the project.
+
+            begin
+               Get_Name_String (For_Project.Library_Dir.Display_Name);
+               Change_Dir (Name_Buffer (1 .. Name_Len));
+
+            exception
+               when others =>
+                  Com.Fail
+                    ("unable to access library directory """
+                     & Name_Buffer (1 .. Name_Len)
+                     & """");
+            end;
+
+            Open (Dir, ".");
+
+            loop
+               Read (Dir, Name, Last);
+               exit when Last = 0;
+
+               declare
+                  Filename : constant String := Name (1 .. Last);
+
+               begin
+                  if Is_Regular_File (Filename) then
+                     Canonical_Case_File_Name (Name (1 .. Last));
+                     Delete := False;
+
+                     if (The_Build_Mode = Static
+                          and then Name (1 .. Last) =  Archive_Name)
+                       or else
+                         ((The_Build_Mode = Dynamic
+                            or else
+                           The_Build_Mode = Relocatable)
+                          and then Name (1 .. Last) = DLL_Name)
+                     then
+                        Delete := True;
+
+                     elsif Last > 4
+                       and then Name (Last - 3 .. Last) = ".ali"
+                     then
+                        declare
+                           Unit : Unit_Index;
+
+                        begin
+                           --  Compare with ALI file names of the project
+
+                           Unit := Units_Htable.Get_First (In_Tree.Units_HT);
+                           while Unit /= No_Unit_Index loop
+                              if Unit.File_Names (Impl) /= null
+                                and then Unit.File_Names (Impl).Project /=
+                                                                 No_Project
+                              then
+                                 if Ultimate_Extending_Project_Of
+                                      (Unit.File_Names (Impl).Project) =
+                                                                 For_Project
+                                 then
+                                    Get_Name_String
+                                      (Unit.File_Names (Impl).File);
+                                    Name_Len :=
+                                      Name_Len -
+                                        File_Extension
+                                          (Name (1 .. Name_Len))'Length;
+
+                                    if Name_Buffer (1 .. Name_Len) =
+                                      Name (1 .. Last - 4)
+                                    then
+                                       Delete := True;
+                                       exit;
+                                    end if;
+                                 end if;
+
+                              elsif Unit.File_Names (Spec) /= null
+                                and then Ultimate_Extending_Project_Of
+                                           (Unit.File_Names (Spec).Project) =
+                                                                   For_Project
+                              then
+                                 Get_Name_String (Unit.File_Names (Spec).File);
+                                 Name_Len :=
+                                   Name_Len -
+                                     File_Extension (Name (1 .. Last))'Length;
+
+                                 if Name_Buffer (1 .. Name_Len) =
+                                      Name (1 .. Last - 4)
+                                 then
+                                    Delete := True;
+                                    exit;
+                                 end if;
+                              end if;
+
+                              Unit := Units_Htable.Get_Next (In_Tree.Units_HT);
+                           end loop;
+                        end;
+                     end if;
+
+                     if Delete then
+                        Set_Writable (Filename);
+                        Delete_File (Filename, Disregard);
+                     end if;
+                  end if;
+               end;
+            end loop;
+
+            Close (Dir);
 
-         Copy_Dir := Projects.Table (For_Project).Library_Dir;
-         Clean (Copy_Dir);
+            Change_Dir (Current_Dir);
+         end;
 
          --  Call procedure to build the library, depending on the build mode
 
@@ -1441,23 +1909,18 @@ package body MLib.Prj is
             when Dynamic | Relocatable =>
                Build_Dynamic_Library
                  (Ofiles        => Object_Files.all,
-                  Foreign       => Foreign_Objects.all,
-                  Afiles        => Ali_Files.all,
                   Options       => Options.all,
                   Interfaces    => Arguments (1 .. Argument_Number),
                   Lib_Filename  => Lib_Filename.all,
                   Lib_Dir       => Lib_Dirpath.all,
-                  Symbol_Data   => Data.Symbol_Data,
+                  Symbol_Data   => Current_Proj.Symbol_Data,
                   Driver_Name   => Driver_Name,
-                  Lib_Address   => DLL_Address.all,
                   Lib_Version   => Lib_Version.all,
-                  Relocatable   => The_Build_Mode = Relocatable,
-                  Auto_Init     => Data.Lib_Auto_Init);
+                  Auto_Init     => Current_Proj.Lib_Auto_Init);
 
             when Static =>
                MLib.Build_Library
                  (Object_Files.all,
-                  Ali_Files.all,
                   Lib_Filename.all,
                   Lib_Dirpath.all);
 
@@ -1465,38 +1928,109 @@ package body MLib.Prj is
                null;
          end case;
 
-         --  We need to copy the ALI files from the object directory to
-         --  the library directory, so that the linker find them there,
-         --  and does not need to look in the object directory where it
-         --  would also find the object files; and we don't want that:
-         --  we want the linker to use the library.
+         --  We need to copy the ALI files from the object directory to the
+         --  library ALI directory, so that the linker find them there, and
+         --  does not need to look in the object directory where it would also
+         --  find the object files; and we don't want that: we want the linker
+         --  to use the library.
 
          --  Copy the ALI files and make the copies read-only. For interfaces,
          --  mark the copies as interfaces.
 
          Copy_ALI_Files
            (Files      => Ali_Files.all,
-            To         => Copy_Dir,
+            To         => For_Project.Library_ALI_Dir.Display_Name,
             Interfaces => Arguments (1 .. Argument_Number));
 
          --  Copy interface sources if Library_Src_Dir specified
 
          if Standalone
-           and then Projects.Table (For_Project).Library_Src_Dir /= No_Name
+           and then For_Project.Library_Src_Dir /= No_Path_Information
          then
-            --  Clean the interface copy directory, if it is not also the
-            --  library directory. If it is also the library directory, it
-            --  has already been cleaned before generation of the library.
+            --  Clean the interface copy directory: remove any source that
+            --  could be a source of the project.
 
-            if Projects.Table (For_Project).Library_Src_Dir /= Copy_Dir then
-               Copy_Dir := Projects.Table (For_Project).Library_Src_Dir;
-               Clean (Copy_Dir);
-            end if;
+            begin
+               Get_Name_String (For_Project.Library_Src_Dir.Display_Name);
+               Change_Dir (Name_Buffer (1 .. Name_Len));
+
+            exception
+               when others =>
+                  Com.Fail
+                    ("unable to access library source copy directory """
+                     & Name_Buffer (1 .. Name_Len)
+                     & """");
+            end;
+
+            declare
+               Dir    : Dir_Type;
+               Delete : Boolean := False;
+               Unit   : Unit_Index;
+
+               Name : String (1 .. 200);
+               Last : Natural;
+
+               Disregard : Boolean;
+               pragma Warnings (Off, Disregard);
+
+            begin
+               Open (Dir, ".");
+
+               loop
+                  Read (Dir, Name, Last);
+                  exit when Last = 0;
+
+                  if Is_Regular_File (Name (1 .. Last)) then
+                     Canonical_Case_File_Name (Name (1 .. Last));
+                     Delete := False;
+
+                     --  Compare with source file names of the project
+
+                     Unit := Units_Htable.Get_First (In_Tree.Units_HT);
+                     while Unit /= No_Unit_Index loop
+                        if Unit.File_Names (Impl) /= null
+                          and then Ultimate_Extending_Project_Of
+                            (Unit.File_Names (Impl).Project) = For_Project
+                          and then
+                            Get_Name_String
+                              (Unit.File_Names (Impl).File) =
+                            Name (1 .. Last)
+                        then
+                           Delete := True;
+                           exit;
+                        end if;
+
+                        if Unit.File_Names (Spec) /= null
+                          and then Ultimate_Extending_Project_Of
+                            (Unit.File_Names (Spec).Project) =
+                             For_Project
+                          and then
+                           Get_Name_String
+                             (Unit.File_Names (Spec).File) =
+                           Name (1 .. Last)
+                        then
+                           Delete := True;
+                           exit;
+                        end if;
+
+                        Unit := Units_Htable.Get_Next (In_Tree.Units_HT);
+                     end loop;
+                  end if;
+
+                  if Delete then
+                     Set_Writable (Name (1 .. Last));
+                     Delete_File (Name (1 .. Last), Disregard);
+                  end if;
+               end loop;
+
+               Close (Dir);
+            end;
 
             Copy_Interface_Sources
               (For_Project => For_Project,
-               Interfaces => Arguments (1 .. Argument_Number),
-               To_Dir => Copy_Dir);
+               In_Tree     => In_Tree,
+               Interfaces  => Arguments (1 .. Argument_Number),
+               To_Dir      => For_Project.Library_Src_Dir.Display_Name);
          end if;
       end if;
 
@@ -1512,7 +2046,7 @@ package body MLib.Prj is
    procedure Check (Filename : String) is
    begin
       if not Is_Regular_File (Filename) then
-         Com.Fail (Filename, " not found.");
+         Com.Fail (Filename & " not found.");
       end if;
    end Check;
 
@@ -1533,126 +2067,86 @@ package body MLib.Prj is
    -- Check_Library --
    -------------------
 
-   procedure Check_Library (For_Project : Project_Id) is
-      Data : constant Project_Data := Projects.Table (For_Project);
+   procedure Check_Library
+     (For_Project : Project_Id; In_Tree : Project_Tree_Ref)
+   is
+      Lib_TS  : Time_Stamp_Type;
+      Current : constant Dir_Name_Str := Get_Current_Dir;
 
    begin
-      if Data.Library and not Data.Flag1 then
-         declare
-            Current  : constant Dir_Name_Str := Get_Current_Dir;
-            Lib_Name : constant Name_Id := Library_File_Name_For (For_Project);
-            Lib_TS   : Time_Stamp_Type;
-            Obj_TS   : Time_Stamp_Type;
-
-            Object_Dir : Dir_Type;
+      --  No need to build the library if there is no object directory,
+      --  hence no object files to build the library.
 
+      if For_Project.Library then
+         declare
+            Lib_Name : constant File_Name_Type :=
+                         Library_File_Name_For (For_Project, In_Tree);
          begin
-            if Hostparm.OpenVMS then
-               B_Start (B_Start'Last) := '$';
-            end if;
-
-            Change_Dir (Get_Name_String (Data.Library_Dir));
-
+            Change_Dir
+              (Get_Name_String (For_Project.Library_Dir.Display_Name));
             Lib_TS := File_Stamp (Lib_Name);
+            For_Project.Library_TS := Lib_TS;
+         end;
 
-            --  If the library file does not exist, then the time stamp will
-            --  be Empty_Time_Stamp, earlier than any other time stamp.
-
-            Change_Dir (Get_Name_String (Data.Object_Directory));
-            Open (Dir => Object_Dir, Dir_Name => ".");
-
-            --  For all entries in the object directory
-
-            loop
-               Read (Object_Dir, Name_Buffer, Name_Len);
-               exit when Name_Len = 0;
-
-               --  Check if it is an object file, but ignore any binder
-               --  generated file.
-
-               if Is_Obj (Name_Buffer (1 .. Name_Len))
-                  and then Name_Buffer (1 .. B_Start'Length) /= B_Start
-               then
-                  --  Get the object file time stamp
-
-                  Obj_TS := File_Stamp (Name_Find);
-
-                  --  If library file time stamp is earlier, set Flag1 and
-                  --  return. String comparaison is used, otherwise time stamps
-                  --  may be too close and the comparaison would return True,
-                  --  which would trigger an unnecessary rebuild of the
-                  --  library.
-
-                  if String (Lib_TS) < String (Obj_TS) then
-
-                     --  Library must be rebuilt
+         if not For_Project.Externally_Built
+           and then not For_Project.Need_To_Build_Lib
+           and then For_Project.Object_Directory /= No_Path_Information
+         then
+            declare
+               Obj_TS     : Time_Stamp_Type;
+               Object_Dir : Dir_Type;
 
-                     Projects.Table (For_Project).Flag1 := True;
-                     exit;
-                  end if;
+            begin
+               if OpenVMS_On_Target then
+                  B_Start := new String'("b__");
                end if;
-            end loop;
-
-            Change_Dir (Current);
-         end;
-      end if;
-   end Check_Library;
-
-   -----------
-   -- Clean --
-   -----------
 
-   procedure Clean (Directory : Name_Id) is
-      Current  : constant Dir_Name_Str := Get_Current_Dir;
+               --  If the library file does not exist, then the time stamp will
+               --  be Empty_Time_Stamp, earlier than any other time stamp.
 
-      Dir : Dir_Type;
+               Change_Dir
+                 (Get_Name_String (For_Project.Object_Directory.Display_Name));
+               Open (Dir => Object_Dir, Dir_Name => ".");
 
-      Name : String (1 .. 200);
-      Last : Natural;
+               --  For all entries in the object directory
 
-      Disregard : Boolean;
+               loop
+                  Read (Object_Dir, Name_Buffer, Name_Len);
+                  exit when Name_Len = 0;
 
-      procedure Set_Writable (Name : System.Address);
-      pragma Import (C, Set_Writable, "__gnat_set_writable");
+                  --  Check if it is an object file, but ignore any binder
+                  --  generated file.
 
-   begin
-      Get_Name_String (Directory);
+                  if Is_Obj (Name_Buffer (1 .. Name_Len))
+                    and then Name_Buffer (1 .. B_Start'Length) /= B_Start.all
+                  then
+                     --  Get the object file time stamp
 
-      --  Change the working directory to the directory to clean
+                     Obj_TS := File_Stamp (File_Name_Type'(Name_Find));
 
-      begin
-         Change_Dir (Name_Buffer (1 .. Name_Len));
+                     --  If library file time stamp is earlier, set
+                     --  Need_To_Build_Lib and return. String comparison is
+                     --  used, otherwise time stamps may be too close and the
+                     --  comparison would return True, which would trigger
+                     --  an unnecessary rebuild of the library.
 
-      exception
-         when others =>
-            Com.Fail
-              ("unable to access directory """,
-               Name_Buffer (1 .. Name_Len),
-               """");
-      end;
+                     if String (Lib_TS) < String (Obj_TS) then
 
-      Open (Dir, ".");
+                        --  Library must be rebuilt
 
-      --  For each regular file in the directory, make it writable and
-      --  delete the file.
-
-      loop
-         Read (Dir, Name, Last);
-         exit when Last = 0;
+                        For_Project.Need_To_Build_Lib := True;
+                        exit;
+                     end if;
+                  end if;
+               end loop;
 
-         if Is_Regular_File (Name (1 .. Last)) then
-            Name (Last + 1) := ASCII.NUL;
-            Set_Writable (Name (1)'Address);
-            Delete_File (Name (1 .. Last), Disregard);
+               Close (Object_Dir);
+            end;
          end if;
-      end loop;
-
-      Close (Dir);
-
-      --  Restore the initial working directory
 
-      Change_Dir (Current);
-   end Clean;
+         Change_Dir (Current);
+      end if;
+   end Check_Library;
 
    ----------------------------
    -- Copy_Interface_Sources --
@@ -1660,63 +2154,63 @@ package body MLib.Prj is
 
    procedure Copy_Interface_Sources
      (For_Project : Project_Id;
+      In_Tree     : Project_Tree_Ref;
       Interfaces  : Argument_List;
-      To_Dir      : Name_Id)
+      To_Dir      : Path_Name_Type)
    is
-      Current  : constant Dir_Name_Str := Get_Current_Dir;
-      Target   : constant Dir_Name_Str := Get_Name_String (To_Dir);
+      Current : constant Dir_Name_Str := Get_Current_Dir;
+      --  The current directory, where to return to at the end
+
+      Target : constant Dir_Name_Str := Get_Name_String (To_Dir);
+      --  The directory where to copy sources
 
       Text     : Text_Buffer_Ptr;
       The_ALI  : ALI.ALI_Id;
-      Lib_File : Name_Id;
+      Lib_File : File_Name_Type;
 
       First_Unit  : ALI.Unit_Id;
       Second_Unit : ALI.Unit_Id;
 
-      Data : Unit_Data;
-
       Copy_Subunits : Boolean := False;
+      --  When True, indicates that subunits, if any, need to be copied too
 
-      procedure Copy (File_Name : Name_Id);
+      procedure Copy (File_Name : File_Name_Type);
       --  Copy one source of the project to the target directory
 
       ----------
       -- Copy --
       ----------
 
-      procedure Copy (File_Name : Name_Id) is
-         Success : Boolean := False;
+      procedure Copy (File_Name : File_Name_Type) is
+         Success : Boolean;
+         pragma Warnings (Off, Success);
 
+         Source : Standard.Prj.Source_Id;
       begin
-         Unit_Loop :
-         for Index in 1 .. Com.Units.Last loop
-            Data := Com.Units.Table (Index);
-
-            for J in Data.File_Names'Range loop
-               if Data.File_Names (J).Project = For_Project
-                 and then Data.File_Names (J).Name = File_Name
-               then
-                  Copy_File
-                    (Get_Name_String (Data.File_Names (J).Path),
-                     Target,
-                     Success,
-                     Mode => Overwrite,
-                     Preserve => Preserve);
-                  exit Unit_Loop;
-               end if;
-            end loop;
-         end loop Unit_Loop;
+         Source := Find_Source
+           (In_Tree, For_Project,
+            In_Extended_Only => True,
+            Base_Name => File_Name);
+
+         if Source /= No_Source
+           and then not Source.Locally_Removed
+           and then Source.Replaced_By = No_Source
+         then
+            Copy_File
+              (Get_Name_String (Source.Path.Name),
+               Target,
+               Success,
+               Mode     => Overwrite,
+               Preserve => Preserve);
+         end if;
       end Copy;
 
-      use ALI;
-
    --  Start of processing for Copy_Interface_Sources
 
    begin
       --  Change the working directory to the object directory
 
-      Change_Dir
-        (Get_Name_String (Projects.Table (For_Project).Object_Directory));
+      Change_Dir (Get_Name_String (For_Project.Object_Directory.Display_Name));
 
       for Index in Interfaces'Range loop
 
@@ -1789,12 +2283,34 @@ package body MLib.Prj is
          for Index in 1 .. Argument_Number loop
             Write_Char (' ');
             Write_Str (Arguments (Index).all);
+
+            if not Opt.Verbose_Mode and then Index > 4 then
+               Write_Str (" ...");
+               exit;
+            end if;
          end loop;
 
          Write_Eol;
       end if;
    end Display;
 
+   -----------
+   -- Index --
+   -----------
+
+   function Index (S, Pattern : String) return Natural is
+      Len : constant Natural := Pattern'Length;
+
+   begin
+      for J in reverse S'First .. S'Last - Len + 1 loop
+         if Pattern = S (J .. J + Len - 1) then
+            return J;
+         end if;
+      end loop;
+
+      return 0;
+   end Index;
+
    -------------------------
    -- Process_Binder_File --
    -------------------------
@@ -1803,7 +2319,7 @@ package body MLib.Prj is
       Fd : FILEs;
       --  Binder file's descriptor
 
-      Read_Mode  : constant String := "r" & ASCII.Nul;
+      Read_Mode : constant String := "r" & ASCII.NUL;
       --  For fopen
 
       Status : Interfaces.C_Streams.int;
@@ -1903,6 +2419,9 @@ package body MLib.Prj is
                Next_Line (1 .. Nlast) /= "-lgnarl" and then
                Next_Line (1 .. Nlast) /= "-lgnat" and then
                Next_Line
+                 (1 .. Natural'Min (Nlast, 10 + Library_Version'Length)) /=
+                   Shared_Lib ("decgnat") and then
+               Next_Line
                  (1 .. Natural'Min (Nlast, 8 + Library_Version'Length)) /=
                    Shared_Lib ("gnarl") and then
                Next_Line
@@ -1941,7 +2460,9 @@ package body MLib.Prj is
       end if;
 
       Status := fclose (Fd);
+
       --  Is it really right to ignore any close error ???
+
    end Process_Binder_File;
 
    ------------------
@@ -1952,11 +2473,22 @@ package body MLib.Prj is
    begin
       Objects.Init;
       Objects_Htable.Reset;
-      Foreigns.Init;
       ALIs.Init;
       Opts.Init;
       Processed_Projects.Reset;
       Library_Projs.Init;
    end Reset_Tables;
 
+   ---------------------------
+   -- SALs_Use_Constructors --
+   ---------------------------
+
+   function SALs_Use_Constructors return Boolean is
+      function C_SALs_Init_Using_Constructors return Integer;
+      pragma Import (C, C_SALs_Init_Using_Constructors,
+                     "__gnat_sals_init_using_constructors");
+   begin
+      return C_SALs_Init_Using_Constructors /= 0;
+   end SALs_Use_Constructors;
+
 end MLib.Prj;