------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                                 M A K E                                  --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2005 Free Software Foundation, Inc.          --
--                                                                          --
-- 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- --
-- 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.                                                      --
--                                                                          --
-- 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 ALI.Util; use ALI.Util;
with Csets;
with Debug;
with Fmap;
with Fname;    use Fname;
with Fname.SF; use Fname.SF;
with Fname.UF; use Fname.UF;
with Gnatvsn;  use Gnatvsn;
with Hostparm; use Hostparm;
with Makeusg;
with Makeutl;  use Makeutl;
with MLib.Prj;
with MLib.Tgt; use MLib.Tgt;
with MLib.Utl;
with Namet;    use Namet;
with Opt;      use Opt;
with Osint.M;  use Osint.M;
with Osint;    use Osint;
with Output;   use Output;
with Prj;      use Prj;
with Prj.Com;
with Prj.Env;
with Prj.Pars;
with Prj.Util;
with SFN_Scan;
with Sinput.P;
with Snames;   use Snames;
with Switch;   use Switch;
with Switch.M; use Switch.M;
with Targparm;
with Tempdir;

with Ada.Exceptions;            use Ada.Exceptions;
with Ada.Command_Line;          use Ada.Command_Line;

with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with GNAT.Case_Util;            use GNAT.Case_Util;

with System.HTable;

package body Make is

   use ASCII;
   --  Make control characters visible

   Standard_Library_Package_Body_Name : constant String := "s-stalib.adb";
   --  Every program depends on this package, that must then be checked,
   --  especially when -f and -a are used.

   type Sigint_Handler is access procedure;

   procedure Install_Int_Handler (Handler : Sigint_Handler);
   pragma Import (C, Install_Int_Handler, "__gnat_install_int_handler");
   --  Called by Gnatmake to install the SIGINT handler below

   procedure Sigint_Intercepted;
   --  Called when the program is interrupted by Ctrl-C to delete the
   --  temporary mapping files and configuration pragmas files.

   -------------------------
   -- Note on terminology --
   -------------------------

   --  In this program, we use the phrase "termination" of a file name to
   --  refer to the suffix that appears after the unit name portion. Very
   --  often this is simply the extension, but in some cases, the sequence
   --  may be more complex, for example in main.1.ada, the termination in
   --  this name is ".1.ada" and in main_.ada the termination is "_.ada".

   -------------------------------------
   -- Queue (Q) Manipulation Routines --
   -------------------------------------

   --  The Q is used in Compile_Sources below. Its implementation uses the
   --  GNAT generic package Table (basically an extensible array). Q_Front
   --  points to the first valid element in the Q, whereas Q.First is the first
   --  element ever enqueued, while Q.Last - 1 is the last element in the Q.
   --
   --        +---+--------------+---+---+---+-----------+---+--------
   --    Q   |   |  ........    |   |   |   | .......   |   |
   --        +---+--------------+---+---+---+-----------+---+--------
   --          ^                  ^                       ^
   --       Q.First             Q_Front               Q.Last - 1
   --
   --  The elements comprised between Q.First and Q_Front - 1 are the
   --  elements that have been enqueued and then dequeued, while the
   --  elements between Q_Front and Q.Last - 1 are the elements currently
   --  in the Q. When the Q is initialized Q_Front = Q.First = Q.Last.
   --  After Compile_Sources has terminated its execution, Q_Front = Q.Last
   --  and the elements contained between Q.Front and Q.Last-1 are those that
   --  were explored and thus marked by Compile_Sources. Whenever the Q is
   --  reinitialized, the elements between Q.First and Q.Last - 1 are unmarked.

   procedure Init_Q;
   --  Must be called to (re)initialize the Q

   procedure Insert_Q
     (Source_File : File_Name_Type;
      Source_Unit : Unit_Name_Type := No_Name;
      Index       : Int            := 0);
   --  Inserts Source_File at the end of Q. Provide Source_Unit when possible
   --  for external use (gnatdist). Provide index for multi-unit sources.

   function Empty_Q return Boolean;
   --  Returns True if Q is empty

   procedure Extract_From_Q
     (Source_File  : out File_Name_Type;
      Source_Unit  : out Unit_Name_Type;
      Source_Index : out Int);
   --  Extracts the first element from the Q

   procedure Insert_Project_Sources
     (The_Project  : Project_Id;
      All_Projects : Boolean;
      Into_Q       : Boolean);
   --  If Into_Q is True, insert all sources of the project file(s) that are
   --  not already marked into the Q. If Into_Q is False, call Osint.Add_File
   --  for the first source, then insert all other sources that are not already
   --  marked into the Q. If All_Projects is True, all sources of all projects
   --  are concerned; otherwise, only sources of The_Project are concerned,
   --  including, if The_Project is an extending project, sources inherited
   --  from projects being extended.

   First_Q_Initialization : Boolean := True;
   --  Will be set to false after Init_Q has been called once

   Q_Front : Natural;
   --  Points to the first valid element in the Q

   Unique_Compile : Boolean := False;
   --  Set to True if -u or -U or a project file with no main is used

   Unique_Compile_All_Projects : Boolean := False;
   --  Set to True if -U is used

   RTS_Specified : String_Access := null;
   --  Used to detect multiple --RTS= switches

   type Q_Record is record
      File  : File_Name_Type;
      Unit  : Unit_Name_Type;
      Index : Int;
   end record;
   --  File is the name of the file to compile. Unit is for gnatdist
   --  use in order to easily get the unit name of a file to compile
   --  when its name is krunched or declared in gnat.adc. Index, when not 0,
   --  is the index of the unit in a multi-unit source.

   package Q is new Table.Table (
     Table_Component_Type => Q_Record,
     Table_Index_Type     => Natural,
     Table_Low_Bound      => 0,
     Table_Initial        => 4000,
     Table_Increment      => 100,
     Table_Name           => "Make.Q");
   --  This is the actual Q

   --  The following instantiations and variables are necessary to save what
   --  is found on the command line, in case there is a project file specified.

   package Saved_Gcc_Switches is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Make.Saved_Gcc_Switches");

   package Saved_Binder_Switches is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Make.Saved_Binder_Switches");

   package Saved_Linker_Switches is new Table.Table
     (Table_Component_Type => String_Access,
      Table_Index_Type     => Integer,
      Table_Low_Bound      => 1,
      Table_Initial        => 20,
      Table_Increment      => 100,
      Table_Name           => "Make.Saved_Linker_Switches");

   package Switches_To_Check is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Make.Switches_To_Check");

   package Library_Paths is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Make.Library_Paths");

   package Failed_Links is new Table.Table (
     Table_Component_Type => File_Name_Type,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 10,
     Table_Increment      => 100,
     Table_Name           => "Make.Failed_Links");

   package Successful_Links is new Table.Table (
     Table_Component_Type => File_Name_Type,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 10,
     Table_Increment      => 100,
     Table_Name           => "Make.Successful_Links");

   package Library_Projs is new Table.Table (
     Table_Component_Type => Project_Id,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 10,
     Table_Increment      => 100,
     Table_Name           => "Make.Library_Projs");

   --  Two variables to keep the last binder and linker switch index
   --  in tables Binder_Switches and Linker_Switches, before adding
   --  switches from the project file (if any) and switches from the
   --  command line (if any).

   Last_Binder_Switch : Integer := 0;
   Last_Linker_Switch : Integer := 0;

   Normalized_Switches : Argument_List_Access := new Argument_List (1 .. 10);
   Last_Norm_Switch    : Natural := 0;

   Saved_Maximum_Processes : Natural := 0;

   type Arg_List_Ref is access Argument_List;
   The_Saved_Gcc_Switches : Arg_List_Ref;

   Project_File_Name : String_Access  := null;
   --  The path name of the main project file, if any

   Project_File_Name_Present : Boolean := False;
   --  True when -P is used with a space between -P and the project file name

   Current_Verbosity : Prj.Verbosity  := Prj.Default;
   --  Verbosity to parse the project files

   Main_Project : Prj.Project_Id := No_Project;
   --  The project id of the main project file, if any

   Project_Object_Directory : Project_Id := No_Project;
   --  The object directory of the project for the last compilation.
   --  Avoid calling Change_Dir if the current working directory is already
   --  this directory

   --  Packages of project files where unknown attributes are errors

   Naming_String   : aliased String := "naming";
   Builder_String  : aliased String := "builder";
   Compiler_String : aliased String := "compiler";
   Binder_String   : aliased String := "binder";
   Linker_String   : aliased String := "linker";

   Gnatmake_Packages : aliased String_List :=
     (Naming_String   'Access,
      Builder_String  'Access,
      Compiler_String 'Access,
      Binder_String   'Access,
      Linker_String   'Access);

   Packages_To_Check_By_Gnatmake : constant String_List_Access :=
     Gnatmake_Packages'Access;

   procedure Add_Source_Dir (N : String);
   --  Call Add_Src_Search_Dir.
   --  Output one line when in verbose mode.

   procedure Add_Source_Directories is
     new Prj.Env.For_All_Source_Dirs (Action => Add_Source_Dir);

   procedure Add_Object_Dir (N : String);
   --  Call Add_Lib_Search_Dir.
   --  Output one line when in verbose mode.

   procedure Add_Object_Directories is
     new Prj.Env.For_All_Object_Dirs (Action => Add_Object_Dir);

   procedure Change_To_Object_Directory (Project : Project_Id);
   --  Change to the object directory of project Project, if this is not
   --  already the current working directory.

   type Bad_Compilation_Info is record
      File  : File_Name_Type;
      Unit  : Unit_Name_Type;
      Found : Boolean;
   end record;
   --  File is the name of the file for which a compilation failed.
   --  Unit is for gnatdist use in order to easily get the unit name
   --  of a file when its name is krunched or declared in gnat.adc.
   --  Found is False if the compilation failed because the file could
   --  not be found.

   package Bad_Compilation is new Table.Table (
     Table_Component_Type => Bad_Compilation_Info,
     Table_Index_Type     => Natural,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Make.Bad_Compilation");
   --  Full name of all the source files for which compilation fails

   Do_Compile_Step : Boolean := True;
   Do_Bind_Step    : Boolean := True;
   Do_Link_Step    : Boolean := True;
   --  Flags to indicate what step should be executed.
   --  Can be set to False with the switches -c, -b and -l.
   --  These flags are reset to True for each invokation of procedure Gnatmake.

   Shared_String           : aliased String := "-shared";
   Force_Elab_Flags_String : aliased String := "-F";

   No_Shared_Switch : aliased Argument_List := (1 .. 0 => null);
   Shared_Switch    : aliased Argument_List := (1 => Shared_String'Access);
   Bind_Shared      : Argument_List_Access := No_Shared_Switch'Access;
   --  Switch to added in front of gnatbind switches. By default no switch is
   --  added. Switch "-shared" is added if there is a non-static Library
   --  Project File.

   Shared_Libgcc : aliased String := "-shared-libgcc";

   No_Shared_Libgcc_Switch : aliased Argument_List := (1 .. 0 => null);
   Shared_Libgcc_Switch    : aliased Argument_List :=
                               (1 => Shared_Libgcc'Access);
   Link_With_Shared_Libgcc : Argument_List_Access :=
                               No_Shared_Libgcc_Switch'Access;

   procedure Make_Failed (S1 : String; S2 : String := ""; S3 : String := "");
   --  Delete all temp files created by Gnatmake and call Osint.Fail,
   --  with the parameter S1, S2 and S3 (see osint.ads).
   --  This is called from the Prj hierarchy and the MLib hierarchy.

   --------------------------
   -- Obsolete Executables --
   --------------------------

   Executable_Obsolete : Boolean := False;
   --  Executable_Obsolete is initially set to False for each executable,
   --  and is set to True whenever one of the source of the executable is
   --  compiled, or has already been compiled for another executable.

   Max_Header : constant := 200;
   --  This needs a proper comment, it used to say "arbitrary"
   --  that's not an adequate comment ???

   type Header_Num is range 1 .. Max_Header;
   --  Header_Num for the hash table Obsoleted below

   function Hash (F : Name_Id) return Header_Num;
   --  Hash function for the hash table Obsoleted below

   package Obsoleted is new System.HTable.Simple_HTable
     (Header_Num => Header_Num,
      Element    => Boolean,
      No_Element => False,
      Key        => Name_Id,
      Hash       => Hash,
      Equal      => "=");
   --  A hash table to keep all files that have been compiled, to detect
   --  if an executable is up to date or not.

   procedure Enter_Into_Obsoleted (F : Name_Id);
   --  Enter a file name, without directory information, into the has table
   --  Obsoleted.

   function Is_In_Obsoleted (F : Name_Id) return Boolean;
   --  Check if a file name, without directory information, has already been
   --  entered into the hash table Obsoleted.

   type Dependency is record
      This       : Name_Id;
      Depends_On : Name_Id;
   end record;
   --  Components of table Dependencies below

   package Dependencies is new Table.Table (
     Table_Component_Type => Dependency,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Make.Dependencies");
   --  A table to keep dependencies, to be able to decide if an executable
   --  is obsolete.

   procedure Add_Dependency (S : Name_Id; On : Name_Id);
   --  Add one entry in table Dependencies

   ----------------------------
   -- Arguments and Switches --
   ----------------------------

   Arguments : Argument_List_Access;
   --  Used to gather the arguments for invocation of the compiler

   Last_Argument : Natural := 0;
   --  Last index of arguments in Arguments above

   Arguments_Collected : Boolean := False;
   --  Set to True when the arguments for the next invocation of the compiler
   --  have been collected.

   Arguments_Project : Project_Id;
   --  Project id, if any, of the source to be compiled

   Arguments_Path_Name : File_Name_Type;
   --  Full path of the source to be compiled, when Arguments_Project is not
   --  No_Project.

   Dummy_Switch : constant String_Access := new String'("- ");
   --  Used to initialized Prev_Switch in procedure Check

   procedure Add_Arguments (Args : Argument_List);
   --  Add arguments to global variable Arguments, increasing its size
   --  if necessary and adjusting Last_Argument.

   function Configuration_Pragmas_Switch
     (For_Project : Project_Id) return Argument_List;
   --  Return an argument list of one element, if there is a configuration
   --  pragmas file to be specified for For_Project,
   --  otherwise return an empty argument list.

   -------------------
   -- Misc Routines --
   -------------------

   procedure List_Depend;
   --  Prints to standard output the list of object dependencies. This list
   --  can be used directly in a Makefile. A call to Compile_Sources must
   --  precede the call to List_Depend. Also because this routine uses the
   --  ALI files that were originally loaded and scanned by Compile_Sources,
   --  no additional ALI files should be scanned between the two calls (i.e.
   --  between the call to Compile_Sources and List_Depend.)

   procedure Inform (N : Name_Id := No_Name; Msg : String);
   --  Prints out the program name followed by a colon, N and S

   procedure List_Bad_Compilations;
   --  Prints out the list of all files for which the compilation failed

   procedure Verbose_Msg
     (N1     : Name_Id;
      S1     : String;
      N2     : Name_Id := No_Name;
      S2     : String  := "";
      Prefix : String  := "  -> ");
   --  If the verbose flag (Verbose_Mode) is set then print Prefix to standard
   --  output followed by N1 and S1. If N2 /= No_Name then N2 is printed after
   --  S1. S2 is printed last. Both N1 and N2 are printed in quotation marks.

   Usage_Needed : Boolean := True;
   --  Flag used to make sure Makeusg is call at most once

   procedure Usage;
   --  Call Makeusg, if Usage_Needed is True.
   --  Set Usage_Needed to False.

   procedure Debug_Msg (S : String; N : Name_Id);
   --  If Debug.Debug_Flag_W is set outputs string S followed by name N

   procedure Recursive_Compute_Depth
     (Project : Project_Id;
      Depth   : Natural);
   --  Compute depth of Project and of the projects it depends on

   -----------------------
   -- Gnatmake Routines --
   -----------------------

   Gnatmake_Called : Boolean := False;
   --  Set to True when procedure Gnatmake is called.
   --  Attempt to delete temporary files is made only when Gnatmake_Called
   --  is True.

   subtype Lib_Mark_Type is Byte;
   --  Used in Mark_Directory

   Ada_Lib_Dir : constant Lib_Mark_Type := 1;
   --  Used to mark a directory as a GNAT lib dir

   --  Note that the notion of GNAT lib dir is no longer used. The code
   --  related to it has not been removed to give an idea on how to use
   --  the directory prefix marking mechanism.

   --  An Ada library directory is a directory containing ali and object
   --  files but no source files for the bodies (the specs can be in the
   --  same or some other directory). These directories are specified
   --  in the Gnatmake command line with the switch "-Adir" (to specify the
   --  spec location -Idir cab be used).  Gnatmake skips the missing sources
   --  whose ali are in Ada library directories. For an explanation of why
   --  Gnatmake behaves that way, see the spec of Make.Compile_Sources.
   --  The directory lookup penalty is incurred every single time this
   --  routine is called.

   procedure Check_Steps;
   --  Check what steps (Compile, Bind, Link) must be executed.
   --  Set the step flags accordingly.

   function In_Ada_Lib_Dir  (File : File_Name_Type) return Boolean;
   --  Get directory prefix of this file and get lib mark stored in name
   --  table for this directory. Then check if an Ada lib mark has been set.

   procedure Mark_Directory
     (Dir  : String;
      Mark : Lib_Mark_Type);
   --  Store Dir in name table and set lib mark as name info to identify
   --  Ada libraries.

   Output_Is_Object : Boolean := True;
   --  Set to False when using a switch -S for the compiler

   procedure Check_For_S_Switch;
   --  Set Output_Is_Object to False when the -S switch is used for the
   --  compiler.

   function Switches_Of
     (Source_File      : Name_Id;
      Source_File_Name : String;
      Source_Index     : Int;
      Naming           : Naming_Data;
      In_Package       : Package_Id;
      Allow_ALI        : Boolean) return Variable_Value;
   --  Return the switches for the source file in the specified package
   --  of a project file. If the Source_File ends with a standard GNAT
   --  extension (".ads" or ".adb"), try first the full name, then the
   --  name without the extension, then, if Allow_ALI is True, the name with
   --  the extension ".ali". If there is no switches for either names, try the
   --  default switches for Ada. If all failed, return No_Variable_Value.

   function Is_In_Object_Directory
     (Source_File   : File_Name_Type;
      Full_Lib_File : File_Name_Type) return Boolean;
   --  Check if, when using a project file, the ALI file is in the project
   --  directory of the ultimate extending project. If it is not, we ignore
   --  the fact that this ALI file is read-only.

   ----------------------------------------------------
   -- Compiler, Binder & Linker Data and Subprograms --
   ----------------------------------------------------

   Gcc             : String_Access := Program_Name ("gcc");
   Gnatbind        : String_Access := Program_Name ("gnatbind");
   Gnatlink        : String_Access := Program_Name ("gnatlink");
   --  Default compiler, binder, linker programs

   Saved_Gcc       : String_Access := null;
   Saved_Gnatbind  : String_Access := null;
   Saved_Gnatlink  : String_Access := null;
   --  Given by the command line. Will be used, if non null

   Gcc_Path        : String_Access :=
                       GNAT.OS_Lib.Locate_Exec_On_Path (Gcc.all);
   Gnatbind_Path   : String_Access :=
                       GNAT.OS_Lib.Locate_Exec_On_Path (Gnatbind.all);
   Gnatlink_Path   : String_Access :=
                       GNAT.OS_Lib.Locate_Exec_On_Path (Gnatlink.all);
   --  Path for compiler, binder, linker programs, defaulted now for gnatdist.
   --  Changed later if overridden on command line.

   Comp_Flag         : constant String_Access := new String'("-c");
   Output_Flag       : constant String_Access := new String'("-o");
   Ada_Flag_1        : constant String_Access := new String'("-x");
   Ada_Flag_2        : constant String_Access := new String'("ada");
   No_gnat_adc       : constant String_Access := new String'("-gnatA");
   GNAT_Flag         : constant String_Access := new String'("-gnatpg");
   Do_Not_Check_Flag : constant String_Access := new String'("-x");

   Object_Suffix     : constant String := Get_Object_Suffix.all;
   Executable_Suffix : constant String := Get_Executable_Suffix.all;

   Syntax_Only : Boolean := False;
   --  Set to True when compiling with -gnats

   Display_Executed_Programs : Boolean := True;
   --  Set to True if name of commands should be output on stderr

   Output_File_Name_Seen : Boolean := False;
   --  Set to True after having scanned the file_name for
   --  switch "-o file_name"

   Object_Directory_Seen : Boolean := False;
   --  Set to True after having scanned the object directory for
   --  switch "-D obj_dir".

   Object_Directory_Path : String_Access := null;
   --  The path name of the object directory, set with switch -D

   type Make_Program_Type is (None, Compiler, Binder, Linker);

   Program_Args : Make_Program_Type := None;
   --  Used to indicate if we are scanning gnatmake, gcc, gnatbind, or gnatbind
   --  options within the gnatmake command line. Used in Scan_Make_Arg only,
   --  but must be global since value preserved from one call to another.

   Temporary_Config_File : Boolean := False;
   --  Set to True when there is a temporary config file used for a project
   --  file, to avoid displaying the -gnatec switch for a temporary file.

   procedure Add_Switches
     (The_Package : Package_Id;
      File_Name   : String;
      Index       : Int;
      Program     : Make_Program_Type);
   procedure Add_Switch
     (S             : String_Access;
      Program       : Make_Program_Type;
      Append_Switch : Boolean := True;
      And_Save      : Boolean := True);
   procedure Add_Switch
     (S             : String;
      Program       : Make_Program_Type;
      Append_Switch : Boolean := True;
      And_Save      : Boolean := True);
   --  Make invokes one of three programs (the compiler, the binder or the
   --  linker). For the sake of convenience, some program specific switches
   --  can be passed directly on the gnatmake commande line. This procedure
   --  records these switches so that gnamake can pass them to the right
   --  program.  S is the switch to be added at the end of the command line
   --  for Program if Append_Switch is True. If Append_Switch is False S is
   --  added at the beginning of the command line.

   procedure Check
     (Source_File  : File_Name_Type;
      Source_Index : Int;
      The_Args     : Argument_List;
      Lib_File     : File_Name_Type;
      Read_Only    : Boolean;
      ALI          : out ALI_Id;
      O_File       : out File_Name_Type;
      O_Stamp      : out Time_Stamp_Type);
   --  Determines whether the library file Lib_File is up-to-date or not. The
   --  full name (with path information) of the object file corresponding to
   --  Lib_File is returned in O_File. Its time stamp is saved in O_Stamp.
   --  ALI is the ALI_Id corresponding to Lib_File. If Lib_File in not
   --  up-to-date, then the corresponding source file needs to be recompiled.
   --  In this case ALI = No_ALI_Id.

   procedure Check_Linker_Options
     (E_Stamp : Time_Stamp_Type;
      O_File  : out File_Name_Type;
      O_Stamp : out Time_Stamp_Type);
   --  Checks all linker options for linker files that are newer
   --  than E_Stamp. If such objects are found, the youngest object
   --  is returned in O_File and its stamp in O_Stamp.
   --
   --  If no obsolete linker files were found, the first missing
   --  linker file is returned in O_File and O_Stamp is empty.
   --  Otherwise O_File is No_File.

   procedure Collect_Arguments
     (Source_File  : File_Name_Type;
      Source_Index : Int;
      Args         : Argument_List);
   --  Collect all arguments for a source to be compiled, including those
   --  that come from a project file.

   procedure Display (Program : String; Args : Argument_List);
   --  Displays Program followed by the arguments in Args if variable
   --  Display_Executed_Programs is set. The lower bound of Args must be 1.

   -----------------
   --  Mapping files
   -----------------

   type Temp_File_Names is
     array (Project_Id range <>, Positive range <>) of Name_Id;

   type Temp_Files_Ptr is access Temp_File_Names;

   type Indices is array (Project_Id range <>) of Natural;

   type Indices_Ptr is access Indices;

   type Free_File_Indices is array
     (Project_Id range <>, Positive range <>) of Positive;

   type Free_Indices_Ptr is access Free_File_Indices;

   The_Mapping_File_Names : Temp_Files_Ptr;
   --  For each project, the name ids of the temporary mapping files used

   Last_Mapping_File_Names : Indices_Ptr;
   --  For each project, the index of the last mapping file created

   The_Free_Mapping_File_Indices : Free_Indices_Ptr;
   --  For each project, the indices in The_Mapping_File_Names of the mapping
   --  file names that can be reused for subsequent compilations.

   Last_Free_Indices : Indices_Ptr;
   --  For each project, the number of mapping files that can be reused

   Gnatmake_Mapping_File : String_Access := null;
   --  The path name of a mapping file specified by switch -C=

   procedure Delete_Mapping_Files;
   --  Delete all temporary mapping files

   procedure Init_Mapping_File
     (Project : Project_Id;
      File_Index : in out Natural);
   --  Create a new temporary mapping file, and fill it with the project file
   --  mappings, when using project file(s). The out parameter File_Index is
   --  the index to the name of the file in the array The_Mapping_File_Names.

   procedure Delete_Temp_Config_Files;
   --  Delete all temporary config files

   procedure Delete_All_Temp_Files;
   --  Delete all temp files (config files, mapping files, path files)

   -------------------
   -- Add_Arguments --
   -------------------

   procedure Add_Arguments (Args : Argument_List) is
   begin
      if Arguments = null then
         Arguments := new Argument_List (1 .. Args'Length + 10);

      else
         while Last_Argument + Args'Length > Arguments'Last loop
            declare
               New_Arguments : constant Argument_List_Access :=
                                 new Argument_List (1 .. Arguments'Last * 2);
            begin
               New_Arguments (1 .. Last_Argument) :=
                 Arguments (1 .. Last_Argument);
               Arguments := New_Arguments;
            end;
         end loop;
      end if;

      Arguments (Last_Argument + 1 .. Last_Argument + Args'Length) := Args;
      Last_Argument := Last_Argument + Args'Length;
   end Add_Arguments;

   --------------------
   -- Add_Dependency --
   --------------------

   procedure Add_Dependency (S : Name_Id; On : Name_Id) is
   begin
      Dependencies.Increment_Last;
      Dependencies.Table (Dependencies.Last) := (S, On);
   end Add_Dependency;

   --------------------
   -- Add_Object_Dir --
   --------------------

   procedure Add_Object_Dir (N : String) is
   begin
      Add_Lib_Search_Dir (N);

      if Verbose_Mode then
         Write_Str ("Adding object directory """);
         Write_Str (N);
         Write_Str (""".");
         Write_Eol;
      end if;
   end Add_Object_Dir;

   --------------------
   -- Add_Source_Dir --
   --------------------

   procedure Add_Source_Dir (N : String) is
   begin
      Add_Src_Search_Dir (N);

      if Verbose_Mode then
         Write_Str ("Adding source directory """);
         Write_Str (N);
         Write_Str (""".");
         Write_Eol;
      end if;
   end Add_Source_Dir;

   ----------------
   -- Add_Switch --
   ----------------

   procedure Add_Switch
     (S             : String_Access;
      Program       : Make_Program_Type;
      Append_Switch : Boolean := True;
      And_Save      : Boolean := True)
   is
      generic
         with package T is new Table.Table (<>);
      procedure Generic_Position (New_Position : out Integer);
      --  Generic procedure that chooses a position for S in T at the
      --  beginning or the end, depending on the boolean Append_Switch.
      --  Calling this procedure may expand the table.

      ----------------------
      -- Generic_Position --
      ----------------------

      procedure  Generic_Position (New_Position : out Integer) is
      begin
         T.Increment_Last;

         if Append_Switch then
            New_Position := Integer (T.Last);
         else
            for J in reverse T.Table_Index_Type'Succ (T.First) .. T.Last loop
               T.Table (J) := T.Table (T.Table_Index_Type'Pred (J));
            end loop;

            New_Position := Integer (T.First);
         end if;
      end Generic_Position;

      procedure Gcc_Switches_Pos    is new Generic_Position (Gcc_Switches);
      procedure Binder_Switches_Pos is new Generic_Position (Binder_Switches);
      procedure Linker_Switches_Pos is new Generic_Position (Linker_Switches);

      procedure Saved_Gcc_Switches_Pos is new
        Generic_Position (Saved_Gcc_Switches);

      procedure Saved_Binder_Switches_Pos is new
        Generic_Position (Saved_Binder_Switches);

      procedure Saved_Linker_Switches_Pos is new
        Generic_Position (Saved_Linker_Switches);

      New_Position : Integer;

   --  Start of processing for Add_Switch

   begin
      if And_Save then
         case Program is
            when Compiler =>
               Saved_Gcc_Switches_Pos (New_Position);
               Saved_Gcc_Switches.Table (New_Position) := S;

            when Binder   =>
               Saved_Binder_Switches_Pos (New_Position);
               Saved_Binder_Switches.Table (New_Position) := S;

            when Linker   =>
               Saved_Linker_Switches_Pos (New_Position);
               Saved_Linker_Switches.Table (New_Position) := S;

            when None =>
               raise Program_Error;
         end case;

      else
         case Program is
            when Compiler =>
               Gcc_Switches_Pos (New_Position);
               Gcc_Switches.Table (New_Position) := S;

            when Binder   =>
               Binder_Switches_Pos (New_Position);
               Binder_Switches.Table (New_Position) := S;

            when Linker   =>
               Linker_Switches_Pos (New_Position);
               Linker_Switches.Table (New_Position) := S;

            when None =>
               raise Program_Error;
         end case;
      end if;
   end Add_Switch;

   procedure Add_Switch
     (S             : String;
      Program       : Make_Program_Type;
      Append_Switch : Boolean := True;
      And_Save      : Boolean := True)
   is
   begin
      Add_Switch (S             => new String'(S),
                  Program       => Program,
                  Append_Switch => Append_Switch,
                  And_Save      => And_Save);
   end Add_Switch;

   ------------------
   -- Add_Switches --
   ------------------

   procedure Add_Switches
     (The_Package : Package_Id;
      File_Name   : String;
      Index       : Int;
      Program     : Make_Program_Type)
   is
      Switches    : Variable_Value;
      Switch_List : String_List_Id;
      Element     : String_Element;

   begin
      if File_Name'Length > 0 then
         Name_Len := File_Name'Length;
         Name_Buffer (1 .. Name_Len) := File_Name;
         Switches :=
           Switches_Of
           (Source_File      => Name_Find,
            Source_File_Name => File_Name,
            Source_Index     => Index,
            Naming           => Projects.Table (Main_Project).Naming,
            In_Package       => The_Package,
            Allow_ALI        =>
              Program = Binder or else Program = Linker);

         case Switches.Kind is
            when Undefined =>
               null;

            when List =>
               Program_Args := Program;

               Switch_List := Switches.Values;

               while Switch_List /= Nil_String loop
                  Element := String_Elements.Table (Switch_List);
                  Get_Name_String (Element.Value);

                  if Name_Len > 0 then
                     declare
                        Argv : constant String := Name_Buffer (1 .. Name_Len);
                        --  We need a copy, because Name_Buffer may be
                        --  modified.

                     begin
                        if Verbose_Mode then
                           Write_Str ("   Adding ");
                           Write_Line (Argv);
                        end if;

                        Scan_Make_Arg (Argv, And_Save => False);
                     end;
                  end if;

                  Switch_List := Element.Next;
               end loop;

            when Single =>
               Program_Args := Program;
               Get_Name_String (Switches.Value);

               if Name_Len > 0 then
                  declare
                     Argv : constant String := Name_Buffer (1 .. Name_Len);
                     --  We need a copy, because Name_Buffer may be modified

                  begin
                     if Verbose_Mode then
                        Write_Str ("   Adding ");
                        Write_Line (Argv);
                     end if;

                     Scan_Make_Arg (Argv, And_Save => False);
                  end;
               end if;
         end case;
      end if;
   end Add_Switches;

   ----------
   -- Bind --
   ----------

   procedure Bind (ALI_File : File_Name_Type; Args : Argument_List) is
      Bind_Args : Argument_List (1 .. Args'Last + 2);
      Bind_Last : Integer;
      Success   : Boolean;

   begin
      pragma Assert (Args'First = 1);

      --  Optimize the simple case where the gnatbind command line looks like
      --     gnatbind -aO. -I- file.ali   --into->   gnatbind file.adb

      if Args'Length = 2
        and then Args (Args'First).all = "-aO" & Normalized_CWD
        and then Args (Args'Last).all = "-I-"
        and then ALI_File = Strip_Directory (ALI_File)
      then
         Bind_Last := Args'First - 1;

      else
         Bind_Last := Args'Last;
         Bind_Args (Args'Range) := Args;
      end if;

      --  It is completely pointless to re-check source file time stamps.
      --  This has been done already by gnatmake

      Bind_Last := Bind_Last + 1;
      Bind_Args (Bind_Last) := Do_Not_Check_Flag;

      Get_Name_String (ALI_File);

      Bind_Last := Bind_Last + 1;
      Bind_Args (Bind_Last) := new String'(Name_Buffer (1 .. Name_Len));

      GNAT.OS_Lib.Normalize_Arguments (Bind_Args (Args'First .. Bind_Last));

      Display (Gnatbind.all, Bind_Args (Args'First .. Bind_Last));

      if Gnatbind_Path = null then
         Make_Failed ("error, unable to locate ", Gnatbind.all);
      end if;

      GNAT.OS_Lib.Spawn
        (Gnatbind_Path.all, Bind_Args (Args'First .. Bind_Last), Success);

      if not Success then
         raise Bind_Failed;
      end if;
   end Bind;

   --------------------------------
   -- Change_To_Object_Directory --
   --------------------------------

   procedure Change_To_Object_Directory (Project : Project_Id) is
   begin
      --  Nothing to do if the current working directory is alresdy the one
      --  we want.

      if Project_Object_Directory /= Project then
         Project_Object_Directory := Project;

         --  If in a real project, set the working directory to the object
         --  directory of the project.

         if Project /= No_Project then
            Change_Dir
              (Get_Name_String (Projects.Table (Project).Object_Directory));

         --  Otherwise, for sources outside of any project, set the working
         --  directory to the object directory of the main project.

         elsif Main_Project /= No_Project then
            Change_Dir
              (Get_Name_String
                 (Projects.Table (Main_Project).Object_Directory));
         end if;
      end if;
   end Change_To_Object_Directory;

   -----------
   -- Check --
   -----------

   procedure Check
     (Source_File  : File_Name_Type;
      Source_Index : Int;
      The_Args     : Argument_List;
      Lib_File     : File_Name_Type;
      Read_Only    : Boolean;
      ALI          : out ALI_Id;
      O_File       : out File_Name_Type;
      O_Stamp      : out Time_Stamp_Type)
   is
      function First_New_Spec (A : ALI_Id) return File_Name_Type;
      --  Looks in the with table entries of A and returns the spec file name
      --  of the first withed unit (subprogram) for which no spec existed when
      --  A was generated but for which there exists one now, implying that A
      --  is now obsolete. If no such unit is found No_File is returned.
      --  Otherwise the spec file name of the unit is returned.
      --
      --  **WARNING** in the event of Uname format modifications, one *MUST*
      --  make sure this function is also updated.
      --
      --  Note: This function should really be in ali.adb and use Uname
      --  services, but this causes the whole compiler to be dragged along
      --  for gnatbind and gnatmake.

      --------------------
      -- First_New_Spec --
      --------------------

      function First_New_Spec (A : ALI_Id) return File_Name_Type is
         Spec_File_Name : File_Name_Type := No_File;

         function New_Spec (Uname : Unit_Name_Type) return Boolean;
         --  Uname is the name of the spec or body of some ada unit.
         --  This function returns True if the Uname is the name of a body
         --  which has a spec not mentioned inali file A. If True is returned
         --  Spec_File_Name above is set to the name of this spec file.

         --------------
         -- New_Spec --
         --------------

         function New_Spec (Uname : Unit_Name_Type) return Boolean is
            Spec_Name : Unit_Name_Type;
            File_Name : File_Name_Type;

         begin
            --  Test whether Uname is the name of a body unit (ie ends with %b)

            Get_Name_String (Uname);
            pragma
              Assert (Name_Len > 2 and then Name_Buffer (Name_Len - 1) = '%');

            if Name_Buffer (Name_Len) /= 'b' then
               return False;
            end if;

            --  Convert unit name into spec name

            --  ??? this code seems dubious in presence of pragma
            --  Source_File_Name since there is no more direct relationship
            --  between unit name and file name.

            --  ??? Further, what about alternative subunit naming

            Name_Buffer (Name_Len) := 's';
            Spec_Name := Name_Find;
            File_Name := Get_File_Name (Spec_Name, Subunit => False);

            --  Look if File_Name is mentioned in A's sdep list.
            --  If not look if the file exists. If it does return True.

            for D in
              ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep
            loop
               if Sdep.Table (D).Sfile = File_Name then
                  return False;
               end if;
            end loop;

            if Full_Source_Name (File_Name) /= No_File then
               Spec_File_Name := File_Name;
               return True;
            end if;

            return False;
         end New_Spec;

      --  Start of processing for First_New_Spec

      begin
         U_Chk : for U in
           ALIs.Table (A).First_Unit .. ALIs.Table (A).Last_Unit
         loop
            exit U_Chk when Units.Table (U).Utype = Is_Body_Only
               and then New_Spec (Units.Table (U).Uname);

            for W in Units.Table (U).First_With
                       ..
                     Units.Table (U).Last_With
            loop
               exit U_Chk when
                 Withs.Table (W).Afile /= No_File
                 and then New_Spec (Withs.Table (W).Uname);
            end loop;
         end loop U_Chk;

         return Spec_File_Name;
      end First_New_Spec;

      ---------------------------------
      -- Data declarations for Check --
      ---------------------------------

      Full_Lib_File : File_Name_Type;
      --  Full name of current library file

      Full_Obj_File : File_Name_Type;
      --  Full name of the object file corresponding to Lib_File

      Lib_Stamp : Time_Stamp_Type;
      --  Time stamp of the current ada library file

      Obj_Stamp : Time_Stamp_Type;
      --  Time stamp of the current object file

      Modified_Source : File_Name_Type;
      --  The first source in Lib_File whose current time stamp differs
      --  from that stored in Lib_File.

      New_Spec : File_Name_Type;
      --  If Lib_File contains in its W (with) section a body (for a
      --  subprogram) for which there exists a spec and the spec did not
      --  appear in the Sdep section of Lib_File, New_Spec contains the file
      --  name of this new spec.

      Source_Name : Name_Id;
      Text        : Text_Buffer_Ptr;

      Prev_Switch : String_Access;
      --  Previous switch processed

      Arg : Arg_Id := Arg_Id'First;
      --  Current index in Args.Table for a given unit (init to stop warning)

      Switch_Found : Boolean;
      --  True if a given switch has been found

   --  Start of processing for Check

   begin
      pragma Assert (Lib_File /= No_File);

      --  If the ALI file is read-only, set temporarily
      --  Check_Object_Consistency to False: we don't care if the object file
      --  is not there; presumably, a library will be used for linking.

      if Read_Only then
         declare
            Saved_Check_Object_Consistency : constant Boolean :=
                                               Check_Object_Consistency;
         begin
            Check_Object_Consistency := False;
            Text := Read_Library_Info (Lib_File);
            Check_Object_Consistency := Saved_Check_Object_Consistency;
         end;

      else
         Text := Read_Library_Info (Lib_File);
      end if;

      Full_Lib_File := Full_Library_Info_Name;
      Full_Obj_File := Full_Object_File_Name;
      Lib_Stamp     := Current_Library_File_Stamp;
      Obj_Stamp     := Current_Object_File_Stamp;

      if Full_Lib_File = No_File then
         Verbose_Msg (Lib_File, "being checked ...", Prefix => "  ");
      else
         Verbose_Msg (Full_Lib_File, "being checked ...", Prefix => "  ");
      end if;

      ALI     := No_ALI_Id;
      O_File  := Full_Obj_File;
      O_Stamp := Obj_Stamp;

      if Text = null then
         if Full_Lib_File = No_File then
            Verbose_Msg (Lib_File, "missing.");

         elsif Obj_Stamp (Obj_Stamp'First) = ' ' then
            Verbose_Msg (Full_Obj_File, "missing.");

         else
            Verbose_Msg
              (Full_Lib_File, "(" & String (Lib_Stamp) & ") newer than",
               Full_Obj_File, "(" & String (Obj_Stamp) & ")");
         end if;

      else
         ALI := Scan_ALI (Lib_File, Text, Ignore_ED => False, Err => True);
         Free (Text);

         if ALI = No_ALI_Id then
            Verbose_Msg (Full_Lib_File, "incorrectly formatted ALI file");
            return;

         elsif ALIs.Table (ALI).Ver (1 .. ALIs.Table (ALI).Ver_Len) /=
                 Verbose_Library_Version
         then
            Verbose_Msg (Full_Lib_File, "compiled with old GNAT version");
            ALI := No_ALI_Id;
            return;
         end if;

         --  Don't take Ali file into account if it was generated with
         --  errors.

         if ALIs.Table (ALI).Compile_Errors then
            Verbose_Msg (Full_Lib_File, "had errors, must be recompiled");
            ALI := No_ALI_Id;
            return;
         end if;

         --  Don't take Ali file into account if it was generated without
         --  object.

         if Operating_Mode /= Check_Semantics
           and then ALIs.Table (ALI).No_Object
         then
            Verbose_Msg (Full_Lib_File, "has no corresponding object");
            ALI := No_ALI_Id;
            return;
         end if;

         --  Check for matching compiler switches if needed

         if Check_Switches then

            --  First, collect all the switches

            Collect_Arguments (Source_File, Source_Index, The_Args);

            Prev_Switch := Dummy_Switch;

            Get_Name_String (ALIs.Table (ALI).Sfile);

            Switches_To_Check.Set_Last (0);

            for J in 1 .. Last_Argument loop

               --  Skip non switches -c, -I and -o switches

               if Arguments (J) (1) = '-'
                 and then Arguments (J) (2) /= 'c'
                 and then Arguments (J) (2) /= 'o'
                 and then Arguments (J) (2) /= 'I'
               then
                  Normalize_Compiler_Switches
                    (Arguments (J).all,
                     Normalized_Switches,
                     Last_Norm_Switch);

                  for K in 1 .. Last_Norm_Switch loop
                     Switches_To_Check.Increment_Last;
                     Switches_To_Check.Table (Switches_To_Check.Last) :=
                       Normalized_Switches (K);
                  end loop;
               end if;
            end loop;

            for J in 1 .. Switches_To_Check.Last loop

               --  Comparing switches is delicate because gcc reorders
               --  a number of switches, according to lang-specs.h, but
               --  gnatmake doesn't have the sufficient knowledge to
               --  perform the same reordering. Instead, we ignore orders
               --  between different "first letter" switches, but keep
               --  orders between same switches, e.g -O -O2 is different
               --  than -O2 -O, but -g -O is equivalent to -O -g.

               if Switches_To_Check.Table (J) (2) /= Prev_Switch (2) or else
                   (Prev_Switch'Length >= 6 and then
                    Prev_Switch (2 .. 5) = "gnat" and then
                    Switches_To_Check.Table (J)'Length >= 6 and then
                    Switches_To_Check.Table (J) (2 .. 5) = "gnat" and then
                    Prev_Switch (6) /= Switches_To_Check.Table (J) (6))
               then
                  Prev_Switch := Switches_To_Check.Table (J);
                  Arg :=
                    Units.Table (ALIs.Table (ALI).First_Unit).First_Arg;
               end if;

               Switch_Found := False;

               for K in Arg ..
                 Units.Table (ALIs.Table (ALI).First_Unit).Last_Arg
               loop
                  if
                    Switches_To_Check.Table (J).all = Args.Table (K).all
                  then
                     Arg := K + 1;
                     Switch_Found := True;
                     exit;
                  end if;
               end loop;

               if not Switch_Found then
                  if Verbose_Mode then
                     Verbose_Msg (ALIs.Table (ALI).Sfile,
                                  "switch mismatch """ &
                                  Switches_To_Check.Table (J).all & '"');
                  end if;

                  ALI := No_ALI_Id;
                  return;
               end if;
            end loop;

            if Switches_To_Check.Last /=
              Integer (Units.Table (ALIs.Table (ALI).First_Unit).Last_Arg -
                       Units.Table (ALIs.Table (ALI).First_Unit).First_Arg + 1)
            then
               if Verbose_Mode then
                  Verbose_Msg (ALIs.Table (ALI).Sfile,
                               "different number of switches");

                  for K in Units.Table (ALIs.Table (ALI).First_Unit).First_Arg
                    .. Units.Table (ALIs.Table (ALI).First_Unit).Last_Arg
                  loop
                     Write_Str (Args.Table (K).all);
                     Write_Char (' ');
                  end loop;

                  Write_Eol;

                  for J in 1 .. Switches_To_Check.Last loop
                     Write_Str (Switches_To_Check.Table (J).all);
                     Write_Char (' ');
                  end loop;

                  Write_Eol;
               end if;

               ALI := No_ALI_Id;
               return;
            end if;
         end if;

         --  Get the source files and their message digests. Note that some
         --  sources may be missing if ALI is out-of-date.

         Set_Source_Table (ALI);

         Modified_Source := Time_Stamp_Mismatch (ALI, Read_Only);

         if Modified_Source /= No_File then
            ALI := No_ALI_Id;

            if Verbose_Mode then
               Source_Name := Full_Source_Name (Modified_Source);

               if Source_Name /= No_File then
                  Verbose_Msg (Source_Name, "time stamp mismatch");
               else
                  Verbose_Msg (Modified_Source, "missing");
               end if;
            end if;

         else
            New_Spec := First_New_Spec (ALI);

            if New_Spec /= No_File then
               ALI := No_ALI_Id;

               if Verbose_Mode then
                  Source_Name := Full_Source_Name (New_Spec);

                  if Source_Name /= No_File then
                     Verbose_Msg (Source_Name, "new spec");
                  else
                     Verbose_Msg (New_Spec, "old spec missing");
                  end if;
               end if;
            end if;
         end if;
      end if;
   end Check;

   ------------------------
   -- Check_For_S_Switch --
   ------------------------

   procedure Check_For_S_Switch is
   begin
      --  By default, we generate an object file

      Output_Is_Object := True;

      for Arg in 1 .. Last_Argument loop
         if Arguments (Arg).all = "-S" then
            Output_Is_Object := False;

         elsif Arguments (Arg).all = "-c" then
            Output_Is_Object := True;
         end if;
      end loop;
   end Check_For_S_Switch;

   --------------------------
   -- Check_Linker_Options --
   --------------------------

   procedure Check_Linker_Options
     (E_Stamp   : Time_Stamp_Type;
      O_File    : out File_Name_Type;
      O_Stamp   : out Time_Stamp_Type)
   is
      procedure Check_File (File : File_Name_Type);
      --  Update O_File and O_Stamp if the given file is younger than E_Stamp
      --  and O_Stamp, or if O_File is No_File and File does not exist.

      function Get_Library_File (Name : String) return File_Name_Type;
      --  Return the full file name including path of a library based
      --  on the name specified with the -l linker option, using the
      --  Ada object path. Return No_File if no such file can be found.

      type Char_Array is array (Natural) of Character;
      type Char_Array_Access is access constant Char_Array;

      Template : Char_Array_Access;
      pragma Import (C, Template, "__gnat_library_template");

      ----------------
      -- Check_File --
      ----------------

      procedure Check_File (File : File_Name_Type) is
         Stamp : Time_Stamp_Type;
         Name  : File_Name_Type := File;

      begin
         Get_Name_String (Name);

         --  Remove any trailing NUL characters

         while Name_Len >= Name_Buffer'First
           and then Name_Buffer (Name_Len) = NUL
         loop
            Name_Len := Name_Len - 1;
         end loop;

         if Name_Len <= 0 then
            return;

         elsif Name_Buffer (1) = '-' then

            --  Do not check if File is a switch other than "-l"

            if Name_Buffer (2) /= 'l' then
               return;
            end if;

            --  The argument is a library switch, get actual name. It
            --  is necessary to make a copy of the relevant part of
            --  Name_Buffer as Get_Library_Name uses Name_Buffer as well.

            declare
               Base_Name : constant String := Name_Buffer (3 .. Name_Len);

            begin
               Name := Get_Library_File (Base_Name);
            end;

            if Name = No_File then
               return;
            end if;
         end if;

         Stamp := File_Stamp (Name);

         --  Find the youngest object file that is younger than the
         --  executable. If no such file exist, record the first object
         --  file that is not found.

         if (O_Stamp < Stamp and then E_Stamp < Stamp)
           or else (O_File = No_File and then Stamp (Stamp'First) = ' ')
         then
            O_Stamp := Stamp;
            O_File := Name;

            --  Strip the trailing NUL if present

            Get_Name_String (O_File);

            if Name_Buffer (Name_Len) = NUL then
               Name_Len := Name_Len - 1;
               O_File := Name_Find;
            end if;
         end if;
      end Check_File;

      ----------------------
      -- Get_Library_Name --
      ----------------------

      --  See comments in a-adaint.c about template syntax

      function Get_Library_File (Name : String) return File_Name_Type is
         File : File_Name_Type := No_File;

      begin
         Name_Len := 0;

         for Ptr in Template'Range loop
            case Template (Ptr) is
               when '*'    =>
                  Add_Str_To_Name_Buffer (Name);

               when ';'    =>
                  File := Full_Lib_File_Name (Name_Find);
                  exit when File /= No_File;
                  Name_Len := 0;

               when NUL    =>
                  exit;

               when others =>
                  Add_Char_To_Name_Buffer (Template (Ptr));
            end case;
         end loop;

         --  The for loop exited because the end of the template
         --  was reached. File contains the last possible file name
         --  for the library.

         if File = No_File and then Name_Len > 0 then
            File := Full_Lib_File_Name (Name_Find);
         end if;

         return File;
      end Get_Library_File;

   --  Start of processing for Check_Linker_Options

   begin
      O_File  := No_File;
      O_Stamp := (others => ' ');

      --  Process linker options from the ALI files

      for Opt in 1 .. Linker_Options.Last loop
         Check_File (Linker_Options.Table (Opt).Name);
      end loop;

      --  Process options given on the command line

      for Opt in Linker_Switches.First .. Linker_Switches.Last loop

         --  Check if the previous Opt has one of the two switches
         --  that take an extra parameter. (See GCC manual.)

         if Opt = Linker_Switches.First
           or else (Linker_Switches.Table (Opt - 1).all /= "-u"
                      and then
                    Linker_Switches.Table (Opt - 1).all /= "-Xlinker"
                      and then
                    Linker_Switches.Table (Opt - 1).all /= "-L")
         then
            Name_Len := 0;
            Add_Str_To_Name_Buffer (Linker_Switches.Table (Opt).all);
            Check_File (Name_Find);
         end if;
      end loop;

   end Check_Linker_Options;

   -----------------
   -- Check_Steps --
   -----------------

   procedure Check_Steps is
   begin
      --  If either -c, -b or -l has been specified, we will not necessarily
      --  execute all steps.

      if Make_Steps then
         Do_Compile_Step := Do_Compile_Step and Compile_Only;
         Do_Bind_Step    := Do_Bind_Step    and Bind_Only;
         Do_Link_Step    := Do_Link_Step    and Link_Only;

         --  If -c has been specified, but not -b, ignore any potential -l

         if Do_Compile_Step and then not Do_Bind_Step then
            Do_Link_Step := False;
         end if;
      end if;
   end Check_Steps;

   -----------------------
   -- Collect_Arguments --
   -----------------------

   procedure Collect_Arguments
     (Source_File  : File_Name_Type;
      Source_Index : Int;
      Args         : Argument_List)
   is
   begin
      Arguments_Collected := True;
      Arguments_Project := No_Project;
      Last_Argument := 0;
      Add_Arguments (Args);

      if Main_Project /= No_Project then
         declare
            Source_File_Name : constant String :=
                                 Get_Name_String (Source_File);
            Compiler_Package : Prj.Package_Id;
            Switches         : Prj.Variable_Value;
            Data             : Project_Data;

         begin
            Prj.Env.
              Get_Reference
              (Source_File_Name => Source_File_Name,
               Project          => Arguments_Project,
               Path             => Arguments_Path_Name);

            --  If the source is not a source of a project file, check if
            --  this is allowed.

            if Arguments_Project = No_Project then
               if not External_Unit_Compilation_Allowed then
                  Make_Failed ("external source (", Source_File_Name,
                               ") is not part of any project; cannot be " &
                               "compiled without gnatmake switch -x");
               end if;

               --  If it is allowed, simply add the saved gcc switches

               Add_Arguments (The_Saved_Gcc_Switches.all);

            else
               --  We get the project directory for the relative path
               --  switches and arguments.

               Data := Projects.Table (Arguments_Project);

               --  If the source is in an extended project, we go to
               --  the ultimate extending project.

               while Data.Extended_By /= No_Project loop
                  Arguments_Project := Data.Extended_By;
                  Data := Projects.Table (Arguments_Project);
               end loop;

               --  If building a dynamic or relocatable library, compile with
               --  PIC option, if it exists.

               if Data.Library and then Data.Library_Kind /= Static then
                  declare
                     PIC : constant String := MLib.Tgt.PIC_Option;

                  begin
                     if PIC /= "" then
                        Add_Arguments ((1 => new String'(PIC)));
                     end if;
                  end;
               end if;

               if Data.Dir_Path = null then
                  Data.Dir_Path :=
                    new String'(Get_Name_String (Data.Display_Directory));
                  Projects.Table (Arguments_Project) := Data;
               end if;

               --  We now look for package Compiler
               --  and get the switches from this package.

               Compiler_Package :=
                 Prj.Util.Value_Of
                   (Name        => Name_Compiler,
                    In_Packages => Data.Decl.Packages);

               if Compiler_Package /= No_Package then

                  --  If package Gnatmake.Compiler exists, we get
                  --  the specific switches for the current source,
                  --  or the global switches, if any.

                  Switches := Switches_Of
                    (Source_File      => Source_File,
                     Source_File_Name => Source_File_Name,
                     Source_Index     => Source_Index,
                     Naming           => Data.Naming,
                     In_Package       => Compiler_Package,
                     Allow_ALI        => False);

               end if;

               case Switches.Kind is

                  --  We have a list of switches. We add these switches,
                  --  plus the saved gcc switches.

                  when List =>

                     declare
                        Current : String_List_Id := Switches.Values;
                        Element : String_Element;
                        Number  : Natural := 0;

                     begin
                        while Current /= Nil_String loop
                           Element := String_Elements.Table (Current);
                           Number  := Number + 1;
                           Current := Element.Next;
                        end loop;

                        declare
                           New_Args : Argument_List (1 .. Number);

                        begin
                           Current := Switches.Values;

                           for Index in New_Args'Range loop
                              Element := String_Elements.Table (Current);
                              Get_Name_String (Element.Value);
                              New_Args (Index) :=
                                new String'(Name_Buffer (1 .. Name_Len));
                              Test_If_Relative_Path
                                (New_Args (Index), Parent => Data.Dir_Path);
                              Current := Element.Next;
                           end loop;

                           Add_Arguments
                             (Configuration_Pragmas_Switch
                                (Arguments_Project) &
                              New_Args & The_Saved_Gcc_Switches.all);
                        end;
                     end;

                     --  We have a single switch. We add this switch,
                     --  plus the saved gcc switches.

                  when Single =>
                     Get_Name_String (Switches.Value);

                     declare
                        New_Args : Argument_List :=
                                     (1 => new String'
                                            (Name_Buffer (1 .. Name_Len)));

                     begin
                        Test_If_Relative_Path
                          (New_Args (1), Parent => Data.Dir_Path);
                        Add_Arguments
                          (Configuration_Pragmas_Switch (Arguments_Project) &
                           New_Args & The_Saved_Gcc_Switches.all);
                     end;

                     --  We have no switches from Gnatmake.Compiler.
                     --  We add the saved gcc switches.

                  when Undefined =>
                     Add_Arguments
                       (Configuration_Pragmas_Switch (Arguments_Project) &
                        The_Saved_Gcc_Switches.all);
               end case;
            end if;
         end;
      end if;

      --  Set Output_Is_Object, depending if there is a -S switch.
      --  If the bind step is not performed, and there is a -S switch,
      --  then we will not check for a valid object file.

      Check_For_S_Switch;
   end Collect_Arguments;

   ---------------------
   -- Compile_Sources --
   ---------------------

   procedure Compile_Sources
     (Main_Source           : File_Name_Type;
      Args                  : Argument_List;
      First_Compiled_File   : out Name_Id;
      Most_Recent_Obj_File  : out Name_Id;
      Most_Recent_Obj_Stamp : out Time_Stamp_Type;
      Main_Unit             : out Boolean;
      Compilation_Failures  : out Natural;
      Main_Index            : Int      := 0;
      Check_Readonly_Files  : Boolean  := False;
      Do_Not_Execute        : Boolean  := False;
      Force_Compilations    : Boolean  := False;
      Keep_Going            : Boolean  := False;
      In_Place_Mode         : Boolean  := False;
      Initialize_ALI_Data   : Boolean  := True;
      Max_Process           : Positive := 1)
   is
      No_Mapping_File : constant Natural := 0;

      type Compilation_Data is record
         Pid              : Process_Id;
         Full_Source_File : File_Name_Type;
         Lib_File         : File_Name_Type;
         Source_Unit      : Unit_Name_Type;
         Mapping_File     : Natural := No_Mapping_File;
         Project          : Project_Id := No_Project;
         Syntax_Only      : Boolean := False;
         Output_Is_Object : Boolean := True;
      end record;

      Running_Compile : array (1 .. Max_Process) of Compilation_Data;
      --  Used to save information about outstanding compilations

      Outstanding_Compiles : Natural := 0;
      --  Current number of outstanding compiles

      Source_Unit : Unit_Name_Type;
      --  Current source unit

      Source_File : File_Name_Type;
      --  Current source file

      Full_Source_File : File_Name_Type;
      --  Full name of the current source file

      Lib_File : File_Name_Type;
      --  Current library file

      Full_Lib_File : File_Name_Type;
      --  Full name of the current library file

      Obj_File : File_Name_Type;
      --  Full name of the object file corresponding to Lib_File

      Obj_Stamp : Time_Stamp_Type;
      --  Time stamp of the current object file

      Sfile : File_Name_Type;
      --  Contains the source file of the units withed by Source_File

      ALI : ALI_Id;
      --  ALI Id of the current ALI file

      --  Comment following declarations ???

      Read_Only : Boolean := False;

      Compilation_OK  : Boolean;
      Need_To_Compile : Boolean;

      Pid  : Process_Id;
      Text : Text_Buffer_Ptr;

      Mfile : Natural := No_Mapping_File;

      Need_To_Check_Standard_Library : Boolean :=
                                         Check_Readonly_Files
                                           and not Unique_Compile;

      Mapping_File_Arg : String_Access;

      Process_Created : Boolean := False;

      procedure Add_Process
        (Pid    : Process_Id;
         Sfile  : File_Name_Type;
         Afile  : File_Name_Type;
         Uname  : Unit_Name_Type;
         Mfile  : Natural := No_Mapping_File);
      --  Adds process Pid to the current list of outstanding compilation
      --  processes and record the full name of the source file Sfile that
      --  we are compiling, the name of its library file Afile and the
      --  name of its unit Uname. If Mfile is not equal to No_Mapping_File,
      --  it is the index of the mapping file used during compilation in the
      --  array The_Mapping_File_Names.

      procedure Await_Compile
        (Sfile : out File_Name_Type;
         Afile : out File_Name_Type;
         Uname : out Unit_Name_Type;
         OK    : out Boolean);
      --  Awaits that an outstanding compilation process terminates. When
      --  it does set Sfile to the name of the source file that was compiled
      --  Afile to the name of its library file and Uname to the name of its
      --  unit. Note that this time stamp can be used to check whether the
      --  compilation did generate an object file. OK is set to True if the
      --  compilation succeeded. Note that Sfile, Afile and Uname could be
      --  resp. No_File, No_File and No_Name  if there were no compilations
      --  to wait for.

      function Bad_Compilation_Count return Natural;
      --  Returns the number of compilation failures

      procedure Check_Standard_Library;
      --  Check if s-stalib.adb needs to be compiled

      procedure Collect_Arguments_And_Compile
        (Source_File : File_Name_Type; Source_Index : Int);
      --  Collect arguments from project file (if any) and compile

      function Compile
        (S            : Name_Id;
         L            : Name_Id;
         Source_Index : Int;
         Args         : Argument_List) return Process_Id;
      --  Compiles S using Args. If S is a GNAT predefined source
      --  "-gnatpg" is added to Args. Non blocking call. L corresponds to the
      --  expected library file name. Process_Id of the process spawned to
      --  execute the compile.

      package Good_ALI is new Table.Table (
        Table_Component_Type => ALI_Id,
        Table_Index_Type     => Natural,
        Table_Low_Bound      => 1,
        Table_Initial        => 50,
        Table_Increment      => 100,
        Table_Name           => "Make.Good_ALI");
      --  Contains the set of valid ALI files that have not yet been scanned

      function Good_ALI_Present return Boolean;
      --  Returns True if any ALI file was recorded in the previous set

      procedure Get_Mapping_File (Project : Project_Id);
      --  Get a mapping file name. If there is one to be reused, reuse it.
      --  Otherwise, create a new mapping file.

      function Get_Next_Good_ALI return ALI_Id;
      --  Returns the next good ALI_Id record

      procedure Record_Failure
        (File  : File_Name_Type;
         Unit  : Unit_Name_Type;
         Found : Boolean := True);
      --  Records in the previous table that the compilation for File failed.
      --  If Found is False then the compilation of File failed because we
      --  could not find it. Records also Unit when possible.

      procedure Record_Good_ALI (A : ALI_Id);
      --  Records in the previous set the Id of an ALI file

      -----------------
      -- Add_Process --
      -----------------

      procedure Add_Process
        (Pid    : Process_Id;
         Sfile  : File_Name_Type;
         Afile  : File_Name_Type;
         Uname  : Unit_Name_Type;
         Mfile  : Natural := No_Mapping_File)
      is
         OC1 : constant Positive := Outstanding_Compiles + 1;

      begin
         pragma Assert (OC1 <= Max_Process);
         pragma Assert (Pid /= Invalid_Pid);

         Running_Compile (OC1).Pid              := Pid;
         Running_Compile (OC1).Full_Source_File := Sfile;
         Running_Compile (OC1).Lib_File         := Afile;
         Running_Compile (OC1).Source_Unit      := Uname;
         Running_Compile (OC1).Mapping_File     := Mfile;
         Running_Compile (OC1).Project          := Arguments_Project;
         Running_Compile (OC1).Syntax_Only      := Syntax_Only;
         Running_Compile (OC1).Output_Is_Object := Output_Is_Object;

         Outstanding_Compiles := OC1;
      end Add_Process;

      --------------------
      -- Await_Compile --
      -------------------

      procedure Await_Compile
        (Sfile  : out File_Name_Type;
         Afile  : out File_Name_Type;
         Uname  : out File_Name_Type;
         OK     : out Boolean)
      is
         Pid : Process_Id;
         Project : Project_Id;

      begin
         pragma Assert (Outstanding_Compiles > 0);

         Sfile := No_File;
         Afile := No_File;
         Uname := No_Name;
         OK    := False;

         --  The loop here is a work-around for a problem on VMS; in some
         --  circumstances (shared library and several executables, for
         --  example), there are child processes other than compilation
         --  processes that are received. Until this problem is resolved,
         --  we will ignore such processes.

         loop
            Wait_Process (Pid, OK);

            if Pid = Invalid_Pid then
               return;
            end if;

            for J in Running_Compile'First .. Outstanding_Compiles loop
               if Pid = Running_Compile (J).Pid then
                  Sfile := Running_Compile (J).Full_Source_File;
                  Afile := Running_Compile (J).Lib_File;
                  Uname := Running_Compile (J).Source_Unit;
                  Syntax_Only := Running_Compile (J).Syntax_Only;
                  Output_Is_Object := Running_Compile (J).Output_Is_Object;
                  Project := Running_Compile (J).Project;

                  --  If a mapping file was used by this compilation,
                  --  get its file name for reuse by a subsequent compilation

                  if Running_Compile (J).Mapping_File /= No_Mapping_File then
                     Last_Free_Indices (Project) :=
                       Last_Free_Indices (Project) + 1;
                     The_Free_Mapping_File_Indices
                       (Project, Last_Free_Indices (Project)) :=
                       Running_Compile (J).Mapping_File;
                  end if;

                  --  To actually remove this Pid and related info from
                  --  Running_Compile replace its entry with the last valid
                  --  entry in Running_Compile.

                  if J = Outstanding_Compiles then
                     null;

                  else
                     Running_Compile (J) :=
                       Running_Compile (Outstanding_Compiles);
                  end if;

                  Outstanding_Compiles := Outstanding_Compiles - 1;
                  return;
               end if;
            end loop;

            --  This child process was not one of our compilation processes;
            --  just ignore it for now.

            --  raise Program_Error;
         end loop;
      end Await_Compile;

      ---------------------------
      -- Bad_Compilation_Count --
      ---------------------------

      function Bad_Compilation_Count return Natural is
      begin
         return Bad_Compilation.Last - Bad_Compilation.First + 1;
      end Bad_Compilation_Count;

      ----------------------------
      -- Check_Standard_Library --
      ----------------------------

      procedure Check_Standard_Library is
      begin
         Need_To_Check_Standard_Library := False;

         if not Targparm.Suppress_Standard_Library_On_Target then
            declare
               Sfile  : Name_Id;
               Add_It : Boolean := True;

            begin
               Name_Len := Standard_Library_Package_Body_Name'Length;
               Name_Buffer (1 .. Name_Len) :=
                 Standard_Library_Package_Body_Name;
               Sfile := Name_Enter;

               --  If we have a special runtime, we add the standard
               --  library only if we can find it.

               if RTS_Switch then
                  Add_It :=
                    Find_File (Sfile, Osint.Source) /= No_File;
               end if;

               if Add_It then
                  if Is_Marked (Sfile) then
                     if Is_In_Obsoleted (Sfile) then
                        Executable_Obsolete := True;
                     end if;

                  else
                     Insert_Q (Sfile, Index => 0);
                     Mark (Sfile, Index => 0);
                  end if;
               end if;
            end;
         end if;
      end Check_Standard_Library;

      -----------------------------------
      -- Collect_Arguments_And_Compile --
      -----------------------------------

      procedure Collect_Arguments_And_Compile
        (Source_File : File_Name_Type; Source_Index : Int)
      is
      begin
         --  Process_Created will be set True if an attempt is made to compile
         --  the source, that is if it is not in an externally built project.

         Process_Created := False;

         --  If arguments not yet collected (in Check), collect them now

         if not Arguments_Collected then
            Collect_Arguments (Source_File, Source_Index, Args);
         end if;

         --  If we use mapping file (-P or -C switches), then get one

         if Create_Mapping_File then
            Get_Mapping_File (Arguments_Project);
         end if;

         --  If the source is part of a project file, we set the ADA_*_PATHs,
         --  check for an eventual library project, and use the full path.

         if Arguments_Project /= No_Project then
            if not Projects.Table (Arguments_Project).Externally_Built then
               Prj.Env.Set_Ada_Paths (Arguments_Project, True);

               if not Unique_Compile
                 and then MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None
               then
                  declare
                     The_Data : Project_Data :=
                                  Projects.Table (Arguments_Project);

                     Prj : Project_Id := Arguments_Project;

                  begin
                     while The_Data.Extended_By /= No_Project loop
                        Prj := The_Data.Extended_By;
                        The_Data := Projects.Table (Prj);
                     end loop;

                     if The_Data.Library
                       and then not The_Data.Need_To_Build_Lib
                     then
                        --  Add to the Q all sources of the project that
                        --  have not been marked

                        Insert_Project_Sources
                          (The_Project  => Prj,
                           All_Projects => False,
                           Into_Q       => True);

                        --  Now mark the project as processed

                        Projects.Table (Prj).Need_To_Build_Lib := True;
                     end if;
                  end;
               end if;

               --  Change to the object directory of the project file,
               --  if necessary.

               Change_To_Object_Directory (Arguments_Project);

               Pid := Compile (Arguments_Path_Name, Lib_File, Source_Index,
                               Arguments (1 .. Last_Argument));
               Process_Created := True;
            end if;

         else
            --  If this is a source outside of any project file, make sure it
            --  will be compiled in object directory of the main project file.

            if Main_Project /= No_Project then
               Change_To_Object_Directory (Arguments_Project);
            end if;

            Pid := Compile (Full_Source_File, Lib_File, Source_Index,
                            Arguments (1 .. Last_Argument));
            Process_Created := True;
         end if;
      end Collect_Arguments_And_Compile;

      -------------
      -- Compile --
      -------------

      function Compile
        (S            : Name_Id;
         L            : Name_Id;
         Source_Index : Int;
         Args         : Argument_List) return Process_Id
      is
         Comp_Args : Argument_List (Args'First .. Args'Last + 9);
         Comp_Next : Integer := Args'First;
         Comp_Last : Integer;

         function Ada_File_Name (Name : Name_Id) return Boolean;
         --  Returns True if Name is the name of an ada source file
         --  (i.e. suffix is .ads or .adb)

         -------------------
         -- Ada_File_Name --
         -------------------

         function Ada_File_Name (Name : Name_Id) return Boolean is
         begin
            Get_Name_String (Name);
            return
              Name_Len > 4
                and then Name_Buffer (Name_Len - 3 .. Name_Len - 1) = ".ad"
                and then (Name_Buffer (Name_Len) = 'b'
                            or else
                          Name_Buffer (Name_Len) = 's');
         end Ada_File_Name;

      --  Start of processing for Compile

      begin
         Enter_Into_Obsoleted (S);

         --  By default, Syntax_Only is False

         Syntax_Only := False;

         for J in Args'Range loop
            if Args (J).all = "-gnats" then

               --  If we compile with -gnats, the bind step and the link step
               --  are inhibited. Also, we set Syntax_Only to True, so that
               --  we don't fail when we don't find the ALI file, after
               --  compilation.

               Do_Bind_Step := False;
               Do_Link_Step := False;
               Syntax_Only  := True;

            elsif Args (J).all = "-gnatc" then

               --  If we compile with -gnatc, the bind step and the link step
               --  are inhibited. We set Syntax_Only to False for the case when
               --  -gnats was previously specified.

               Do_Bind_Step := False;
               Do_Link_Step := False;
               Syntax_Only  := False;
            end if;
         end loop;

         Comp_Args (Comp_Next) := Comp_Flag;
         Comp_Next := Comp_Next + 1;

         --  Optimize the simple case where the gcc command line looks like
         --     gcc -c -I. ... -I- file.adb  --into->  gcc -c ... file.adb

         if Args (Args'First).all = "-I" & Normalized_CWD
           and then Args (Args'Last).all = "-I-"
           and then S = Strip_Directory (S)
         then
            Comp_Last := Comp_Next + Args'Length - 3;
            Comp_Args (Comp_Next .. Comp_Last) :=
              Args (Args'First + 1 .. Args'Last - 1);

         else
            Comp_Last := Comp_Next + Args'Length - 1;
            Comp_Args (Comp_Next .. Comp_Last) := Args;
         end if;

         --  Set -gnatpg for predefined files (for this purpose the renamings
         --  such as Text_IO do not count as predefined). Note that we strip
         --  the directory name from the source file name becase the call to
         --  Fname.Is_Predefined_File_Name cannot deal with directory prefixes.

         declare
            Fname : constant File_Name_Type := Strip_Directory (S);

         begin
            if Is_Predefined_File_Name (Fname, False) then
               if Check_Readonly_Files then
                  Comp_Last := Comp_Last + 1;
                  Comp_Args (Comp_Last) := GNAT_Flag;

               else
                  Make_Failed
                    ("not allowed to compile """ &
                     Get_Name_String (Fname) &
                     """; use -a switch, or compile file with " &
                     """-gnatg"" switch");
               end if;
            end if;
         end;

         --  Now check if the file name has one of the suffixes familiar to
         --  the gcc driver. If this is not the case then add the ada flag
         --  "-x ada".

         if not Ada_File_Name (S) and then not Targparm.AAMP_On_Target then
            Comp_Last := Comp_Last + 1;
            Comp_Args (Comp_Last) := Ada_Flag_1;
            Comp_Last := Comp_Last + 1;
            Comp_Args (Comp_Last) := Ada_Flag_2;
         end if;

         if Source_Index /= 0 then
            declare
               Num : constant String := Source_Index'Img;
            begin
               Comp_Last := Comp_Last + 1;
               Comp_Args (Comp_Last) :=
                 new String'("-gnateI" & Num (Num'First + 1 .. Num'Last));
            end;
         end if;

         if Source_Index /= 0 or else
           L /= Strip_Directory (L) or else
           Object_Directory_Path /= null
         then
            --  Build -o argument

            Get_Name_String (L);

            for J in reverse 1 .. Name_Len loop
               if Name_Buffer (J) = '.' then
                  Name_Len := J + Object_Suffix'Length - 1;
                  Name_Buffer (J .. Name_Len) := Object_Suffix;
                  exit;
               end if;
            end loop;

            Comp_Last := Comp_Last + 1;
            Comp_Args (Comp_Last) := Output_Flag;
            Comp_Last := Comp_Last + 1;

            --  If an object directory was specified, prepend the object file
            --  name with this object directory.

            if Object_Directory_Path /= null then
               Comp_Args (Comp_Last) :=
                 new String'(Object_Directory_Path.all &
                               Name_Buffer (1 .. Name_Len));

            else
               Comp_Args (Comp_Last) :=
                 new String'(Name_Buffer (1 .. Name_Len));
            end if;
         end if;

         if Create_Mapping_File then
            Comp_Last := Comp_Last + 1;
            Comp_Args (Comp_Last) := Mapping_File_Arg;
         end if;

         Get_Name_String (S);

         Comp_Last := Comp_Last + 1;
         Comp_Args (Comp_Last) := new String'(Name_Buffer (1 .. Name_Len));

         GNAT.OS_Lib.Normalize_Arguments (Comp_Args (Args'First .. Comp_Last));

         Comp_Last := Comp_Last + 1;
         Comp_Args (Comp_Last) := new String'("-gnatez");

         Display (Gcc.all, Comp_Args (Args'First .. Comp_Last));

         if Gcc_Path = null then
            Make_Failed ("error, unable to locate ", Gcc.all);
         end if;

         return
           GNAT.OS_Lib.Non_Blocking_Spawn
             (Gcc_Path.all, Comp_Args (Args'First .. Comp_Last));
      end Compile;

      ----------------------
      -- Get_Mapping_File --
      ----------------------

      procedure Get_Mapping_File (Project : Project_Id) is
      begin
         --  If there is a mapping file ready to be reused, reuse it

         if Last_Free_Indices (Project) > 0 then
            Mfile := The_Free_Mapping_File_Indices
                       (Project, Last_Free_Indices (Project));
            Last_Free_Indices (Project) := Last_Free_Indices (Project) - 1;

         --  Otherwise, create and initialize a new one

         else
            Init_Mapping_File (Project => Project, File_Index => Mfile);
         end if;

         --  Put the name in the mapping file argument for the invocation
         --  of the compiler.

         Free (Mapping_File_Arg);
         Mapping_File_Arg :=
           new String'("-gnatem=" &
                       Get_Name_String
                         (The_Mapping_File_Names (Project, Mfile)));

      end Get_Mapping_File;

      -----------------------
      -- Get_Next_Good_ALI --
      -----------------------

      function Get_Next_Good_ALI return ALI_Id is
         ALI : ALI_Id;

      begin
         pragma Assert (Good_ALI_Present);
         ALI := Good_ALI.Table (Good_ALI.Last);
         Good_ALI.Decrement_Last;
         return ALI;
      end Get_Next_Good_ALI;

      ----------------------
      -- Good_ALI_Present --
      ----------------------

      function Good_ALI_Present return Boolean is
      begin
         return Good_ALI.First <= Good_ALI.Last;
      end Good_ALI_Present;

      --------------------
      -- Record_Failure --
      --------------------

      procedure Record_Failure
        (File  : File_Name_Type;
         Unit  : Unit_Name_Type;
         Found : Boolean := True)
      is
      begin
         Bad_Compilation.Increment_Last;
         Bad_Compilation.Table (Bad_Compilation.Last) := (File, Unit, Found);
      end Record_Failure;

      ---------------------
      -- Record_Good_ALI --
      ---------------------

      procedure Record_Good_ALI (A : ALI_Id) is
      begin
         Good_ALI.Increment_Last;
         Good_ALI.Table (Good_ALI.Last) := A;
      end Record_Good_ALI;

   --  Start of processing for Compile_Sources

   begin
      pragma Assert (Args'First = 1);

      --  Package and Queue initializations

      Good_ALI.Init;
      Output.Set_Standard_Error;

      if First_Q_Initialization then
         Init_Q;
      end if;

      if Initialize_ALI_Data then
         Initialize_ALI;
         Initialize_ALI_Source;
      end if;

      --  The following two flags affect the behavior of ALI.Set_Source_Table.
      --  We set Check_Source_Files to True to ensure that source file
      --  time stamps are checked, and we set All_Sources to False to
      --  avoid checking the presence of the source files listed in the
      --  source dependency section of an ali file (which would be a mistake
      --  since the ali file may be obsolete).

      Check_Source_Files := True;
      All_Sources        := False;

      --  Only insert in the Q if it is not already done, to avoid simultaneous
      --  compilations if -jnnn is used.

      if not Is_Marked (Main_Source, Main_Index) then
         Insert_Q (Main_Source, Index => Main_Index);
         Mark (Main_Source, Main_Index);
      end if;

      First_Compiled_File   := No_File;
      Most_Recent_Obj_File  := No_File;
      Most_Recent_Obj_Stamp := Empty_Time_Stamp;
      Main_Unit             := False;

      --  Keep looping until there is no more work to do (the Q is empty)
      --  and all the outstanding compilations have terminated

      Make_Loop : while not Empty_Q or else Outstanding_Compiles > 0 loop

         --  If the user does not want to keep going in case of errors then
         --  wait for the remaining outstanding compiles and then exit.

         if Bad_Compilation_Count > 0 and then not Keep_Going then
            while Outstanding_Compiles > 0 loop
               Await_Compile
                 (Full_Source_File, Lib_File, Source_Unit, Compilation_OK);

               if not Compilation_OK then
                  Record_Failure (Full_Source_File, Source_Unit);
               end if;
            end loop;

            exit Make_Loop;
         end if;

         --  PHASE 1: Check if there is more work that we can do (ie the Q
         --  is non empty). If there is, do it only if we have not yet used
         --  up all the available processes.

         if not Empty_Q and then Outstanding_Compiles < Max_Process then
            declare
               Source_Index : Int;
               --  Index of the current unit in the current source file

            begin
               Extract_From_Q (Source_File, Source_Unit, Source_Index);
               Full_Source_File := Osint.Full_Source_Name (Source_File);
               Lib_File         := Osint.Lib_File_Name
                 (Source_File, Source_Index);
               Full_Lib_File    := Osint.Full_Lib_File_Name (Lib_File);

               --  If this source has already been compiled, the executable is
               --  obsolete.

               if Is_In_Obsoleted (Source_File) then
                  Executable_Obsolete := True;
               end if;

               --  If the library file is an Ada library skip it

               if Full_Lib_File /= No_File
                 and then In_Ada_Lib_Dir (Full_Lib_File)
               then
                  Verbose_Msg
                    (Lib_File, "is in an Ada library", Prefix => "  ");

                  --  If the library file is a read-only library skip it, but
                  --  only if, when using project files, this library file is
                  --  in the right object directory (a read-only ALI file
                  --  in the object directory of a project being extended
                  --  should not be skipped).

               elsif Full_Lib_File /= No_File
                 and then not Check_Readonly_Files
                 and then Is_Readonly_Library (Full_Lib_File)
                 and then Is_In_Object_Directory (Source_File, Full_Lib_File)
               then
                  Verbose_Msg
                    (Lib_File, "is a read-only library", Prefix => "  ");

                  --  The source file that we are checking cannot be located

               elsif Full_Source_File = No_File then
                  Record_Failure (Source_File, Source_Unit, False);

                  --  Source and library files can be located but are internal
                  --  files

               elsif not Check_Readonly_Files
                 and then Full_Lib_File /= No_File
                 and then Is_Internal_File_Name (Source_File)
               then
                  if Force_Compilations then
                     Fail
                       ("not allowed to compile """ &
                        Get_Name_String (Source_File) &
                        """; use -a switch, or compile file with " &
                        """-gnatg"" switch");
                  end if;

                  Verbose_Msg
                    (Lib_File, "is an internal library", Prefix => "  ");

               --  The source file that we are checking can be located

               else
                  Arguments_Collected := False;

                  --  Don't waste any time if we have to recompile anyway

                  Obj_Stamp       := Empty_Time_Stamp;
                  Need_To_Compile := Force_Compilations;

                  if not Force_Compilations then
                     Read_Only :=
                       Full_Lib_File /= No_File
                       and then not Check_Readonly_Files
                       and then Is_Readonly_Library (Full_Lib_File);
                     Check (Source_File, Source_Index, Args, Lib_File,
                            Read_Only, ALI, Obj_File, Obj_Stamp);
                     Need_To_Compile := (ALI = No_ALI_Id);
                  end if;

                  if not Need_To_Compile then

                     --  The ALI file is up-to-date. Record its Id

                     Record_Good_ALI (ALI);

                     --  Record the time stamp of the most recent object file
                     --  as long as no (re)compilations are needed.

                     if First_Compiled_File = No_File
                       and then (Most_Recent_Obj_File = No_File
                                   or else Obj_Stamp > Most_Recent_Obj_Stamp)
                     then
                        Most_Recent_Obj_File  := Obj_File;
                        Most_Recent_Obj_Stamp := Obj_Stamp;
                     end if;

                  else
                     --  Is this the first file we have to compile?

                     if First_Compiled_File = No_File then
                        First_Compiled_File  := Full_Source_File;
                        Most_Recent_Obj_File := No_File;

                        if Do_Not_Execute then
                           exit Make_Loop;
                        end if;
                     end if;

                     if In_Place_Mode then

                        --  If the library file was not found, then save the
                        --  library file near the source file.

                        if Full_Lib_File = No_File then
                           Lib_File := Osint.Lib_File_Name
                             (Full_Source_File, Source_Index);

                           --  If the library file was found, then save the
                           --  library file in the same place.

                        else
                           Lib_File := Full_Lib_File;
                        end if;

                     end if;

                     --  Start the compilation and record it. We can do this
                     --  because there is at least one free process.

                     Collect_Arguments_And_Compile (Source_File, Source_Index);

                     --  Make sure we could successfully start the compilation

                     if Process_Created then
                        if Pid = Invalid_Pid then
                           Record_Failure (Full_Source_File, Source_Unit);
                        else
                           Add_Process
                             (Pid,
                              Full_Source_File,
                              Lib_File,
                              Source_Unit,
                              Mfile);
                        end if;
                     end if;
                  end if;
               end if;
            end;
         end if;

         --  PHASE 2: Now check if we should wait for a compilation to
         --  finish. This is the case if all the available processes are
         --  busy compiling sources or there is nothing else to do
         --  (that is the Q is empty and there are no good ALIs to process).

         if Outstanding_Compiles = Max_Process
           or else (Empty_Q
                     and then not Good_ALI_Present
                     and then Outstanding_Compiles > 0)
         then
            Await_Compile
              (Full_Source_File, Lib_File, Source_Unit, Compilation_OK);

            if not Compilation_OK then
               Record_Failure (Full_Source_File, Source_Unit);
            end if;

            if Compilation_OK or else Keep_Going then

               --  Re-read the updated library file

               declare
                  Saved_Object_Consistency : constant Boolean :=
                                               Check_Object_Consistency;

               begin
                  --  If compilation was not OK, or if output is not an
                  --  object file and we don't do the bind step, don't check
                  --  for object consistency.

                  Check_Object_Consistency :=
                    Check_Object_Consistency
                    and Compilation_OK
                    and (Output_Is_Object or Do_Bind_Step);
                  Text := Read_Library_Info (Lib_File);

                  --  Restore Check_Object_Consistency to its initial value

                  Check_Object_Consistency := Saved_Object_Consistency;
               end;

               --  If an ALI file was generated by this compilation, scan
               --  the ALI file and record it.
               --  If the scan fails, a previous ali file is inconsistent with
               --  the unit just compiled.

               if Text /= null then
                  ALI :=
                    Scan_ALI (Lib_File, Text, Ignore_ED => False, Err => True);

                  if ALI = No_ALI_Id then

                     --  Record a failure only if not already done

                     if Compilation_OK then
                        Inform
                          (Lib_File,
                           "incompatible ALI file, please recompile");
                        Record_Failure (Full_Source_File, Source_Unit);
                     end if;
                  else
                     Free (Text);
                     Record_Good_ALI (ALI);
                  end if;

               --  If we could not read the ALI file that was just generated
               --  then there could be a problem reading either the ALI or the
               --  corresponding object file (if Check_Object_Consistency
               --  is set Read_Library_Info checks that the time stamp of the
               --  object file is more recent than that of the ALI). For an
               --  example of problems caught by this test see [6625-009].
               --  However, we record a failure only if not already done.

               else
                  if Compilation_OK and not Syntax_Only then
                     Inform
                       (Lib_File,
                        "WARNING: ALI or object file not found after compile");
                     Record_Failure (Full_Source_File, Source_Unit);
                  end if;
               end if;
            end if;
         end if;

         --  PHASE 3: Check if we recorded good ALI files. If yes process
         --  them now in the order in which they have been recorded. There
         --  are two occasions in which we record good ali files. The first is
         --  in phase 1 when, after scanning an existing ALI file we realize
         --  it is up-to-date, the second instance is after a successful
         --  compilation.

         while Good_ALI_Present loop
            ALI := Get_Next_Good_ALI;

            declare
               Source_Index : Int := Unit_Index_Of (ALIs.Table (ALI).Afile);

            begin
               --  If we are processing the library file corresponding to the
               --  main source file check if this source can be a main unit.

               if ALIs.Table (ALI).Sfile = Main_Source and then
                 Source_Index = Main_Index
               then
                  Main_Unit := ALIs.Table (ALI).Main_Program /= None;
               end if;

               --  The following adds the standard library (s-stalib) to the
               --  list of files to be handled by gnatmake: this file and any
               --  files it depends on are always included in every bind,
               --  even if they are not in the explicit dependency list.
               --  Of course, it is not added if Suppress_Standard_Library
               --  is True.

               --  However, to avoid annoying output about s-stalib.ali being
               --  read only, when "-v" is used, we add the standard library
               --  only when "-a" is used.

               if Need_To_Check_Standard_Library then
                  Check_Standard_Library;
               end if;

               --  Now insert in the Q the unmarked source files (i.e. those
               --  which have never been inserted in the Q and hence never
               --  considered). Only do that if Unique_Compile is False.

               if not Unique_Compile then
                  for J in
                    ALIs.Table (ALI).First_Unit .. ALIs.Table (ALI).Last_Unit
                  loop
                     for K in
                       Units.Table (J).First_With .. Units.Table (J).Last_With
                     loop
                        Sfile := Withs.Table (K).Sfile;
                        Add_Dependency (ALIs.Table (ALI).Sfile, Sfile);

                        if Is_In_Obsoleted (Sfile) then
                           Executable_Obsolete := True;
                        end if;

                        if Sfile = No_File then
                           Debug_Msg
                             ("Skipping generic:", Withs.Table (K).Uname);

                        else
                           Source_Index :=
                             Unit_Index_Of (Withs.Table (K).Afile);

                           if Is_Marked (Sfile, Source_Index) then
                              Debug_Msg ("Skipping marked file:", Sfile);

                           elsif not Check_Readonly_Files
                             and then Is_Internal_File_Name (Sfile)
                           then
                              Debug_Msg ("Skipping internal file:", Sfile);

                           else
                              Insert_Q
                                (Sfile, Withs.Table (K).Uname, Source_Index);
                              Mark (Sfile, Source_Index);
                           end if;
                        end if;
                     end loop;
                  end loop;
               end if;
            end;
         end loop;

         if Display_Compilation_Progress then
            Write_Str ("completed ");
            Write_Int (Int (Q_Front));
            Write_Str (" out of ");
            Write_Int (Int (Q.Last));
            Write_Str (" (");
            Write_Int (Int ((Q_Front * 100) / (Q.Last - Q.First)));
            Write_Str ("%)...");
            Write_Eol;
         end if;
      end loop Make_Loop;

      Compilation_Failures := Bad_Compilation_Count;

      --  Compilation is finished

      --  Delete any temporary configuration pragma file

      Delete_Temp_Config_Files;

   end Compile_Sources;

   ----------------------------------
   -- Configuration_Pragmas_Switch --
   ----------------------------------

   function Configuration_Pragmas_Switch
     (For_Project : Project_Id) return Argument_List
   is
      The_Packages : Package_Id;
      Gnatmake     : Package_Id;
      Compiler     : Package_Id;

      Global_Attribute : Variable_Value := Nil_Variable_Value;
      Local_Attribute  : Variable_Value := Nil_Variable_Value;

      Global_Attribute_Present : Boolean := False;
      Local_Attribute_Present  : Boolean := False;

      Result : Argument_List (1 .. 3);
      Last   : Natural := 0;

      function Absolute_Path
        (Path    : Name_Id;
         Project : Project_Id) return String;
      --  Returns an absolute path for a configuration pragmas file

      -------------------
      -- Absolute_Path --
      -------------------

      function Absolute_Path
        (Path    : Name_Id;
         Project : Project_Id) return String
      is
      begin
         Get_Name_String (Path);

         declare
            Path_Name : constant String := Name_Buffer (1 .. Name_Len);

         begin
            if Is_Absolute_Path (Path_Name) then
               return Path_Name;

            else
               declare
                  Parent_Directory : constant String :=
                    Get_Name_String (Projects.Table (Project).Directory);

               begin
                  if Parent_Directory (Parent_Directory'Last) =
                                                 Directory_Separator
                  then
                     return Parent_Directory & Path_Name;

                  else
                     return Parent_Directory & Directory_Separator & Path_Name;
                  end if;
               end;
            end if;
         end;
      end Absolute_Path;

   --  Start of processing for Configuration_Pragmas_Switch

   begin
      Prj.Env.Create_Config_Pragmas_File (For_Project, Main_Project);

      if Projects.Table (For_Project).Config_File_Name /= No_Name then
         Temporary_Config_File :=
           Projects.Table (For_Project).Config_File_Temp;
         Last := 1;
         Result (1) :=
           new String'
                 ("-gnatec=" &
                  Get_Name_String
                    (Projects.Table (For_Project).Config_File_Name));

      else
         Temporary_Config_File := False;
      end if;

      --  Check for attribute Builder'Global_Configuration_Pragmas

      The_Packages := Projects.Table (Main_Project).Decl.Packages;
      Gnatmake :=
        Prj.Util.Value_Of
          (Name        => Name_Builder,
           In_Packages => The_Packages);

      if Gnatmake /= No_Package then
         Global_Attribute := Prj.Util.Value_Of
           (Variable_Name => Name_Global_Configuration_Pragmas,
            In_Variables => Packages.Table (Gnatmake).Decl.Attributes);
         Global_Attribute_Present :=
           Global_Attribute /= Nil_Variable_Value
           and then Get_Name_String (Global_Attribute.Value) /= "";

         if Global_Attribute_Present then
            declare
               Path : constant String :=
                        Absolute_Path
                          (Global_Attribute.Value, Global_Attribute.Project);
            begin
               if not Is_Regular_File (Path) then
                  Make_Failed
                    ("cannot find configuration pragmas file ", Path);
               end if;

               Last := Last + 1;
               Result (Last) := new String'("-gnatec=" &  Path);
            end;
         end if;
      end if;

      --  Check for attribute Compiler'Local_Configuration_Pragmas

      The_Packages := Projects.Table (For_Project).Decl.Packages;
      Compiler :=
        Prj.Util.Value_Of
          (Name        => Name_Compiler,
           In_Packages => The_Packages);

      if Compiler /= No_Package then
         Local_Attribute := Prj.Util.Value_Of
           (Variable_Name => Name_Local_Configuration_Pragmas,
            In_Variables => Packages.Table (Compiler).Decl.Attributes);
         Local_Attribute_Present :=
           Local_Attribute /= Nil_Variable_Value
           and then Get_Name_String (Local_Attribute.Value) /= "";

         if Local_Attribute_Present then
            declare
               Path : constant String :=
                        Absolute_Path
                          (Local_Attribute.Value, Local_Attribute.Project);
            begin
               if not Is_Regular_File (Path) then
                  Make_Failed
                    ("cannot find configuration pragmas file ", Path);
               end if;

               Last := Last + 1;
               Result (Last) := new String'("-gnatec=" & Path);
            end;
         end if;
      end if;

      return Result (1 .. Last);
   end Configuration_Pragmas_Switch;

   ---------------
   -- Debug_Msg --
   ---------------

   procedure Debug_Msg (S : String; N : Name_Id) is
   begin
      if Debug.Debug_Flag_W then
         Write_Str ("   ... ");
         Write_Str (S);
         Write_Str (" ");
         Write_Name (N);
         Write_Eol;
      end if;
   end Debug_Msg;

   ---------------------------
   -- Delete_All_Temp_Files --
   ---------------------------

   procedure Delete_All_Temp_Files is
   begin
      if Gnatmake_Called and not Debug.Debug_Flag_N then
         Delete_Mapping_Files;
         Delete_Temp_Config_Files;
         Prj.Env.Delete_All_Path_Files;
      end if;
   end Delete_All_Temp_Files;

   --------------------------
   -- Delete_Mapping_Files --
   --------------------------

   procedure Delete_Mapping_Files is
      Success : Boolean;
   begin
      if not Debug.Debug_Flag_N then
         if The_Mapping_File_Names /= null then
            for Project in The_Mapping_File_Names'Range (1) loop
               for Index in 1 .. Last_Mapping_File_Names (Project) loop
                  Delete_File
                    (Name => Get_Name_String
                               (The_Mapping_File_Names (Project, Index)),
                     Success => Success);
               end loop;
            end loop;
         end if;
      end if;
   end Delete_Mapping_Files;

   ------------------------------
   -- Delete_Temp_Config_Files --
   ------------------------------

   procedure Delete_Temp_Config_Files is
      Success : Boolean;
   begin
      if (not Debug.Debug_Flag_N) and Main_Project /= No_Project then
         for Project in 1 .. Projects.Last loop
            if Projects.Table (Project).Config_File_Temp then
               if Verbose_Mode then
                  Write_Str ("Deleting temp configuration file """);
                  Write_Str (Get_Name_String
                             (Projects.Table (Project).Config_File_Name));
                  Write_Line ("""");
               end if;

               Delete_File
                 (Name    => Get_Name_String
                  (Projects.Table (Project).Config_File_Name),
                  Success => Success);

               --  Make sure that we don't have a config file for this
               --  project, in case when there are several mains.
               --  In this case, we will recreate another config file:
               --  we cannot reuse the one that we just deleted!

               Projects.Table (Project).Config_Checked   := False;
               Projects.Table (Project).Config_File_Name := No_Name;
               Projects.Table (Project).Config_File_Temp := False;
            end if;
         end loop;
      end if;
   end Delete_Temp_Config_Files;

   -------------
   -- Display --
   -------------

   procedure Display (Program : String; Args : Argument_List) is
   begin
      pragma Assert (Args'First = 1);

      if Display_Executed_Programs then
         Write_Str (Program);

         for J in Args'Range loop

            --  Never display -gnatez

            if Args (J).all /= "-gnatez" then

               --  Do not display the mapping file argument automatically
               --  created when using a project file.

               if Main_Project = No_Project
                 or else Debug.Debug_Flag_N
                 or else Args (J)'Length < 8
                 or else
                   Args (J) (Args (J)'First .. Args (J)'First + 6) /= "-gnatem"
               then
                  --  When -dn is not specified, do not display the config
                  --  pragmas switch (-gnatec) for the temporary file created
                  --  by the project manager (always the first -gnatec switch).
                  --  Reset Temporary_Config_File to False so that the eventual
                  --  other -gnatec switches will be displayed.

                  if (not Debug.Debug_Flag_N)
                    and then Temporary_Config_File
                    and then Args (J)'Length > 7
                    and then Args (J) (Args (J)'First .. Args (J)'First + 6)
                    = "-gnatec"
                  then
                     Temporary_Config_File := False;

                     --  Do not display the -F=mapping_file switch for
                     --  gnatbind, if -dn is not specified.

                  elsif Debug.Debug_Flag_N
                    or else Args (J)'Length < 4
                    or else
                      Args (J) (Args (J)'First .. Args (J)'First + 2) /= "-F="
                  then
                     Write_Str (" ");
                     Write_Str (Args (J).all);
                  end if;
               end if;
            end if;
         end loop;

         Write_Eol;
      end if;
   end Display;

   ----------------------
   -- Display_Commands --
   ----------------------

   procedure Display_Commands (Display : Boolean := True) is
   begin
      Display_Executed_Programs := Display;
   end Display_Commands;

   -------------
   -- Empty_Q --
   -------------

   function Empty_Q return Boolean is
   begin
      if Debug.Debug_Flag_P then
         Write_Str ("   Q := [");

         for J in Q_Front .. Q.Last - 1 loop
            Write_Str (" ");
            Write_Name (Q.Table (J).File);
            Write_Eol;
            Write_Str ("         ");
         end loop;

         Write_Str ("]");
         Write_Eol;
      end if;

      return Q_Front >= Q.Last;
   end Empty_Q;

   --------------------------
   -- Enter_Into_Obsoleted --
   --------------------------

   procedure Enter_Into_Obsoleted (F : Name_Id) is
      Name  : constant String := Get_Name_String (F);
      First : Natural := Name'Last;
      F2    : Name_Id := F;

   begin
      while First > Name'First
        and then Name (First - 1) /= Directory_Separator
        and then Name (First - 1) /= '/'
      loop
         First := First - 1;
      end loop;

      if First /= Name'First then
         Name_Len := 0;
         Add_Str_To_Name_Buffer (Name (First .. Name'Last));
         F2 := Name_Find;
      end if;

      Debug_Msg ("New entry in Obsoleted table:", F2);
      Obsoleted.Set (F2, True);
   end Enter_Into_Obsoleted;

   ---------------------
   -- Extract_Failure --
   ---------------------

   procedure Extract_Failure
     (File  : out File_Name_Type;
      Unit  : out Unit_Name_Type;
      Found : out Boolean)
   is
   begin
      File  := Bad_Compilation.Table (Bad_Compilation.Last).File;
      Unit  := Bad_Compilation.Table (Bad_Compilation.Last).Unit;
      Found := Bad_Compilation.Table (Bad_Compilation.Last).Found;
      Bad_Compilation.Decrement_Last;
   end Extract_Failure;

   --------------------
   -- Extract_From_Q --
   --------------------

   procedure Extract_From_Q
     (Source_File  : out File_Name_Type;
      Source_Unit  : out Unit_Name_Type;
      Source_Index : out Int)
   is
      File  : constant File_Name_Type := Q.Table (Q_Front).File;
      Unit  : constant Unit_Name_Type := Q.Table (Q_Front).Unit;
      Index : constant Int            := Q.Table (Q_Front).Index;

   begin
      if Debug.Debug_Flag_Q then
         Write_Str ("   Q := Q - [ ");
         Write_Name (File);

         if Index /= 0 then
            Write_Str (", ");
            Write_Int (Index);
         end if;

         Write_Str (" ]");
         Write_Eol;
      end if;

      Q_Front := Q_Front + 1;
      Source_File  := File;
      Source_Unit  := Unit;
      Source_Index := Index;
   end Extract_From_Q;

   --------------
   -- Gnatmake --
   --------------

   procedure Gnatmake is
      Main_Source_File : File_Name_Type;
      --  The source file containing the main compilation unit

      Compilation_Failures : Natural;

      Total_Compilation_Failures : Natural := 0;

      Is_Main_Unit : Boolean;
      --  Set to True by Compile_Sources if the Main_Source_File can be a
      --  main unit.

      Main_ALI_File : File_Name_Type;
      --  The ali file corresponding to Main_Source_File

      Executable : File_Name_Type := No_File;
      --  The file name of an executable

      Non_Std_Executable : Boolean := False;
      --  Non_Std_Executable is set to True when there is a possibility
      --  that the linker will not choose the correct executable file name.

      Current_Work_Dir : constant String_Access :=
                                    new String'(Get_Current_Dir);
      --  The current working directory, used to modify some relative path
      --  switches on the command line when a project file is used.

      Current_Main_Index : Int := 0;
      --  If not zero, the index of the current main unit in its source file

      There_Are_Stand_Alone_Libraries : Boolean := False;
      --  Set to True when there are Stand-Alone Libraries, so that gnatbind
      --  is invoked with the -F switch to force checking of elaboration flags.

      Mapping_Path : Name_Id := No_Name;
      --  The path name of the mapping file

      Discard : Boolean;

      procedure Check_Mains;
      --  Check that the main subprograms do exist and that they all
      --  belong to the same project file.

      procedure Create_Binder_Mapping_File
        (Args : in out Argument_List; Last_Arg : in out Natural);
      --  Create a binder mapping file and add the necessary switch

      -----------------
      -- Check_Mains --
      -----------------

      procedure Check_Mains is
         Real_Main_Project : Project_Id := No_Project;
         --  The project of the first main

         Proj              : Project_Id := No_Project;
         --  The project of the current main

         Data              : Project_Data;

         Real_Path         : String_Access;

      begin
         Mains.Reset;

         --  Check each main

         loop
            declare
               Main      : constant String := Mains.Next_Main;
               --  The name specified on the command line may include
               --  directory information.

               File_Name : constant String := Base_Name (Main);
               --  The simple file name of the current main main

            begin
               exit when Main = "";

               --  Get the project of the current main

               Proj := Prj.Env.Project_Of (File_Name, Main_Project);

               --  Fail if the current main is not a source of a
               --  project.

               if Proj = No_Project then
                  Make_Failed
                    ("""" & Main &
                     """ is not a source of any project");

               else
                  --  If there is directory information, check that
                  --  the source exists and, if it does, that the path
                  --  is the actual path of a source of a project.

                  if Main /= File_Name then
                     Data := Projects.Table (Main_Project);

                     Real_Path :=
                       Locate_Regular_File
                         (Main &
                          Get_Name_String
                            (Data.Naming.Ada_Body_Suffix),
                          "");
                     if Real_Path = null then
                        Real_Path :=
                          Locate_Regular_File
                            (Main &
                             Get_Name_String
                               (Data.Naming.Ada_Spec_Suffix),
                             "");
                     end if;

                     if Real_Path = null then
                        Real_Path :=
                          Locate_Regular_File (Main, "");
                     end if;

                     --  Fail if the file cannot be found

                     if Real_Path = null then
                        Make_Failed
                          ("file """ & Main & """ does not exist");
                     end if;

                     declare
                        Project_Path : constant String :=
                                         Prj.Env.File_Name_Of_Library_Unit_Body
                                           (Name              => File_Name,
                                            Project           => Main_Project,
                                            Main_Project_Only => False,
                                            Full_Path         => True);
                        Normed_Path  : constant String :=
                                         Normalize_Pathname
                                           (Real_Path.all,
                                            Case_Sensitive => False);
                        Proj_Path    : constant String :=
                                         Normalize_Pathname
                                           (Project_Path,
                                            Case_Sensitive => False);

                     begin
                        Free (Real_Path);

                        --  Fail if it is not the correct path

                        if Normed_Path /= Proj_Path then
                           if Verbose_Mode then
                              Write_Str (Normed_Path);
                              Write_Str (" /= ");
                              Write_Line (Proj_Path);
                           end if;

                           Make_Failed
                             ("""" & Main &
                              """ is not a source of any project");
                        end if;
                     end;
                  end if;

                  if not Unique_Compile then

                     --  Record the project, if it is the first main

                     if Real_Main_Project = No_Project then
                        Real_Main_Project := Proj;

                     elsif Proj /= Real_Main_Project then

                        --  Fail, as the current main is not a source
                        --  of the same project as the first main.

                        Make_Failed
                          ("""" & Main &
                           """ is not a source of project " &
                           Get_Name_String
                             (Projects.Table
                                (Real_Main_Project).Name));
                     end if;
                  end if;
               end if;

               --  If -u and -U are not used, we may have mains that
               --  are sources of a project that is not the one
               --  specified with switch -P.

               if not Unique_Compile then
                  Main_Project := Real_Main_Project;
               end if;
            end;
         end loop;
      end Check_Mains;

      --------------------------------
      -- Create_Binder_Mapping_File --
      --------------------------------

      procedure Create_Binder_Mapping_File
        (Args : in out Argument_List; Last_Arg : in out Natural)
      is
         Mapping_FD : File_Descriptor := Invalid_FD;
         --  A File Descriptor for an eventual mapping file

         ALI_Unit     : Name_Id := No_Name;
         --  The unit name of an ALI file

         ALI_Name     : Name_Id := No_Name;
         --  The file name of the ALI file

         ALI_Project  : Project_Id := No_Project;
         --  The project of the ALI file

         Bytes        : Integer;
         OK           : Boolean := True;

         Status       : Boolean;
         --  For call to Close

      begin
         Tempdir.Create_Temp_File (Mapping_FD, Mapping_Path);

         if Mapping_FD /= Invalid_FD then

            --  Traverse all units

            for J in Prj.Com.Units.First .. Prj.Com.Units.Last loop
               declare
                  Unit : constant Prj.Com.Unit_Data :=
                           Prj.Com.Units.Table (J);
                  use Prj.Com;

               begin
                  if Unit.Name /= No_Name then

                     --  If there is a body, put it in the mapping

                     if Unit.File_Names (Body_Part).Name /= No_Name
                       and then Unit.File_Names (Body_Part).Project
                       /= No_Project
                     then
                        Get_Name_String (Unit.Name);
                        Name_Buffer
                          (Name_Len + 1 .. Name_Len + 2) := "%b";
                        Name_Len := Name_Len + 2;
                        ALI_Unit := Name_Find;
                        ALI_Name :=
                          Lib_File_Name
                            (Unit.File_Names (Body_Part).Name);
                        ALI_Project :=
                          Unit.File_Names (Body_Part).Project;

                        --  Otherwise, if there is a spec, put it
                        --  in the mapping.

                     elsif Unit.File_Names (Specification).Name
                       /= No_Name
                       and then Unit.File_Names
                         (Specification).Project
                         /= No_Project
                     then
                        Get_Name_String (Unit.Name);
                        Name_Buffer
                          (Name_Len + 1 .. Name_Len + 2) := "%s";
                        Name_Len := Name_Len + 2;
                        ALI_Unit := Name_Find;
                        ALI_Name := Lib_File_Name
                          (Unit.File_Names (Specification).Name);
                        ALI_Project :=
                          Unit.File_Names (Specification).Project;

                     else
                        ALI_Name := No_Name;
                     end if;

                     --  If we have something to put in the mapping
                     --  then we do it now. However, if the project
                     --  is extended, we don't put anything in the
                     --  mapping file, because we do not know where
                     --  the ALI file is: it might be in the ext-
                     --  ended project obj dir as well as in the
                     --  extending project obj dir.

                     if ALI_Name /= No_Name
                       and then
                         Projects.Table (ALI_Project).Extended_By = No_Project
                       and then
                         Projects.Table (ALI_Project).Extends = No_Project
                     then
                        --  First line is the unit name

                        Get_Name_String (ALI_Unit);
                        Name_Len := Name_Len + 1;
                        Name_Buffer (Name_Len) := ASCII.LF;
                        Bytes :=
                          Write
                            (Mapping_FD,
                             Name_Buffer (1)'Address,
                             Name_Len);
                        OK := Bytes = Name_Len;

                        exit when not OK;

                        --  Second line it the ALI file name

                        Get_Name_String (ALI_Name);
                        Name_Len := Name_Len + 1;
                        Name_Buffer (Name_Len) := ASCII.LF;
                        Bytes :=
                          Write
                            (Mapping_FD,
                             Name_Buffer (1)'Address,
                             Name_Len);
                        OK := Bytes = Name_Len;

                        exit when not OK;

                        --  Third line it the ALI path name,
                        --  concatenation of the project
                        --  directory with the ALI file name.

                        declare
                           ALI : constant String :=
                                   Get_Name_String (ALI_Name);
                        begin
                           Get_Name_String
                             (Projects.Table (ALI_Project).
                                Object_Directory);

                           if Name_Buffer (Name_Len) /=
                             Directory_Separator
                           then
                              Name_Len := Name_Len + 1;
                              Name_Buffer (Name_Len) :=
                                Directory_Separator;
                           end if;

                           Name_Buffer
                             (Name_Len + 1 ..
                                Name_Len + ALI'Length) := ALI;
                           Name_Len :=
                             Name_Len + ALI'Length + 1;
                           Name_Buffer (Name_Len) := ASCII.LF;
                           Bytes :=
                             Write
                               (Mapping_FD,
                                Name_Buffer (1)'Address,
                                Name_Len);
                           OK := Bytes = Name_Len;
                        end;

                        --  If OK is False, it means we were unable
                        --  to write a line. No point in continuing
                        --  with the other units.

                        exit when not OK;
                     end if;
                  end if;
               end;
            end loop;

            Close (Mapping_FD, Status);

            OK := OK and Status;

            --  If the creation of the mapping file was successful,
            --  we add the switch to the arguments of gnatbind.

            if OK then
               Last_Arg := Last_Arg + 1;
               Args (Last_Arg) :=
                 new String'("-F=" & Get_Name_String (Mapping_Path));
            end if;
         end if;
      end Create_Binder_Mapping_File;

   --  Start of processing for Gnatmake

   --  This body is very long, should be broken down ???

   begin
      Gnatmake_Called := True;

      Install_Int_Handler (Sigint_Intercepted'Access);

      Do_Compile_Step := True;
      Do_Bind_Step    := True;
      Do_Link_Step    := True;

      Obsoleted.Reset;

      Make.Initialize;

      Bind_Shared := No_Shared_Switch'Access;
      Link_With_Shared_Libgcc := No_Shared_Libgcc_Switch'Access;

      Failed_Links.Set_Last (0);
      Successful_Links.Set_Last (0);

      if Hostparm.Java_VM then
         Gcc := new String'("jgnat");
         Gnatbind := new String'("jgnatbind");
         Gnatlink := new String'("jgnatlink");

         --  Do not check for an object file (".o") when compiling to
         --  Java bytecode since ".class" files are generated instead.

         Check_Object_Consistency := False;
      end if;

      --  Special case when switch -B was specified

      if Build_Bind_And_Link_Full_Project then

         --  When switch -B is specified, there must be a project file

         if Main_Project = No_Project then
            Make_Failed ("-B cannot be used without a project file");

         --  No main program may be specified on the command line

         elsif Osint.Number_Of_Files /= 0 then
            Make_Failed ("-B cannot be used with a main specified on " &
                         "the command line");

         --  And the project file cannot be a library project file

         elsif Projects.Table (Main_Project).Library then
            Make_Failed ("-B cannot be used for a library project file");

         else
            Insert_Project_Sources
              (The_Project  => Main_Project,
               All_Projects => Unique_Compile_All_Projects,
               Into_Q       => False);

            --  If there are no sources to compile, we fail

            if Osint.Number_Of_Files = 0 then
               Make_Failed ("no sources to compile");
            end if;

            --  Specify -n for gnatbind and add the ALI files of all the
            --  sources, except the one which is a fake main subprogram:
            --  this is the one for the binder generated file and it will be
            --  transmitted to gnatlink. These sources are those that are
            --  in the queue.

            Add_Switch ("-n", Binder, And_Save => True);

            for J in Q.First .. Q.Last - 1 loop
               Add_Switch
                 (Get_Name_String
                    (Lib_File_Name (Q.Table (J).File)),
                  Binder, And_Save => True);
            end loop;
         end if;

      elsif Main_Index /= 0 and then Osint.Number_Of_Files > 1 then
         Make_Failed ("cannot specify several mains with a multi-unit index");

      elsif Main_Project /= No_Project then

         --  If the main project file is a library project file, main(s)
         --  cannot be specified on the command line.

         if Osint.Number_Of_Files /= 0 then
            if Projects.Table (Main_Project).Library
              and then not Unique_Compile
              and then ((not Make_Steps) or else Bind_Only or else Link_Only)
            then
               Make_Failed ("cannot specify a main program " &
                            "on the command line for a library project file");

            else
               --  Check that each main on the command line is a source of a
               --  project file and, if there are several mains, each of them
               --  is a source of the same project file.

               Check_Mains;
            end if;

         --  If no mains have been specified on the command line,
         --  and we are using a project file, we either find the main(s)
         --  in the attribute Main of the main project, or we put all
         --  the sources of the project file as mains.

         else
            if Main_Index /= 0 then
               Make_Failed ("cannot specify a multi-unit index but no main " &
                            "on the command line");
            end if;

            declare
               Value : String_List_Id := Projects.Table (Main_Project).Mains;

            begin
               --  The attribute Main is an empty list or not specified,
               --  or else gnatmake was invoked with the switch "-u".

               if Value = Prj.Nil_String or else Unique_Compile then

                  if (not Make_Steps) or else Compile_Only
                    or else not Projects.Table (Main_Project).Library
                  then
                     --  First make sure that the binder and the linker
                     --  will not be invoked.

                     Do_Bind_Step := False;
                     Do_Link_Step := False;

                     --  Put all the sources in the queue

                     Insert_Project_Sources
                       (The_Project  => Main_Project,
                        All_Projects => Unique_Compile_All_Projects,
                        Into_Q       => False);

                     --  If there are no sources to compile, we fail

                     if Osint.Number_Of_Files = 0 then
                        Make_Failed ("no sources to compile");
                     end if;
                  end if;

               else
                  --  The attribute Main is not an empty list.
                  --  Put all the main subprograms in the list as if there
                  --  were specified on the command line. However, if attribute
                  --  Languages includes a language other than Ada, only
                  --  include the Ada mains; if there is no Ada main, compile
                  --  all the sources of the project.

                  declare
                     Data : constant Project_Data :=
                              Projects.Table (Main_Project);

                     Languages : constant Variable_Value :=
                                   Prj.Util.Value_Of
                                     (Name_Languages, Data.Decl.Attributes);

                     Current : String_List_Id;
                     Element : String_Element;

                     Foreign_Language  : Boolean := False;
                     At_Least_One_Main : Boolean := False;

                  begin
                     --  First, determine if there is a foreign language in
                     --  attribute Languages.

                     if not Languages.Default then
                        Current := Languages.Values;

                        Look_For_Foreign :
                        while Current /= Nil_String loop
                           Element := String_Elements.Table (Current);
                           Get_Name_String (Element.Value);
                           To_Lower (Name_Buffer (1 .. Name_Len));

                           if Name_Buffer (1 .. Name_Len) /= "ada" then
                              Foreign_Language := True;
                              exit Look_For_Foreign;
                           end if;

                           Current := Element.Next;
                        end loop Look_For_Foreign;
                     end if;

                     --  Then, find all mains, or if there is a foreign
                     --  language, all the Ada mains.

                     while Value /= Prj.Nil_String loop
                        Get_Name_String (String_Elements.Table (Value).Value);

                        --  To know if a main is an Ada main, get its project.
                        --  It should be the project specified on the command
                        --  line.

                        if (not Foreign_Language) or else
                            Prj.Env.Project_Of
                              (Name_Buffer (1 .. Name_Len), Main_Project) =
                             Main_Project
                        then
                           At_Least_One_Main := True;
                           Osint.Add_File
                             (Get_Name_String
                                (String_Elements.Table (Value).Value),
                              Index => String_Elements.Table (Value).Index);
                        end if;

                        Value := String_Elements.Table (Value).Next;
                     end loop;

                     --  If we did not get any main, it means that all mains
                     --  in attribute Mains are in a foreign language and -B
                     --  was not specified to gnatmake; so, we fail.

                     if not At_Least_One_Main then
                        Make_Failed
                          ("no Ada mains; use -B to build foreign main");
                     end if;
                  end;

               end if;
            end;
         end if;
      end if;

      if Verbose_Mode then
         Write_Eol;
         Write_Str ("GNATMAKE ");
         Write_Str (Gnatvsn.Gnat_Version_String);
         Write_Eol;
         Write_Str ("Copyright 1995-2004 Free Software Foundation, Inc.");
         Write_Eol;
      end if;

      if Main_Project /= No_Project
        and then Projects.Table (Main_Project).Externally_Built
      then
         Make_Failed
           ("nothing to do for a main project that is externally built");
      end if;

      if Osint.Number_Of_Files = 0 then
         if Main_Project /= No_Project
           and then Projects.Table (Main_Project).Library
         then
            if Do_Bind_Step
              and then not Projects.Table (Main_Project).Standalone_Library
            then
               Make_Failed ("only stand-alone libraries may be bound");
            end if;

            --  Add the default search directories to be able to find libgnat

            Osint.Add_Default_Search_Dirs;

            --  And bind and or link the library

            MLib.Prj.Build_Library
              (For_Project   => Main_Project,
               Gnatbind      => Gnatbind.all,
               Gnatbind_Path => Gnatbind_Path,
               Gcc           => Gcc.all,
               Gcc_Path      => Gcc_Path,
               Bind          => Bind_Only,
               Link          => Link_Only);
            Exit_Program (E_Success);

         else
            --  Output usage information if no files to compile

            Usage;
            Exit_Program (E_Fatal);
         end if;
      end if;

      --  If -M was specified, behave as if -n was specified

      if List_Dependencies then
         Do_Not_Execute := True;
      end if;

      --  Note that Osint.Next_Main_Source will always return the (possibly
      --  abbreviated file) without any directory information.

      Main_Source_File := Next_Main_Source;

      if Current_File_Index /= No_Index then
         Main_Index := Current_File_Index;
      end if;

      Add_Switch ("-I-", Binder, And_Save => True);
      Add_Switch ("-I-", Compiler, And_Save => True);

      if Main_Project = No_Project then
         if Look_In_Primary_Dir then

            Add_Switch
              ("-I" &
               Normalize_Directory_Name
               (Get_Primary_Src_Search_Directory.all).all,
               Compiler, Append_Switch => False,
               And_Save => False);

            Add_Switch ("-aO" & Normalized_CWD,
                        Binder,
                        Append_Switch => False,
                        And_Save => False);
         end if;

      else
         --  If we use a project file, we have already checked that a main
         --  specified on the command line with directory information has the
         --  path name corresponding to a correct source in the project tree.
         --  So, we don't need the directory information to be taken into
         --  account by Find_File, and in fact it may lead to take the wrong
         --  sources for other compilation units, when there are extending
         --  projects.

         Look_In_Primary_Dir := False;
      end if;

      --  If the user wants a program without a main subprogram, add the
      --  appropriate switch to the binder.

      if No_Main_Subprogram then
         Add_Switch ("-z", Binder, And_Save => True);
      end if;

      if Main_Project /= No_Project then

         if Projects.Table (Main_Project).Object_Directory /= No_Name then

            --  Change the current directory to the object directory of
            --  the main project.

            begin
               Project_Object_Directory := No_Project;
               Change_To_Object_Directory (Main_Project);

            exception
               when Directory_Error =>

                  --  This should never happen. But, if it does, display the
                  --  content of the parent directory of the obj dir.

                  declare
                     Parent : constant Dir_Name_Str :=
                                Dir_Name
                                  (Get_Name_String
                                     (Projects.Table
                                        (Main_Project).Object_Directory));

                     Dir  : Dir_Type;
                     Str  : String (1 .. 200);
                     Last : Natural;

                  begin
                     Write_Str ("Contents of directory """);
                     Write_Str (Parent);
                     Write_Line (""":");

                     Open (Dir, Parent);

                     loop
                        Read (Dir, Str, Last);
                        exit when Last = 0;
                        Write_Str ("   ");
                        Write_Line (Str (1 .. Last));
                     end loop;

                     Close (Dir);

                  exception
                     when X : others =>
                        Write_Line ("(unexpected exception)");
                        Write_Line (Exception_Information (X));

                        if Is_Open (Dir) then
                           Close (Dir);
                        end if;
                  end;

                  Make_Failed
                    ("unable to change working directory to """,
                     Get_Name_String
                       (Projects.Table (Main_Project).Object_Directory),
                     """");
            end;
         end if;

         --  Source file lookups should be cached for efficiency.
         --  Source files are not supposed to change.

         Osint.Source_File_Data (Cache => True);

         --  Find the file name of the (first) main unit

         declare
            Main_Source_File_Name : constant String :=
                                      Get_Name_String (Main_Source_File);
            Main_Unit_File_Name   : constant String :=
                                      Prj.Env.File_Name_Of_Library_Unit_Body
                                        (Name    => Main_Source_File_Name,
                                         Project => Main_Project,
                                         Main_Project_Only =>
                                           not Unique_Compile);

            The_Packages : constant Package_Id :=
              Projects.Table (Main_Project).Decl.Packages;

            Builder_Package : constant Prj.Package_Id :=
                         Prj.Util.Value_Of
                           (Name        => Name_Builder,
                            In_Packages => The_Packages);

            Binder_Package : constant Prj.Package_Id :=
                         Prj.Util.Value_Of
                           (Name        => Name_Binder,
                            In_Packages => The_Packages);

            Linker_Package : constant Prj.Package_Id :=
                         Prj.Util.Value_Of
                           (Name       => Name_Linker,
                            In_Packages => The_Packages);

         begin
            --  We fail if we cannot find the main source file

            if Main_Unit_File_Name = "" then
               Make_Failed ('"' & Main_Source_File_Name,
                            """ is not a unit of project ",
                            Project_File_Name.all & ".");
            else
               --  Remove any directory information from the main
               --  source file name.

               declare
                  Pos : Natural := Main_Unit_File_Name'Last;

               begin
                  loop
                     exit when Pos < Main_Unit_File_Name'First or else
                       Main_Unit_File_Name (Pos) = Directory_Separator;
                     Pos := Pos - 1;
                  end loop;

                  Name_Len := Main_Unit_File_Name'Last - Pos;

                  Name_Buffer (1 .. Name_Len) :=
                    Main_Unit_File_Name
                    (Pos + 1 .. Main_Unit_File_Name'Last);

                  Main_Source_File := Name_Find;

                  --  We only output the main source file if there is only one

                  if Verbose_Mode and then Osint.Number_Of_Files = 1 then
                     Write_Str ("Main source file: """);
                     Write_Str (Main_Unit_File_Name
                                (Pos + 1 .. Main_Unit_File_Name'Last));
                     Write_Line (""".");
                  end if;
               end;
            end if;

            --  If there is a package Builder in the main project file, add
            --  the switches from it.

            if Builder_Package /= No_Package then

               --  If there is only one main, we attempt to get the gnatmake
               --  switches for this main (if any). If there are no specific
               --  switch for this particular main, get the general gnatmake
               --  switches (if any).

               if Osint.Number_Of_Files = 1 then
                  if Verbose_Mode then
                     Write_Str ("Adding gnatmake switches for """);
                     Write_Str (Main_Unit_File_Name);
                     Write_Line (""".");
                  end if;

                  Add_Switches
                    (File_Name   => Main_Unit_File_Name,
                     Index       => Main_Index,
                     The_Package => Builder_Package,
                     Program     => None);

               else
                  --  If there are several mains, we always get the general
                  --  gnatmake switches (if any).

                  --  Warn the user, if necessary, so that he is not surprized
                  --  that specific switches are not taken into account.

                  declare
                     Defaults : constant Variable_Value :=
                       Prj.Util.Value_Of
                         (Name                    => Name_Ada,
                          Index                   => 0,
                          Attribute_Or_Array_Name => Name_Default_Switches,
                          In_Package              => Builder_Package);

                     Switches : constant Array_Element_Id :=
                          Prj.Util.Value_Of
                             (Name      => Name_Switches,
                              In_Arrays =>
                                Packages.Table (Builder_Package).Decl.Arrays);

                  begin
                     if Defaults /= Nil_Variable_Value then
                        if (not Quiet_Output)
                          and then Switches /= No_Array_Element
                        then
                           Write_Line
                             ("Warning: using Builder'Default_Switches" &
                              "(""Ada""), as there are several mains");
                        end if;

                        --  As there is never a source with name " ", we are
                        --  guaranteed to always get the general switches.

                        Add_Switches
                          (File_Name   => " ",
                           Index       => 0,
                           The_Package => Builder_Package,
                           Program     => None);

                     elsif (not Quiet_Output)
                       and then Switches /= No_Array_Element
                     then
                        Write_Line
                          ("Warning: using no switches from package Builder," &
                           " as there are several mains");
                     end if;
                  end;
               end if;
            end if;

            Osint.Add_Default_Search_Dirs;

            --  Record the current last switch index for table Binder_Switches
            --  and Linker_Switches, so that these tables may be reset before
            --  for each main, before adding swiches from the project file
            --  and from the command line.

            Last_Binder_Switch := Binder_Switches.Last;
            Last_Linker_Switch := Linker_Switches.Last;

            Check_Steps;

            --  Add binder switches from the project file for the first main

            if Do_Bind_Step and Binder_Package /= No_Package then
               if Verbose_Mode then
                  Write_Str ("Adding binder switches for """);
                  Write_Str (Main_Unit_File_Name);
                  Write_Line (""".");
               end if;

               Add_Switches
                 (File_Name   => Main_Unit_File_Name,
                  Index       => Main_Index,
                  The_Package => Binder_Package,
                  Program     => Binder);
            end if;

            --  Add linker switches from the project file for the first main

            if Do_Link_Step and Linker_Package /= No_Package then
               if Verbose_Mode then
                  Write_Str ("Adding linker switches for""");
                  Write_Str (Main_Unit_File_Name);
                  Write_Line (""".");
               end if;

               Add_Switches
                 (File_Name   => Main_Unit_File_Name,
                  Index       => Main_Index,
                  The_Package => Linker_Package,
                  Program     => Linker);
            end if;
         end;
      end if;

      --  Get the target parameters, which are only needed for a couple of
      --  cases in gnatmake. Protect against an exception, such as the case
      --  of system.ads missing from the library, and fail gracefully.

      begin
         Targparm.Get_Target_Parameters;

      exception
         when Unrecoverable_Error =>
            Make_Failed ("*** make failed.");
      end;

      Display_Commands (not Quiet_Output);

      Check_Steps;

      if Main_Project /= No_Project then

         --  For all library project, if the library file does not exist
         --  put all the project sources in the queue, and flag the project
         --  so that the library is generated.

         if not Unique_Compile
           and then MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None
         then
            for Proj in Projects.First .. Projects.Last loop
               if Projects.Table (Proj).Library then
                  Projects.Table (Proj).Need_To_Build_Lib :=
                    (not MLib.Tgt.Library_Exists_For (Proj))
                    and then (not Projects.Table (Proj).Externally_Built);

                  if Projects.Table (Proj).Need_To_Build_Lib then

                     --  If there is no object directory, then it will be
                     --  impossible to build the library. So fail immediately.

                     if Projects.Table (Proj).Object_Directory = No_Name then
                        Make_Failed
                          ("no object files to build library for project """,
                           Get_Name_String (Projects.Table (Proj).Name),
                           """");
                        Projects.Table (Proj).Need_To_Build_Lib := False;

                     else
                        if Verbose_Mode then
                           Write_Str
                             ("Library file does not exist for project """);
                           Write_Str
                             (Get_Name_String (Projects.Table (Proj).Name));
                           Write_Line ("""");
                        end if;

                        Insert_Project_Sources
                          (The_Project  => Proj,
                           All_Projects => False,
                           Into_Q       => True);
                     end if;
                  end if;
               end if;
            end loop;
         end if;

         --  If a relative path output file has been specified, we add
         --  the exec directory.

         for J in reverse 1 .. Saved_Linker_Switches.Last - 1 loop
            if Saved_Linker_Switches.Table (J).all = Output_Flag.all then
               declare
                  Exec_File_Name : constant String :=
                    Saved_Linker_Switches.Table (J + 1).all;

               begin
                  if not Is_Absolute_Path (Exec_File_Name) then
                     for Index in Exec_File_Name'Range loop
                        if Exec_File_Name (Index) = Directory_Separator then
                           Make_Failed ("relative executable (""",
                                        Exec_File_Name,
                                        """) with directory part not " &
                                        "allowed when using project files");
                        end if;
                     end loop;

                     Get_Name_String (Projects.Table
                                        (Main_Project).Exec_Directory);

                     if Name_Buffer (Name_Len) /= Directory_Separator then
                        Name_Len := Name_Len + 1;
                        Name_Buffer (Name_Len) := Directory_Separator;
                     end if;

                     Name_Buffer (Name_Len + 1 ..
                                    Name_Len + Exec_File_Name'Length) :=
                       Exec_File_Name;
                     Name_Len := Name_Len + Exec_File_Name'Length;
                     Saved_Linker_Switches.Table (J + 1) :=
                       new String'(Name_Buffer (1 .. Name_Len));
                  end if;
               end;

               exit;
            end if;
         end loop;

         --  If we are using a project file, for relative paths we add the
         --  current working directory for any relative path on the command
         --  line and the project directory, for any relative path in the
         --  project file.

         declare
            Dir_Path : constant String_Access :=
              new String'(Get_Name_String
                            (Projects.Table (Main_Project).Directory));
         begin
            for J in 1 .. Binder_Switches.Last loop
               Test_If_Relative_Path
                 (Binder_Switches.Table (J),
                  Parent => Dir_Path, Including_L_Switch => False);
            end loop;

            for J in 1 .. Saved_Binder_Switches.Last loop
               Test_If_Relative_Path
                 (Saved_Binder_Switches.Table (J),
                  Parent => Current_Work_Dir, Including_L_Switch => False);
            end loop;

            for J in 1 .. Linker_Switches.Last loop
               Test_If_Relative_Path
                 (Linker_Switches.Table (J), Parent => Dir_Path);
            end loop;

            for J in 1 .. Saved_Linker_Switches.Last loop
               Test_If_Relative_Path
                 (Saved_Linker_Switches.Table (J), Parent => Current_Work_Dir);
            end loop;

            for J in 1 .. Gcc_Switches.Last loop
               Test_If_Relative_Path
                 (Gcc_Switches.Table (J), Parent => Dir_Path);
            end loop;

            for J in 1 .. Saved_Gcc_Switches.Last loop
               Test_If_Relative_Path
                 (Saved_Gcc_Switches.Table (J), Parent => Current_Work_Dir);
            end loop;
         end;
      end if;

      --  We now put in the Binder_Switches and Linker_Switches tables,
      --  the binder and linker switches of the command line that have been
      --  put in the Saved_ tables. If a project file was used, then the
      --  command line switches will follow the project file switches.

      for J in 1 .. Saved_Binder_Switches.Last loop
         Add_Switch
           (Saved_Binder_Switches.Table (J),
            Binder,
            And_Save => False);
      end loop;

      for J in 1 .. Saved_Linker_Switches.Last loop
         Add_Switch
           (Saved_Linker_Switches.Table (J),
            Linker,
            And_Save => False);
      end loop;

      --  If no project file is used, we just put the gcc switches
      --  from the command line in the Gcc_Switches table.

      if Main_Project = No_Project then
         for J in 1 .. Saved_Gcc_Switches.Last loop
            Add_Switch
              (Saved_Gcc_Switches.Table (J),
               Compiler,
              And_Save => False);
         end loop;

      else
         --  And we put the command line gcc switches in the variable
         --  The_Saved_Gcc_Switches. They are going to be used later
         --  in procedure Compile_Sources.

         The_Saved_Gcc_Switches :=
           new Argument_List (1 .. Saved_Gcc_Switches.Last + 1);

         for J in 1 .. Saved_Gcc_Switches.Last loop
            The_Saved_Gcc_Switches (J) := Saved_Gcc_Switches.Table (J);
         end loop;

         --  We never use gnat.adc when a project file is used

         The_Saved_Gcc_Switches (The_Saved_Gcc_Switches'Last) :=
           No_gnat_adc;

      end if;

      --  If there was a --GCC, --GNATBIND or --GNATLINK switch on
      --  the command line, then we have to use it, even if there was
      --  another switch in the project file.

      if Saved_Gcc /= null then
         Gcc := Saved_Gcc;
      end if;

      if Saved_Gnatbind /= null then
         Gnatbind := Saved_Gnatbind;
      end if;

      if Saved_Gnatlink /= null then
         Gnatlink := Saved_Gnatlink;
      end if;

      Gcc_Path       := GNAT.OS_Lib.Locate_Exec_On_Path (Gcc.all);
      Gnatbind_Path  := GNAT.OS_Lib.Locate_Exec_On_Path (Gnatbind.all);
      Gnatlink_Path  := GNAT.OS_Lib.Locate_Exec_On_Path (Gnatlink.all);

      --  If we have specified -j switch both from the project file
      --  and on the command line, the one from the command line takes
      --  precedence.

      if Saved_Maximum_Processes = 0 then
         Saved_Maximum_Processes := Maximum_Processes;
      end if;

      --  Allocate as many temporary mapping file names as the maximum
      --  number of compilation processed, for each possible project.

      The_Mapping_File_Names :=
        new Temp_File_Names
              (No_Project .. Projects.Last, 1 .. Saved_Maximum_Processes);
      Last_Mapping_File_Names :=
        new Indices'(No_Project .. Projects.Last => 0);

      The_Free_Mapping_File_Indices :=
        new Free_File_Indices
              (No_Project .. Projects.Last, 1 .. Saved_Maximum_Processes);
      Last_Free_Indices :=
        new Indices'(No_Project .. Projects.Last => 0);

      Bad_Compilation.Init;

      Current_Main_Index := Main_Index;

      --  Here is where the make process is started

      --  We do the same process for each main

      Multiple_Main_Loop : for N_File in 1 .. Osint.Number_Of_Files loop

         --  First, find the executable name and path

         Executable          := No_File;
         Executable_Obsolete := False;
         Non_Std_Executable  := False;

         --  Look inside the linker switches to see if the name
         --  of the final executable program was specified.

         for
           J in reverse Linker_Switches.First .. Linker_Switches.Last
         loop
            if Linker_Switches.Table (J).all = Output_Flag.all then
               pragma Assert (J < Linker_Switches.Last);

               --  We cannot specify a single executable for several
               --  main subprograms!

               if Osint.Number_Of_Files > 1 then
                  Fail
                    ("cannot specify a single executable " &
                     "for several mains");
               end if;

               Name_Len := Linker_Switches.Table (J + 1)'Length;
               Name_Buffer (1 .. Name_Len) :=
                 Linker_Switches.Table (J + 1).all;
               Executable := Name_Enter;

               Verbose_Msg (Executable, "final executable");
            end if;
         end loop;

         --  If the name of the final executable program was not
         --  specified then construct it from the main input file.

         if Executable = No_File then
            if Main_Project = No_Project then
               Executable :=
                 Executable_Name (Strip_Suffix (Main_Source_File));

            else
               --  If we are using a project file, we attempt to
               --  remove the body (or spec) termination of the main
               --  subprogram. We find it the the naming scheme of the
               --  project file. This will avoid to generate an
               --  executable "main.2" for a main subprogram
               --  "main.2.ada", when the body termination is ".2.ada".

               Executable := Prj.Util.Executable_Of
                               (Main_Project, Main_Source_File, Main_Index);
            end if;
         end if;

         if Main_Project /= No_Project then
            declare
               Exec_File_Name : constant String :=
                 Get_Name_String (Executable);

            begin
               if not Is_Absolute_Path (Exec_File_Name) then
                  for Index in Exec_File_Name'Range loop
                     if Exec_File_Name (Index) = Directory_Separator then
                        Make_Failed ("relative executable (""",
                                           Exec_File_Name,
                                           """) with directory part not " &
                                           "allowed when using project files");
                     end if;
                  end loop;

                  Get_Name_String (Projects.Table
                                           (Main_Project).Exec_Directory);

                  if
                    Name_Buffer (Name_Len) /= Directory_Separator
                  then
                     Name_Len := Name_Len + 1;
                     Name_Buffer (Name_Len) := Directory_Separator;
                  end if;

                  Name_Buffer (Name_Len + 1 ..
                                       Name_Len + Exec_File_Name'Length) :=
                    Exec_File_Name;

                  Name_Len := Name_Len + Exec_File_Name'Length;
                  Executable := Name_Find;
                  Non_Std_Executable := True;
               end if;
            end;
         end if;

         if Do_Compile_Step then
            Recursive_Compilation_Step : declare
               Args : Argument_List (1 .. Gcc_Switches.Last);

               First_Compiled_File : Name_Id;
               Youngest_Obj_File   : Name_Id;
               Youngest_Obj_Stamp  : Time_Stamp_Type;

               Executable_Stamp : Time_Stamp_Type;
               --  Executable is the final executable program

               Library_Rebuilt : Boolean := False;

            begin
               for J in 1 .. Gcc_Switches.Last loop
                  Args (J) := Gcc_Switches.Table (J);
               end loop;

               --  Now we invoke Compile_Sources for the current main

               Compile_Sources
                 (Main_Source           => Main_Source_File,
                  Args                  => Args,
                  First_Compiled_File   => First_Compiled_File,
                  Most_Recent_Obj_File  => Youngest_Obj_File,
                  Most_Recent_Obj_Stamp => Youngest_Obj_Stamp,
                  Main_Unit             => Is_Main_Unit,
                  Main_Index            => Current_Main_Index,
                  Compilation_Failures  => Compilation_Failures,
                  Check_Readonly_Files  => Check_Readonly_Files,
                  Do_Not_Execute        => Do_Not_Execute,
                  Force_Compilations    => Force_Compilations,
                  In_Place_Mode         => In_Place_Mode,
                  Keep_Going            => Keep_Going,
                  Initialize_ALI_Data   => True,
                  Max_Process           => Saved_Maximum_Processes);

               if Verbose_Mode then
                  Write_Str ("End of compilation");
                  Write_Eol;
               end if;

               --  Make sure the queue will be reinitialized for the next round

               First_Q_Initialization := True;

               Total_Compilation_Failures :=
                 Total_Compilation_Failures + Compilation_Failures;

               if Total_Compilation_Failures /= 0 then
                  if Keep_Going then
                     goto Next_Main;
                  else
                     List_Bad_Compilations;
                     raise Compilation_Failed;
                  end if;
               end if;

               --  Regenerate libraries, if any, and if object files
               --  have been regenerated.

               if Main_Project /= No_Project
                 and then MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None
                 and then (Do_Bind_Step or Unique_Compile_All_Projects
                           or not Compile_Only)
                 and then (Do_Link_Step or N_File = Osint.Number_Of_Files)
               then
                  Library_Projs.Init;

                  declare
                     Proj2   : Project_Id;
                     Depth   : Natural;
                     Current : Natural;

                  begin
                     --  Put in Library_Projs table all library project
                     --  file ids when the library need to be rebuilt.

                     for Proj1 in Projects.First .. Projects.Last loop

                        if Projects.Table (Proj1).Standalone_Library then
                           There_Are_Stand_Alone_Libraries := True;
                        end if;

                        if Projects.Table (Proj1).Library
                          and then not Projects.Table (Proj1).Need_To_Build_Lib
                          and then not Projects.Table (Proj1).Externally_Built
                        then
                           MLib.Prj.Check_Library (Proj1);
                        end if;

                        if Projects.Table (Proj1).Need_To_Build_Lib then
                           Library_Projs.Increment_Last;
                           Current := Library_Projs.Last;
                           Depth := Projects.Table (Proj1).Depth;

                           --  Put the projects in decreasing depth order,
                           --  so that if libA depends on libB, libB is first
                           --  in order.

                           while Current > 1 loop
                              Proj2 := Library_Projs.Table (Current - 1);
                              exit when Projects.Table (Proj2).Depth >= Depth;
                              Library_Projs.Table (Current) := Proj2;
                              Current := Current - 1;
                           end loop;

                           Library_Projs.Table (Current) := Proj1;
                           Projects.Table (Proj1).Need_To_Build_Lib := False;
                        end if;
                     end loop;
                  end;

                  --  Build the libraries, if any need to be built

                  for J in 1 .. Library_Projs.Last loop
                     Library_Rebuilt := True;
                     MLib.Prj.Build_Library
                       (For_Project   => Library_Projs.Table (J),
                        Gnatbind      => Gnatbind.all,
                        Gnatbind_Path => Gnatbind_Path,
                        Gcc           => Gcc.all,
                        Gcc_Path      => Gcc_Path);
                  end loop;
               end if;

               if List_Dependencies then
                  if First_Compiled_File /= No_File then
                     Inform
                       (First_Compiled_File,
                        "must be recompiled. Can't generate dependence list.");
                  else
                     List_Depend;
                  end if;

               elsif First_Compiled_File = No_File
                 and then not Do_Bind_Step
                 and then not Quiet_Output
                 and then not Library_Rebuilt
                 and then Osint.Number_Of_Files = 1
               then
                  Inform (Msg => "objects up to date.");

               elsif Do_Not_Execute
                 and then First_Compiled_File /= No_File
               then
                  Write_Name (First_Compiled_File);
                  Write_Eol;
               end if;

               --  Stop after compile step if any of:

               --    1) -n (Do_Not_Execute) specified

               --    2) -M (List_Dependencies) specified (also sets
               --       Do_Not_Execute above, so this is probably superfluous).

               --    3) -c (Compile_Only) specified, but not -b (Bind_Only)

               --    4) Made unit cannot be a main unit

               if (Do_Not_Execute
                   or List_Dependencies
                   or not Do_Bind_Step
                   or not Is_Main_Unit)
                 and then not No_Main_Subprogram
                 and then not Build_Bind_And_Link_Full_Project
               then
                  if Osint.Number_Of_Files = 1 then
                     exit Multiple_Main_Loop;

                  else
                     goto Next_Main;
                  end if;
               end if;

               --  If the objects were up-to-date check if the executable file
               --  is also up-to-date. For now always bind and link on the JVM
               --  since there is currently no simple way to check the
               --  up-to-date status of objects

               if not Hostparm.Java_VM
                 and then First_Compiled_File = No_File
               then
                  Executable_Stamp    := File_Stamp (Executable);

                  if not Executable_Obsolete then
                     Executable_Obsolete :=
                       Youngest_Obj_Stamp > Executable_Stamp;
                  end if;

                  if not Executable_Obsolete then
                     for Index in reverse 1 .. Dependencies.Last loop
                        if Is_In_Obsoleted
                             (Dependencies.Table (Index).Depends_On)
                        then
                           Enter_Into_Obsoleted
                             (Dependencies.Table (Index).This);
                        end if;
                     end loop;

                     Executable_Obsolete := Is_In_Obsoleted (Main_Source_File);
                     Dependencies.Init;
                  end if;

                  if not Executable_Obsolete then

                     --  If no Ada object files obsolete the executable, check
                     --  for younger or missing linker files.

                     Check_Linker_Options
                       (Executable_Stamp,
                        Youngest_Obj_File,
                        Youngest_Obj_Stamp);

                     Executable_Obsolete := Youngest_Obj_File /= No_File;
                  end if;

                  --  Return if the executable is up to date
                  --  and otherwise motivate the relink/rebind.

                  if not Executable_Obsolete then
                     if not Quiet_Output then
                        Inform (Executable, "up to date.");
                     end if;

                     if Osint.Number_Of_Files = 1 then
                        exit Multiple_Main_Loop;

                     else
                        goto Next_Main;
                     end if;
                  end if;

                  if Executable_Stamp (1) = ' ' then
                     Verbose_Msg (Executable, "missing.", Prefix => "  ");

                  elsif Youngest_Obj_Stamp (1) = ' ' then
                     Verbose_Msg
                       (Youngest_Obj_File,
                        "missing.",
                        Prefix => "  ");

                  elsif Youngest_Obj_Stamp > Executable_Stamp then
                     Verbose_Msg
                       (Youngest_Obj_File,
                        "(" & String (Youngest_Obj_Stamp) & ") newer than",
                        Executable,
                        "(" & String (Executable_Stamp) & ")");

                  else
                     Verbose_Msg
                       (Executable, "needs to be rebuild.",
                        Prefix => "  ");

                  end if;
               end if;
            end Recursive_Compilation_Step;
         end if;

         --  For binding and linking, we need to be in the object directory of
         --  the main project.

         if Main_Project /= No_Project then
            Change_To_Object_Directory (Main_Project);
         end if;

         --  If we are here, it means that we need to rebuilt the current
         --  main. So we set Executable_Obsolete to True to make sure that
         --  the subsequent mains will be rebuilt.

         Main_ALI_In_Place_Mode_Step : declare
            ALI_File : File_Name_Type;
            Src_File : File_Name_Type;

         begin
            Src_File      := Strip_Directory (Main_Source_File);
            ALI_File      := Lib_File_Name (Src_File, Current_Main_Index);
            Main_ALI_File := Full_Lib_File_Name (ALI_File);

            --  When In_Place_Mode, the library file can be located in the
            --  Main_Source_File directory which may not be present in the
            --  library path. In this case, use the corresponding library file
            --  name.

            if Main_ALI_File = No_File and then In_Place_Mode then
               Get_Name_String (Get_Directory (Full_Source_Name (Src_File)));
               Get_Name_String_And_Append (ALI_File);
               Main_ALI_File := Name_Find;
               Main_ALI_File := Full_Lib_File_Name (Main_ALI_File);
            end if;

            if Main_ALI_File = No_File then
               Make_Failed ("could not find the main ALI file");
            end if;
         end Main_ALI_In_Place_Mode_Step;

         if Do_Bind_Step then
            Bind_Step : declare
               Args : Argument_List
                        (Binder_Switches.First .. Binder_Switches.Last + 2);
               --  The arguments for the invocation of gnatbind

               Last_Arg : Natural := Binder_Switches.Last;
               --  Index of the last argument in Args

               Shared_Libs : Boolean := False;
               --  Set to True when there are shared library project files or
               --  when gnatbind is invoked with -shared.

            begin
               --  Check if there are shared libraries, so that gnatbind is
               --  called with -shared. Check also if gnatbind is called with
               --  -shared, so that gnatlink is called with -shared-libgcc
               --  for GCC version 3 and above, ensuring that the shared
               --  version of libgcc will be used.

               if Main_Project /= No_Project
                 and then MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None
               then
                  for Proj in Projects.First .. Projects.Last loop
                     if Projects.Table (Proj).Library and then
                       Projects.Table (Proj).Library_Kind /= Static
                     then
                        Shared_Libs := True;
                        Bind_Shared := Shared_Switch'Access;
                        exit;
                     end if;
                  end loop;
               end if;

               --  Check now for switch -shared

               if not Shared_Libs then
                  for J in Binder_Switches.First .. Last_Arg loop
                     if Binder_Switches.Table (J).all = "-shared" then
                        Shared_Libs := True;
                        exit;
                     end if;
                  end loop;
               end if;

               --  If there are shared libraries, invoke gnatlink with
               --  -shared-libgcc if GCC version is 3 or more.

               if Shared_Libs and then GCC_Version >= 3 then
                  Link_With_Shared_Libgcc := Shared_Libgcc_Switch'Access;
               end if;

               --  Get all the binder switches

               for J in Binder_Switches.First .. Last_Arg loop
                  Args (J) := Binder_Switches.Table (J);
               end loop;

               if There_Are_Stand_Alone_Libraries then
                  Last_Arg := Last_Arg + 1;
                  Args (Last_Arg) := Force_Elab_Flags_String'Access;
               end if;

               if Main_Project /= No_Project then

                  --  Put all the source directories in ADA_INCLUDE_PATH,
                  --  and all the object directories in ADA_OBJECTS_PATH

                  Prj.Env.Set_Ada_Paths (Main_Project, False);

                  --  If switch -C was specified, create a binder mapping file

                  if Create_Mapping_File then
                     Create_Binder_Mapping_File (Args, Last_Arg);
                  end if;

               end if;

               begin
                  Bind (Main_ALI_File,
                        Bind_Shared.all & Args (Args'First .. Last_Arg));

               exception
                  when others =>

                     --  If -dn was not specified, delete the temporary mapping
                     --  file, if one was created.

                     if not Debug.Debug_Flag_N
                       and then Mapping_Path /= No_Name
                     then
                        Delete_File (Get_Name_String (Mapping_Path), Discard);
                     end if;

                     --  And reraise the exception

                     raise;
               end;

               --  If -dn was not specified, delete the temporary mapping file,
               --  if one was created.

               if not Debug.Debug_Flag_N and then Mapping_Path /= No_Name then
                  Delete_File (Get_Name_String (Mapping_Path), Discard);
               end if;
            end Bind_Step;
         end if;

         if Do_Link_Step then
            Link_Step : declare
               There_Are_Libraries  : Boolean := False;
               Linker_Switches_Last : constant Integer := Linker_Switches.Last;
               Path_Option : constant String_Access :=
                               MLib.Linker_Library_Path_Option;
               Current : Natural;
               Proj2   : Project_Id;
               Depth   : Natural;

            begin
               if not Run_Path_Option then
                  Linker_Switches.Increment_Last;
                  Linker_Switches.Table (Linker_Switches.Last) :=
                    new String'("-R");
               end if;

               if Main_Project /= No_Project then
                  Library_Paths.Set_Last (0);
                  Library_Projs.Init;

                  if MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None then
                     --  Check for library projects

                     for Proj1 in 1 .. Projects.Last loop
                        if Proj1 /= Main_Project
                          and then Projects.Table (Proj1).Library
                        then
                           --  Add this project to table Library_Projs

                           There_Are_Libraries := True;
                           Depth := Projects.Table (Proj1).Depth;
                           Library_Projs.Increment_Last;
                           Current := Library_Projs.Last;

                           --  Any project with a greater depth should be
                           --  after this project in the list.

                           while Current > 1 loop
                              Proj2 := Library_Projs.Table (Current - 1);
                              exit when Projects.Table (Proj2).Depth <= Depth;
                              Library_Projs.Table (Current) := Proj2;
                              Current := Current - 1;
                           end loop;

                           Library_Projs.Table (Current) := Proj1;

                           --  If it is not a static library and path option
                           --  is set, add it to the Library_Paths table.

                           if Projects.Table (Proj1).Library_Kind /= Static
                             and then Path_Option /= null
                           then
                              Library_Paths.Increment_Last;
                              Library_Paths.Table (Library_Paths.Last) :=
                                new String'
                                  (Get_Name_String
                                       (Projects.Table (Proj1).Library_Dir));
                           end if;
                        end if;
                     end loop;

                     for Index in 1 .. Library_Projs.Last loop
                        --  Add the -L switch

                        Linker_Switches.Increment_Last;
                        Linker_Switches.Table (Linker_Switches.Last) :=
                          new String'("-L" &
                                      Get_Name_String
                                        (Projects.Table
                                           (Library_Projs.Table (Index)).
                                              Library_Dir));

                        --  Add the -l switch

                        Linker_Switches.Increment_Last;
                        Linker_Switches.Table (Linker_Switches.Last) :=
                          new String'("-l" &
                                      Get_Name_String
                                        (Projects.Table
                                           (Library_Projs.Table (Index)).
                                              Library_Name));
                     end loop;
                  end if;

                  if There_Are_Libraries then

                     --  If Path_Option is not null, create the switch
                     --  ("-Wl,-rpath," or equivalent) with all the non static
                     --  library dirs plus the standard GNAT library dir.
                     --  We do that only if Run_Path_Option is True
                     --  (not disabled by -R switch).

                     if Run_Path_Option and Path_Option /= null then
                        declare
                           Option  : String_Access;
                           Length  : Natural := Path_Option'Length;
                           Current : Natural;

                        begin
                           for Index in
                             Library_Paths.First .. Library_Paths.Last
                           loop
                              --  Add the length of the library dir plus one
                              --  for the directory separator.

                              Length :=
                                Length +
                                Library_Paths.Table (Index)'Length + 1;
                           end loop;

                           --  Finally, add the length of the standard GNAT
                           --  library dir.

                           Length := Length + MLib.Utl.Lib_Directory'Length;
                           Option := new String (1 .. Length);
                           Option (1 .. Path_Option'Length) := Path_Option.all;
                           Current := Path_Option'Length;

                           --  Put each library dir followed by a dir separator

                           for Index in
                             Library_Paths.First .. Library_Paths.Last
                           loop
                              Option
                                (Current + 1 ..
                                   Current +
                                   Library_Paths.Table (Index)'Length) :=
                                Library_Paths.Table (Index).all;
                              Current :=
                                Current +
                                Library_Paths.Table (Index)'Length + 1;
                              Option (Current) := Path_Separator;
                           end loop;

                           --  Finally put the standard GNAT library dir

                           Option
                             (Current + 1 ..
                                Current + MLib.Utl.Lib_Directory'Length) :=
                             MLib.Utl.Lib_Directory;

                           --  And add the switch to the linker switches

                           Linker_Switches.Increment_Last;
                           Linker_Switches.Table (Linker_Switches.Last) :=
                             Option;
                        end;
                     end if;

                  end if;

                  --  Put the object directories in ADA_OBJECTS_PATH

                  Prj.Env.Set_Ada_Paths (Main_Project, False);

                  --  Check for attributes Linker'Linker_Options in projects
                  --  other than the main project

                  declare
                     Linker_Options : constant String_List :=
                       Linker_Options_Switches (Main_Project);

                  begin
                     for Option in Linker_Options'Range loop
                        Linker_Switches.Increment_Last;
                        Linker_Switches.Table (Linker_Switches.Last) :=
                          Linker_Options (Option);
                     end loop;
                  end;
               end if;

               declare
                  Args : Argument_List
                           (Linker_Switches.First .. Linker_Switches.Last + 2);

                  Last_Arg : Integer := Linker_Switches.First - 1;
                  Skip     : Boolean := False;

               begin
                  --  Get all the linker switches

                  for J in Linker_Switches.First .. Linker_Switches.Last loop
                     if Skip then
                        Skip := False;

                     elsif Non_Std_Executable
                       and then Linker_Switches.Table (J).all = "-o"
                     then
                        Skip := True;

                     else
                        Last_Arg := Last_Arg + 1;
                        Args (Last_Arg) := Linker_Switches.Table (J);
                     end if;
                  end loop;

                  --  If need be, add the -o switch

                  if Non_Std_Executable then
                     Last_Arg := Last_Arg + 1;
                     Args (Last_Arg) := new String'("-o");
                     Last_Arg := Last_Arg + 1;
                     Args (Last_Arg) :=
                       new String'(Get_Name_String (Executable));
                  end if;

                  --  And invoke the linker

                  begin
                     Link (Main_ALI_File,
                           Link_With_Shared_Libgcc.all &
                           Args (Args'First .. Last_Arg));
                     Successful_Links.Increment_Last;
                     Successful_Links.Table (Successful_Links.Last) :=
                       Main_ALI_File;

                  exception
                     when Link_Failed =>
                        if Osint.Number_Of_Files = 1 or not Keep_Going then
                           raise;

                        else
                           Write_Line ("*** link failed");
                           Failed_Links.Increment_Last;
                           Failed_Links.Table (Failed_Links.Last) :=
                             Main_ALI_File;
                        end if;
                  end;
               end;

               Linker_Switches.Set_Last (Linker_Switches_Last);
            end Link_Step;
         end if;

         --  We go to here when we skip the bind and link steps

         <<Next_Main>>

         --  We go to the next main, if we did not process the last one

         if N_File < Osint.Number_Of_Files then
            Main_Source_File := Next_Main_Source;

            if Current_File_Index /= No_Index then
               Main_Index := Current_File_Index;
            end if;

            if Main_Project /= No_Project then

               --  Find the file name of the main unit

               declare
                  Main_Source_File_Name : constant String :=
                                            Get_Name_String (Main_Source_File);

                  Main_Unit_File_Name : constant String :=
                                          Prj.Env.
                                            File_Name_Of_Library_Unit_Body
                                              (Name => Main_Source_File_Name,
                                               Project => Main_Project,
                                               Main_Project_Only =>
                                                 not Unique_Compile);

                  The_Packages : constant Package_Id :=
                    Projects.Table (Main_Project).Decl.Packages;

                  Binder_Package : constant Prj.Package_Id :=
                               Prj.Util.Value_Of
                                 (Name        => Name_Binder,
                                  In_Packages => The_Packages);

                  Linker_Package : constant Prj.Package_Id :=
                               Prj.Util.Value_Of
                                 (Name       => Name_Linker,
                                 In_Packages => The_Packages);

               begin
                  --  We fail if we cannot find the main source file
                  --  as an immediate source of the main project file.

                  if Main_Unit_File_Name = "" then
                     Make_Failed ('"' & Main_Source_File_Name,
                                  """ is not a unit of project ",
                                  Project_File_Name.all & ".");

                  else
                     --  Remove any directory information from the main
                     --  source file name.

                     declare
                        Pos : Natural := Main_Unit_File_Name'Last;

                     begin
                        loop
                           exit when Pos < Main_Unit_File_Name'First
                             or else
                             Main_Unit_File_Name (Pos) = Directory_Separator;
                           Pos := Pos - 1;
                        end loop;

                        Name_Len := Main_Unit_File_Name'Last - Pos;

                        Name_Buffer (1 .. Name_Len) :=
                          Main_Unit_File_Name
                          (Pos + 1 .. Main_Unit_File_Name'Last);

                        Main_Source_File := Name_Find;
                     end;
                  end if;

                  --  We now deal with the binder and linker switches.
                  --  If no project file is used, there is nothing to do
                  --  because the binder and linker switches are the same
                  --  for all mains.

                  --  Reset the tables Binder_Switches and Linker_Switches

                  Binder_Switches.Set_Last (Last_Binder_Switch);
                  Linker_Switches.Set_Last (Last_Linker_Switch);

                  --  Add binder switches from the project file for this main,
                  --  if any.

                  if Do_Bind_Step and Binder_Package /= No_Package then
                     if Verbose_Mode then
                        Write_Str ("Adding binder switches for """);
                        Write_Str (Main_Unit_File_Name);
                        Write_Line (""".");
                     end if;

                     Add_Switches
                       (File_Name   => Main_Unit_File_Name,
                        Index       => Main_Index,
                        The_Package => Binder_Package,
                        Program     => Binder);
                  end if;

                  --  Add linker switches from the project file for this main,
                  --  if any.

                  if Do_Link_Step and Linker_Package /= No_Package then
                     if Verbose_Mode then
                        Write_Str ("Adding linker switches for""");
                        Write_Str (Main_Unit_File_Name);
                        Write_Line (""".");
                     end if;

                     Add_Switches
                       (File_Name   => Main_Unit_File_Name,
                        Index       => Main_Index,
                        The_Package => Linker_Package,
                        Program     => Linker);
                  end if;

                  --  As we are using a project file, for relative paths we add
                  --  the current working directory for any relative path on
                  --  the command line and the project directory, for any
                  --  relative path in the project file.

                  declare
                     Dir_Path : constant String_Access :=
                       new String'(Get_Name_String
                                    (Projects.Table (Main_Project).Directory));
                  begin
                     for
                       J in Last_Binder_Switch + 1 .. Binder_Switches.Last
                     loop
                        Test_If_Relative_Path
                          (Binder_Switches.Table (J),
                           Parent => Dir_Path, Including_L_Switch => False);
                     end loop;

                     for
                       J in Last_Linker_Switch + 1 .. Linker_Switches.Last
                     loop
                        Test_If_Relative_Path
                          (Linker_Switches.Table (J), Parent => Dir_Path);
                     end loop;
                  end;

                  --  We now put in the Binder_Switches and Linker_Switches
                  --  tables, the binder and linker switches of the command
                  --  line that have been put in the Saved_ tables.
                  --  These switches will follow the project file switches.

                  for J in 1 .. Saved_Binder_Switches.Last loop
                     Add_Switch
                       (Saved_Binder_Switches.Table (J),
                        Binder,
                        And_Save => False);
                  end loop;

                  for J in 1 .. Saved_Linker_Switches.Last loop
                     Add_Switch
                       (Saved_Linker_Switches.Table (J),
                        Linker,
                        And_Save => False);
                  end loop;
               end;
            end if;
         end if;

         --  Remove all marks to be sure to check sources for all executables,
         --  as the switches may be different and -s may be in use.

         Delete_All_Marks;
      end loop Multiple_Main_Loop;

      if Failed_Links.Last > 0 then
         for Index in 1 .. Successful_Links.Last loop
            Write_Str ("Linking of """);
            Write_Str (Get_Name_String (Successful_Links.Table (Index)));
            Write_Line (""" succeeded.");
         end loop;

         for Index in 1 .. Failed_Links.Last loop
            Write_Str ("Linking of """);
            Write_Str (Get_Name_String (Failed_Links.Table (Index)));
            Write_Line (""" failed.");
         end loop;

         if Total_Compilation_Failures = 0 then
            raise Compilation_Failed;
         end if;
      end if;

      if Total_Compilation_Failures /= 0 then
         List_Bad_Compilations;
         raise Compilation_Failed;
      end if;

      --  Delete the temporary mapping file that was created if we are
      --  using project files.

      if not Debug.Debug_Flag_N then
         Delete_Mapping_Files;
         Prj.Env.Delete_All_Path_Files;
      end if;

      Exit_Program (E_Success);

   exception
      when Bind_Failed =>
         Make_Failed ("*** bind failed.");

      when Compilation_Failed =>
         if not Debug.Debug_Flag_N then
            Delete_Mapping_Files;
            Prj.Env.Delete_All_Path_Files;
         end if;

         Exit_Program (E_Fatal);

      when Link_Failed =>
         Make_Failed ("*** link failed.");

      when X : others =>
         Write_Line (Exception_Information (X));
         Make_Failed ("INTERNAL ERROR. Please report.");
   end Gnatmake;

   ----------
   -- Hash --
   ----------

   function Hash (F : Name_Id) return Header_Num is
   begin
      return Header_Num (1 + F mod Max_Header);
   end Hash;

   --------------------
   -- In_Ada_Lib_Dir --
   --------------------

   function In_Ada_Lib_Dir (File : File_Name_Type) return Boolean is
      D : constant Name_Id := Get_Directory (File);
      B : constant Byte    := Get_Name_Table_Byte (D);
   begin
      return (B and Ada_Lib_Dir) /= 0;
   end In_Ada_Lib_Dir;

   ------------
   -- Inform --
   ------------

   procedure Inform (N : Name_Id := No_Name; Msg : String) is
   begin
      Osint.Write_Program_Name;

      Write_Str (": ");

      if N /= No_Name then
         Write_Str ("""");
         Write_Name (N);
         Write_Str (""" ");
      end if;

      Write_Str (Msg);
      Write_Eol;
   end Inform;

   -----------------------
   -- Init_Mapping_File --
   -----------------------

   procedure Init_Mapping_File
     (Project    : Project_Id;
      File_Index : in out Natural)
   is
      FD : File_Descriptor;

      Status : Boolean;
      --  For call to Close

   begin
      --  Increase the index of the last mapping file for this project

      Last_Mapping_File_Names (Project) :=
        Last_Mapping_File_Names (Project) + 1;

      --  If there is a project file, call Create_Mapping_File with
      --  the project id.

      if Project /= No_Project then
         Prj.Env.Create_Mapping_File
           (Project,
            The_Mapping_File_Names
              (Project, Last_Mapping_File_Names (Project)));

      --  Otherwise, just create an empty file

      else
         Tempdir.Create_Temp_File
           (FD,
            The_Mapping_File_Names
              (No_Project, Last_Mapping_File_Names (No_Project)));
         if FD = Invalid_FD then
            Make_Failed ("disk full");
         end if;

         Close (FD, Status);

         if not Status then
            Make_Failed ("disk full");
         end if;
      end if;

      --  And return the index of the newly created file

      File_Index := Last_Mapping_File_Names (Project);
   end Init_Mapping_File;

   ------------
   -- Init_Q --
   ------------

   procedure Init_Q is
   begin
      First_Q_Initialization := False;
      Q_Front := Q.First;
      Q.Set_Last (Q.First);
   end Init_Q;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      --  Override default initialization of Check_Object_Consistency
      --  since this is normally False for GNATBIND, but is True for
      --  GNATMAKE since we do not need to check source consistency
      --  again once GNATMAKE has looked at the sources to check.

      Check_Object_Consistency := True;

      --  Package initializations. The order of calls is important here

      Output.Set_Standard_Error;

      Gcc_Switches.Init;
      Binder_Switches.Init;
      Linker_Switches.Init;

      Csets.Initialize;
      Namet.Initialize;

      Snames.Initialize;

      Prj.Initialize;

      Dependencies.Init;

      RTS_Specified := null;

      Mains.Delete;

      --  Add the directory where gnatmake is invoked in front of the
      --  path, if gnatmake is invoked with directory information.
      --  Only do this if the platform is not VMS, where the notion of path
      --  does not really exist.

      if not OpenVMS then
         declare
            Command : constant String := Command_Name;

         begin
            for Index in reverse Command'Range loop
               if Command (Index) = Directory_Separator then
                  declare
                     Absolute_Dir : constant String :=
                                      Normalize_Pathname
                                        (Command (Command'First .. Index));

                     PATH : constant String :=
                                      Absolute_Dir &
                                      Path_Separator &
                                      Getenv ("PATH").all;

                  begin
                     Setenv ("PATH", PATH);
                  end;

                  exit;
               end if;
            end loop;
         end;
      end if;

      --  Scan the switches and arguments

      Scan_Args : for Next_Arg in 1 .. Argument_Count loop
         Scan_Make_Arg (Argument (Next_Arg), And_Save => True);
      end loop Scan_Args;

      if Usage_Requested then
         Usage;
      end if;

      --  Test for trailing -P switch

      if Project_File_Name_Present and then Project_File_Name = null then
         Make_Failed ("project file name missing after -P");

      --  Test for trailing -o switch

      elsif Output_File_Name_Present
        and then not Output_File_Name_Seen
      then
         Make_Failed ("output file name missing after -o");

      --  Test for trailing -D switch

      elsif Object_Directory_Present
        and then not Object_Directory_Seen then
         Make_Failed ("object directory missing after -D");
      end if;

      --  Test for simultaneity of -i and -D

      if Object_Directory_Path /= null and then In_Place_Mode then
         Make_Failed ("-i and -D cannot be used simutaneously");
      end if;

      --  Deal with -C= switch

      if Gnatmake_Mapping_File /= null then
         --  First, check compatibility with other switches

         if Project_File_Name /= null then
            Make_Failed ("-C= switch is not compatible with -P switch");

         elsif Saved_Maximum_Processes > 1 then
            Make_Failed ("-C= switch is not compatible with -jnnn switch");
         end if;

         Fmap.Initialize (Gnatmake_Mapping_File.all);
         Add_Switch
           ("-gnatem=" & Gnatmake_Mapping_File.all,
            Compiler,
            And_Save => True);
      end if;

      if Project_File_Name /= null then

         --  A project file was specified by a -P switch

         if Verbose_Mode then
            Write_Eol;
            Write_Str ("Parsing Project File """);
            Write_Str (Project_File_Name.all);
            Write_Str (""".");
            Write_Eol;
         end if;

         --  Avoid looking in the current directory for ALI files

         --  Look_In_Primary_Dir := False;

         --  Set the project parsing verbosity to whatever was specified
         --  by a possible -vP switch.

         Prj.Pars.Set_Verbosity (To => Current_Verbosity);

         --  Parse the project file.
         --  If there is an error, Main_Project will still be No_Project.

         Prj.Pars.Parse
           (Project           => Main_Project,
            Project_File_Name => Project_File_Name.all,
            Packages_To_Check => Packages_To_Check_By_Gnatmake);

         if Main_Project = No_Project then
            Make_Failed ("""", Project_File_Name.all, """ processing failed");
         end if;

         if Verbose_Mode then
            Write_Eol;
            Write_Str ("Parsing of Project File """);
            Write_Str (Project_File_Name.all);
            Write_Str (""" is finished.");
            Write_Eol;
         end if;

         --  We add the source directories and the object directories
         --  to the search paths.

         Add_Source_Directories (Main_Project);
         Add_Object_Directories (Main_Project);

         --  Compute depth of each project

         for Proj in 1 .. Projects.Last loop
            Projects.Table (Proj).Seen := False;
            Projects.Table (Proj).Depth := 0;
         end loop;

         Recursive_Compute_Depth
           (Main_Project, Depth => 1);

      else

         Osint.Add_Default_Search_Dirs;

         --  Source file lookups should be cached for efficiency.
         --  Source files are not supposed to change. However, we do that now
         --  only if no project file is used; if a project file is used, we
         --  do it just after changing the directory to the object directory.

         Osint.Source_File_Data (Cache => True);

         --  Read gnat.adc file to initialize Fname.UF

         Fname.UF.Initialize;

         begin
            Fname.SF.Read_Source_File_Name_Pragmas;

         exception
            when Err : SFN_Scan.Syntax_Error_In_GNAT_ADC =>
               Make_Failed (Exception_Message (Err));
         end;
      end if;

      --  Make sure no project object directory is recorded

      Project_Object_Directory := No_Project;

   end Initialize;

   ----------------------------
   -- Insert_Project_Sources --
   ----------------------------

   procedure Insert_Project_Sources
     (The_Project  : Project_Id;
      All_Projects : Boolean;
      Into_Q       : Boolean)
   is
      Put_In_Q : Boolean := Into_Q;
      Unit     : Com.Unit_Data;
      Sfile    : Name_Id;

      Extending : constant Boolean :=
                    Projects.Table (The_Project).Extends /= No_Project;

      function Check_Project (P : Project_Id) return Boolean;
      --  Returns True if P is The_Project or a project extended by
      --  The_Project.

      -------------------
      -- Check_Project --
      -------------------

      function Check_Project (P : Project_Id) return Boolean is
      begin
         if All_Projects or P = The_Project then
            return True;
         elsif Extending then
            declare
               Data : Project_Data := Projects.Table (The_Project);

            begin
               loop
                  if P = Data.Extends then
                     return True;
                  end if;

                  Data := Projects.Table (Data.Extends);
                  exit when Data.Extends = No_Project;
               end loop;
            end;
         end if;

         return False;
      end Check_Project;

   --  Start of processing of Insert_Project_Sources

   begin
      --  For all the sources in the project files,

      for Id in Com.Units.First .. Com.Units.Last loop
         Unit  := Com.Units.Table (Id);
         Sfile := No_Name;

         --  If there is a source for the body, and the body has not been
         --  locally removed,

         if Unit.File_Names (Com.Body_Part).Name /= No_Name
           and then Unit.File_Names (Com.Body_Part).Path /= Slash
         then

            --  And it is a source for the specified project

            if Check_Project (Unit.File_Names (Com.Body_Part).Project) then

               --  If we don't have a spec, we cannot consider the source
               --  if it is a subunit

               if Unit.File_Names (Com.Specification).Name = No_Name then
                  declare
                     Src_Ind : Source_File_Index;

                     --  Here we are cheating a little bit: we don't want to
                     --  use Sinput.L, because it depends on the GNAT tree
                     --  (Atree, Sinfo, ...). So, we pretend that it is
                     --  a project file, and we use Sinput.P.
                     --  Source_File_Is_Subunit is just scanning through
                     --  the file until it finds one of the reserved words
                     --  separate, procedure, function, generic or package.
                     --  Fortunately, these Ada reserved words are also
                     --  reserved for project files.

                  begin
                     Src_Ind := Sinput.P.Load_Project_File
                                  (Get_Name_String
                                     (Unit.File_Names (Com.Body_Part).Path));

                     --  If it is a subunit, discard it

                     if Sinput.P.Source_File_Is_Subunit (Src_Ind) then
                        Sfile := No_Name;

                     else
                        Sfile := Unit.File_Names (Com.Body_Part).Name;
                     end if;
                  end;

               else
                  Sfile := Unit.File_Names (Com.Body_Part).Name;
               end if;
            end if;

         elsif Unit.File_Names (Com.Specification).Name /= No_Name
           and then Unit.File_Names (Com.Specification).Path /= Slash
           and then Check_Project (Unit.File_Names (Com.Specification).Project)
         then
            --  If there is no source for the body, but there is a source
            --  for the spec which has not been locally removed, then we take
            --  this one.

            Sfile := Unit.File_Names (Com.Specification).Name;
         end if;

         --  If Put_In_Q is True, we insert into the Q

         if Put_In_Q then

            --  For the first source inserted into the Q, we need
            --  to initialize the Q, but not for the subsequent sources.

            if First_Q_Initialization then
               Init_Q;
            end if;

            --  And of course, we only insert in the Q if the source
            --  is not marked.

            if Sfile /= No_Name and then not Is_Marked (Sfile) then
               if Verbose_Mode then
                  Write_Str ("Adding """);
                  Write_Str (Get_Name_String (Sfile));
                  Write_Line (""" to the queue");
               end if;

               Insert_Q (Sfile);
               Mark (Sfile);
            end if;

         elsif Sfile /= No_Name then

            --  If Put_In_Q is False, we add the source as it it were
            --  specified on the command line, and we set Put_In_Q to True,
            --  so that the following sources will be put directly in the
            --  queue. This will allow parallel compilation processes if -jx
            --  switch is used.

            if Verbose_Mode then
               Write_Str ("Adding """);
               Write_Str (Get_Name_String (Sfile));
               Write_Line (""" as if on the command line");
            end if;

            Osint.Add_File (Get_Name_String (Sfile));
            Put_In_Q := True;
         end if;
      end loop;
   end Insert_Project_Sources;

   --------------
   -- Insert_Q --
   --------------

   procedure Insert_Q
     (Source_File : File_Name_Type;
      Source_Unit : Unit_Name_Type := No_Name;
      Index       : Int            := 0)
   is
   begin
      if Debug.Debug_Flag_Q then
         Write_Str ("   Q := Q + [ ");
         Write_Name (Source_File);

         if Index /= 0 then
            Write_Str (", ");
            Write_Int (Index);
         end if;

         Write_Str (" ] ");
         Write_Eol;
      end if;

      Q.Table (Q.Last) :=
        (File  => Source_File,
         Unit  => Source_Unit,
         Index => Index);
      Q.Increment_Last;
   end Insert_Q;

   ---------------------
   -- Is_In_Obsoleted --
   ---------------------

   function Is_In_Obsoleted (F : Name_Id) return Boolean is
   begin
      if F = No_File then
         return False;

      else
         declare
            Name  : constant String := Get_Name_String (F);
            First : Natural := Name'Last;
            F2    : Name_Id := F;

         begin
            while First > Name'First
              and then Name (First - 1) /= Directory_Separator
              and then Name (First - 1) /= '/'
            loop
               First := First - 1;
            end loop;

            if First /= Name'First then
               Name_Len := 0;
               Add_Str_To_Name_Buffer (Name (First .. Name'Last));
               F2 := Name_Find;
            end if;

            return Obsoleted.Get (F2);
         end;
      end if;
   end Is_In_Obsoleted;

   ----------------------------
   -- Is_In_Object_Directory --
   ----------------------------

   function Is_In_Object_Directory
     (Source_File   : File_Name_Type;
      Full_Lib_File : File_Name_Type) return Boolean
   is
   begin
      --  There is something to check only when using project files.
      --  Otherwise, this function returns True (last line of the function).

      if Main_Project /= No_Project then
         declare
            Source_File_Name : constant String :=
                                 Get_Name_String (Source_File);
            Saved_Verbosity  : constant Verbosity := Prj.Com.Current_Verbosity;
            Project          : Project_Id := No_Project;
            Path_Name        : Name_Id := No_Name;
            Data             : Project_Data;

         begin
            --  Call Get_Reference to know the ultimate extending project of
            --  the source. Call it with verbosity default to avoid verbose
            --  messages.

            Prj.Com.Current_Verbosity := Default;
            Prj.Env.
              Get_Reference
              (Source_File_Name => Source_File_Name,
               Project          => Project,
               Path             => Path_Name);
            Prj.Com.Current_Verbosity := Saved_Verbosity;

            --  If this source is in a project, check that the ALI file is
            --  in its object directory. If it is not, return False, so that
            --  the ALI file will not be skipped.

            --  If the source is not in an extending project, we fall back to
            --  the general case and return True at the end of the function.

            if Project /= No_Project
              and then Projects.Table (Project).Extends /= No_Project
            then
               Data := Projects.Table (Project);

               declare
                  Object_Directory : constant String :=
                                       Normalize_Pathname
                                         (Get_Name_String
                                           (Data.Object_Directory));

                  Olast : Natural := Object_Directory'Last;

                  Lib_File_Directory : constant String :=
                                         Normalize_Pathname (Dir_Name
                                           (Get_Name_String (Full_Lib_File)));

                  Llast : Natural := Lib_File_Directory'Last;

               begin
                  --  For directories, Normalize_Pathname may or may not put
                  --  a directory separator at the end, depending on its input.
                  --  Remove any last directory separator before comparaison.
                  --  Returns True only if the two directories are the same.

                  if Object_Directory (Olast) = Directory_Separator then
                     Olast := Olast - 1;
                  end if;

                  if Lib_File_Directory (Llast) = Directory_Separator then
                     Llast := Llast - 1;
                  end if;

                  return Object_Directory (Object_Directory'First .. Olast) =
                        Lib_File_Directory (Lib_File_Directory'First .. Llast);
               end;
            end if;
         end;
      end if;

      --  When the source is not in a project file, always return True

      return True;
   end Is_In_Object_Directory;

   ----------
   -- Link --
   ----------

   procedure Link (ALI_File : File_Name_Type; Args : Argument_List) is
      Link_Args : Argument_List (1 .. Args'Length + 1);
      Success   : Boolean;

   begin
      Get_Name_String (ALI_File);
      Link_Args (1) := new String'(Name_Buffer (1 .. Name_Len));

      Link_Args (2 .. Args'Length + 1) :=  Args;

      GNAT.OS_Lib.Normalize_Arguments (Link_Args);

      Display (Gnatlink.all, Link_Args);

      if Gnatlink_Path = null then
         Make_Failed ("error, unable to locate ", Gnatlink.all);
      end if;

      GNAT.OS_Lib.Spawn (Gnatlink_Path.all, Link_Args, Success);

      if not Success then
         raise Link_Failed;
      end if;
   end Link;

   ---------------------------
   -- List_Bad_Compilations --
   ---------------------------

   procedure List_Bad_Compilations is
   begin
      for J in Bad_Compilation.First .. Bad_Compilation.Last loop
         if Bad_Compilation.Table (J).File = No_File then
            null;
         elsif not Bad_Compilation.Table (J).Found then
            Inform (Bad_Compilation.Table (J).File, "not found");
         else
            Inform (Bad_Compilation.Table (J).File, "compilation error");
         end if;
      end loop;
   end List_Bad_Compilations;

   -----------------
   -- List_Depend --
   -----------------

   procedure List_Depend is
      Lib_Name  : Name_Id;
      Obj_Name  : Name_Id;
      Src_Name  : Name_Id;

      Len       : Natural;
      Line_Pos  : Natural;
      Line_Size : constant := 77;

   begin
      Set_Standard_Output;

      for A in ALIs.First .. ALIs.Last loop
         Lib_Name := ALIs.Table (A).Afile;

         --  We have to provide the full library file name in In_Place_Mode

         if In_Place_Mode then
            Lib_Name := Full_Lib_File_Name (Lib_Name);
         end if;

         Obj_Name := Object_File_Name (Lib_Name);
         Write_Name (Obj_Name);
         Write_Str (" :");

         Get_Name_String (Obj_Name);
         Len := Name_Len;
         Line_Pos := Len + 2;

         for D in ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep loop
            Src_Name := Sdep.Table (D).Sfile;

            if Is_Internal_File_Name (Src_Name)
              and then not Check_Readonly_Files
            then
               null;
            else
               if not Quiet_Output then
                  Src_Name := Full_Source_Name (Src_Name);
               end if;

               Get_Name_String (Src_Name);
               Len := Name_Len;

               if Line_Pos + Len + 1 > Line_Size then
                  Write_Str (" \");
                  Write_Eol;
                  Line_Pos := 0;
               end if;

               Line_Pos := Line_Pos + Len + 1;

               Write_Str (" ");
               Write_Name (Src_Name);
            end if;
         end loop;

         Write_Eol;
      end loop;

      Set_Standard_Error;
   end List_Depend;

   -----------------
   -- Make_Failed --
   -----------------

   procedure Make_Failed (S1 : String; S2 : String := ""; S3 : String := "") is
   begin
      Delete_All_Temp_Files;
      Osint.Fail (S1, S2, S3);
   end Make_Failed;

   --------------------
   -- Mark_Directory --
   --------------------

   procedure Mark_Directory
     (Dir  : String;
      Mark : Lib_Mark_Type)
   is
      N : Name_Id;
      B : Byte;

   begin
      --  Dir last character is supposed to be a directory separator

      Name_Len := Dir'Length;
      Name_Buffer (1 .. Name_Len) := Dir;

      if not Is_Directory_Separator (Name_Buffer (Name_Len)) then
         Name_Len := Name_Len + 1;
         Name_Buffer (Name_Len) := Directory_Separator;
      end if;

      --  Add flags to the already existing flags

      N := Name_Find;
      B := Get_Name_Table_Byte (N);
      Set_Name_Table_Byte (N, B or Mark);
   end Mark_Directory;

   -----------------------------
   -- Recursive_Compute_Depth --
   -----------------------------

   procedure Recursive_Compute_Depth
     (Project : Project_Id;
      Depth   : Natural)
   is
      List : Project_List;
      Proj : Project_Id;

   begin
      --  Nothing to do if there is no project or if the project has already
      --  been seen or if the depth is large enough.

      if Project = No_Project
        or else Projects.Table (Project).Seen
        or else Projects.Table (Project).Depth >= Depth
      then
         return;
      end if;

      Projects.Table (Project).Depth := Depth;

      --  Mark the project as Seen to avoid endless loop caused by limited
      --  withs.

      Projects.Table (Project).Seen := True;

      List := Projects.Table (Project).Imported_Projects;

      --  Visit each imported project

      while List /= Empty_Project_List loop
         Proj := Project_Lists.Table (List).Project;
         List := Project_Lists.Table (List).Next;
         Recursive_Compute_Depth
           (Project => Proj,
            Depth => Depth + 1);
      end loop;

      --  Visit a project being extended, if any

      Recursive_Compute_Depth
        (Project => Projects.Table (Project).Extends,
         Depth   => Depth + 1);

      --  Reset the Seen flag, as we leave this project

      Projects.Table (Project).Seen := False;
   end Recursive_Compute_Depth;

   -----------------------
   -- Sigint_Intercpted --
   -----------------------

   procedure Sigint_Intercepted is
   begin
      Write_Line ("*** Interrupted ***");
      Delete_All_Temp_Files;
      OS_Exit (1);
   end Sigint_Intercepted;

   -------------------
   -- Scan_Make_Arg --
   -------------------

   procedure Scan_Make_Arg (Argv : String; And_Save : Boolean) is
   begin
      pragma Assert (Argv'First = 1);

      if Argv'Length = 0 then
         return;
      end if;

      --  If the previous switch has set the Project_File_Name_Present
      --  flag (that is we have seen a -P alone), then the next argument is
      --  the name of the project file.

      if Project_File_Name_Present and then Project_File_Name = null then
         if Argv (1) = '-' then
            Make_Failed ("project file name missing after -P");

         else
            Project_File_Name_Present := False;
            Project_File_Name := new String'(Argv);
         end if;

      --  If the previous switch has set the Output_File_Name_Present
      --  flag (that is we have seen a -o), then the next argument is
      --  the name of the output executable.

      elsif Output_File_Name_Present
        and then not Output_File_Name_Seen
      then
         Output_File_Name_Seen := True;

         if Argv (1) = '-' then
            Make_Failed ("output file name missing after -o");

         else
            Add_Switch ("-o", Linker, And_Save => And_Save);

            --  Automatically add the executable suffix if it has not been
            --  specified explicitly.

            declare
               Canonical_Argv : String := Argv;
            begin
               --  Get the file name in canonical case to accept as is
               --  names ending with ".EXE" on VMS and Windows.

               Canonical_Case_File_Name (Canonical_Argv);

               if Executable_Suffix'Length /= 0
                 and then (Canonical_Argv'Length <= Executable_Suffix'Length
                        or else Canonical_Argv
                                  (Canonical_Argv'Last -
                                   Executable_Suffix'Length + 1
                                   .. Canonical_Argv'Last)
                                /= Executable_Suffix)
               then
                  Add_Switch
                    (Argv & Executable_Suffix,
                     Linker,
                     And_Save => And_Save);
               else
                  Add_Switch (Argv, Linker, And_Save => And_Save);
               end if;
            end;
         end if;

      --  If the previous switch has set the Object_Directory_Present flag
      --  (that is we have seen a -D), then the next argument is
      --  the path name of the object directory..

      elsif Object_Directory_Present
        and then not Object_Directory_Seen
      then
         Object_Directory_Seen := True;

         if Argv (1) = '-' then
            Make_Failed ("object directory path name missing after -D");

         elsif not Is_Directory (Argv) then
            Make_Failed ("cannot find object directory """, Argv, """");

         else
            Add_Lib_Search_Dir (Argv);

            --  Specify the object directory to the binder

            Add_Switch ("-aO" & Argv, Binder, And_Save => And_Save);

            --  Record the object directory. Make sure it ends with a directory
            --  separator.

            if Argv (Argv'Last) = Directory_Separator then
               Object_Directory_Path := new String'(Argv);

            else
               Object_Directory_Path :=
                 new String'(Argv & Directory_Separator);
            end if;
         end if;

      --  Then check if we are dealing with -cargs/-bargs/-largs/-margs

      elsif Argv = "-bargs"
              or else
            Argv = "-cargs"
              or else
            Argv = "-largs"
              or else
            Argv = "-margs"
      then
         case Argv (2) is
            when 'c' => Program_Args := Compiler;
            when 'b' => Program_Args := Binder;
            when 'l' => Program_Args := Linker;
            when 'm' => Program_Args := None;

            when others =>
               raise Program_Error;
         end case;

      --  A special test is needed for the -o switch within a -largs
      --  since that is another way to specify the name of the final
      --  executable.

      elsif Program_Args = Linker
        and then Argv = "-o"
      then
         Make_Failed ("switch -o not allowed within a -largs. " &
                      "Use -o directly.");

      --  Check to see if we are reading switches after a -cargs,
      --  -bargs or -largs switch. If yes save it.

      elsif Program_Args /= None then

         --  Check to see if we are reading -I switches in order
         --  to take into account in the src & lib search directories.

         if Argv'Length > 2 and then Argv (1 .. 2) = "-I" then
            if Argv (3 .. Argv'Last) = "-" then
               Look_In_Primary_Dir := False;

            elsif Program_Args = Compiler then
               if Argv (3 .. Argv'Last) /= "-" then
                  Add_Src_Search_Dir (Argv (3 .. Argv'Last));
               end if;

            elsif Program_Args = Binder then
               Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
            end if;
         end if;

         Add_Switch (Argv, Program_Args, And_Save => And_Save);

      --  Handle non-default compiler, binder, linker, and handle --RTS switch

      elsif Argv'Length > 2 and then Argv (1 .. 2) = "--" then
         if Argv'Length > 6
           and then Argv (1 .. 6) = "--GCC="
         then
            declare
               Program_Args : constant Argument_List_Access :=
                                Argument_String_To_List
                                  (Argv (7 .. Argv'Last));

            begin
               if And_Save then
                  Saved_Gcc := new String'(Program_Args.all (1).all);
               else
                  Gcc := new String'(Program_Args.all (1).all);
               end if;

               for J in 2 .. Program_Args.all'Last loop
                  Add_Switch
                    (Program_Args.all (J).all,
                     Compiler,
                     And_Save => And_Save);
               end loop;
            end;

         elsif Argv'Length > 11
           and then Argv (1 .. 11) = "--GNATBIND="
         then
            declare
               Program_Args : constant Argument_List_Access :=
                                Argument_String_To_List
                                  (Argv (12 .. Argv'Last));

            begin
               if And_Save then
                  Saved_Gnatbind := new String'(Program_Args.all (1).all);
               else
                  Gnatbind := new String'(Program_Args.all (1).all);
               end if;

               for J in 2 .. Program_Args.all'Last loop
                  Add_Switch
                    (Program_Args.all (J).all, Binder, And_Save => And_Save);
               end loop;
            end;

         elsif Argv'Length > 11
           and then Argv (1 .. 11) = "--GNATLINK="
         then
            declare
               Program_Args : constant Argument_List_Access :=
                                Argument_String_To_List
                                  (Argv (12 .. Argv'Last));
            begin
               if And_Save then
                  Saved_Gnatlink := new String'(Program_Args.all (1).all);
               else
                  Gnatlink := new String'(Program_Args.all (1).all);
               end if;

               for J in 2 .. Program_Args.all'Last loop
                  Add_Switch (Program_Args.all (J).all, Linker);
               end loop;
            end;

         elsif Argv'Length >= 5 and then
           Argv (1 .. 5) = "--RTS"
         then
            Add_Switch (Argv, Compiler, And_Save => And_Save);
            Add_Switch (Argv, Binder, And_Save => And_Save);

            if Argv'Length <= 6 or else Argv (6) /= '=' then
               Make_Failed ("missing path for --RTS");

            else
               --  Check that this is the first time we see this switch or
               --  if it is not the first time, the same path is specified.

               if RTS_Specified = null then
                  RTS_Specified := new String'(Argv (7 .. Argv'Last));

               elsif RTS_Specified.all /= Argv (7 .. Argv'Last) then
                  Make_Failed ("--RTS cannot be specified multiple times");
               end if;

               --  Valid --RTS switch

               No_Stdinc := True;
               No_Stdlib := True;
               RTS_Switch := True;

               declare
                  Src_Path_Name : constant String_Ptr :=
                                    Get_RTS_Search_Dir
                                      (Argv (7 .. Argv'Last), Include);

                  Lib_Path_Name : constant String_Ptr :=
                                    Get_RTS_Search_Dir
                                      (Argv (7 .. Argv'Last), Objects);

               begin
                  if Src_Path_Name /= null and then
                    Lib_Path_Name /= null
                  then
                     --  Set the RTS_*_Path_Name variables, so that the correct
                     --  directories will be set when
                     --  Osint.Add_Default_Search_Dirs will be called later.

                     RTS_Src_Path_Name := Src_Path_Name;
                     RTS_Lib_Path_Name := Lib_Path_Name;

                  elsif  Src_Path_Name = null
                    and Lib_Path_Name = null then
                     Make_Failed ("RTS path not valid: missing " &
                                  "adainclude and adalib directories");

                  elsif Src_Path_Name = null then
                     Make_Failed ("RTS path not valid: missing adainclude " &
                                  "directory");

                  elsif  Lib_Path_Name = null then
                     Make_Failed ("RTS path not valid: missing adalib " &
                                  "directory");
                  end if;
               end;
            end if;

         else
            Make_Failed ("unknown switch: ", Argv);
         end if;

      --  If we have seen a regular switch process it

      elsif Argv (1) = '-' then

         if Argv'Length = 1 then
            Make_Failed ("switch character cannot be followed by a blank");

         --  -I-

         elsif Argv (2 .. Argv'Last) = "I-" then
            Look_In_Primary_Dir := False;

         --  Forbid  -?-  or  -??-  where ? is any character

         elsif (Argv'Length = 3 and then Argv (3) = '-')
           or else (Argv'Length = 4 and then Argv (4) = '-')
         then
            Make_Failed ("trailing ""-"" at the end of ", Argv, " forbidden.");

         --  -Idir

         elsif Argv (2) = 'I' then
            Add_Src_Search_Dir (Argv (3 .. Argv'Last));
            Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
            Add_Switch (Argv, Compiler, And_Save => And_Save);
            Add_Switch (Argv, Binder, And_Save => And_Save);

         --  -aIdir (to gcc this is like a -I switch)

         elsif Argv'Length >= 3 and then Argv (2 .. 3) = "aI" then
            Add_Src_Search_Dir (Argv (4 .. Argv'Last));
            Add_Switch ("-I" & Argv (4 .. Argv'Last),
                        Compiler,
                        And_Save => And_Save);
            Add_Switch (Argv, Binder, And_Save => And_Save);

         --  -aOdir

         elsif Argv'Length >= 3 and then Argv (2 .. 3) = "aO" then
            Add_Lib_Search_Dir (Argv (4 .. Argv'Last));
            Add_Switch (Argv, Binder, And_Save => And_Save);

         --  -aLdir (to gnatbind this is like a -aO switch)

         elsif Argv'Length >= 3 and then Argv (2 .. 3) = "aL" then
            Mark_Directory (Argv (4 .. Argv'Last), Ada_Lib_Dir);
            Add_Lib_Search_Dir (Argv (4 .. Argv'Last));
            Add_Switch ("-aO" & Argv (4 .. Argv'Last),
                        Binder,
                        And_Save => And_Save);

         --  -Adir (to gnatbind this is like a -aO switch, to gcc like a -I)

         elsif Argv (2) = 'A' then
            Mark_Directory (Argv (3 .. Argv'Last), Ada_Lib_Dir);
            Add_Src_Search_Dir (Argv (3 .. Argv'Last));
            Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
            Add_Switch ("-I"  & Argv (3 .. Argv'Last),
                        Compiler,
                        And_Save => And_Save);
            Add_Switch ("-aO" & Argv (3 .. Argv'Last),
                        Binder,
                        And_Save => And_Save);

         --  -Ldir

         elsif Argv (2) = 'L' then
            Add_Switch (Argv, Linker, And_Save => And_Save);

         --  For -gxxxxx, -pg, -mxxx, -fxxx: give the switch to both the
         --  compiler and the linker (except for -gnatxxx which is only for
         --  the compiler). Some of the -mxxx (for example -m64) and -fxxx
         --  (for example -ftest-coverage for gcov) need to be used when
         --  compiling the binder generated files, and using all these gcc
         --  switches for the binder generated files should not be a problem.

         elsif
           (Argv (2) = 'g' and then (Argv'Last < 5
                                       or else Argv (2 .. 5) /= "gnat"))
             or else Argv (2 .. Argv'Last) = "pg"
             or else (Argv (2) = 'm' and then Argv'Last > 2)
             or else (Argv (2) = 'f' and then Argv'Last > 2)
         then
            Add_Switch (Argv, Compiler, And_Save => And_Save);
            Add_Switch (Argv, Linker, And_Save => And_Save);

         --  -C=<mapping file>

         elsif Argv'Last > 2 and then Argv (2) = 'C' then
            if And_Save then
               if Argv (3) /= '=' or else Argv'Last <= 3 then
                  Make_Failed ("illegal switch ", Argv);
               end if;

               Gnatmake_Mapping_File := new String'(Argv (4 .. Argv'Last));
            end if;

         --  -D

         elsif Argv'Last = 2 and then Argv (2) = 'D' then
            if Project_File_Name /= null then
               Make_Failed ("-D cannot be used in conjunction with a " &
                            "project file");

            else
               Scan_Make_Switches (Argv);
            end if;

         --  -d

         elsif Argv (2) = 'd'
           and then Argv'Last = 2
         then
            Display_Compilation_Progress := True;

         --  -i

         elsif Argv'Last = 2 and then Argv (2) = 'i' then
            if Project_File_Name /= null then
               Make_Failed ("-i cannot be used in conjunction with a " &
                            "project file");

            else
               Scan_Make_Switches (Argv);
            end if;

         --  -j (need to save the result)

         elsif Argv (2) = 'j' then
            Scan_Make_Switches (Argv);

            if And_Save then
               Saved_Maximum_Processes := Maximum_Processes;
            end if;

         --  -m

         elsif Argv (2) = 'm'
           and then Argv'Last = 2
         then
            Minimal_Recompilation := True;

         --  -u

         elsif Argv (2) = 'u'
           and then Argv'Last = 2
         then
            Unique_Compile   := True;
            Compile_Only := True;
            Do_Bind_Step     := False;
            Do_Link_Step     := False;

         --  -U

         elsif Argv (2) = 'U'
           and then Argv'Last = 2
         then
            Unique_Compile_All_Projects := True;
            Unique_Compile   := True;
            Compile_Only := True;
            Do_Bind_Step     := False;
            Do_Link_Step     := False;

         --  -Pprj or -P prj (only once, and only on the command line)

         elsif Argv (2) = 'P' then
            if Project_File_Name /= null then
               Make_Failed ("cannot have several project files specified");

            elsif Object_Directory_Path /= null then
               Make_Failed ("-D cannot be used in conjunction with a " &
                            "project file");

            elsif In_Place_Mode then
               Make_Failed ("-i cannot be used in conjunction with a " &
                            "project file");

            elsif not And_Save then

               --  It could be a tool other than gnatmake (i.e, gnatdist)
               --  or a -P switch inside a project file.

               Fail
                 ("either the tool is not ""project-aware"" or " &
                  "a project file is specified inside a project file");

            elsif Argv'Last = 2 then

               --  -P is used alone: the project file name is the next option

               Project_File_Name_Present := True;

            else
               Project_File_Name := new String'(Argv (3 .. Argv'Last));
            end if;

         --  -vPx  (verbosity of the parsing of the project files)

         elsif Argv'Last = 4
           and then Argv (2 .. 3) = "vP"
           and then Argv (4) in '0' .. '2'
         then
            if And_Save then
               case Argv (4) is
                  when '0' =>
                     Current_Verbosity := Prj.Default;
                  when '1' =>
                     Current_Verbosity := Prj.Medium;
                  when '2' =>
                     Current_Verbosity := Prj.High;
                  when others =>
                     null;
               end case;
            end if;

         --  -Xext=val  (External assignment)

         elsif Argv (2) = 'X'
           and then Is_External_Assignment (Argv)
         then
            --  Is_External_Assignment has side effects
            --  when it returns True;

            null;

         --  If -gnath is present, then generate the usage information
         --  right now and do not pass this option on to the compiler calls.

         elsif Argv = "-gnath" then
            Usage;

         --  If -gnatc is specified, make sure the bind step and the link
         --  step are not executed.

         elsif Argv'Length >= 6 and then Argv (2 .. 6) = "gnatc" then

            --  If -gnatc is specified, make sure the bind step and the link
            --  step are not executed.

            Add_Switch (Argv, Compiler, And_Save => And_Save);
            Operating_Mode := Check_Semantics;
            Check_Object_Consistency := False;
            Compile_Only             := True;
            Do_Bind_Step                 := False;
            Do_Link_Step                 := False;

         elsif Argv (2 .. Argv'Last) = "nostdlib" then

            --  Don't pass -nostdlib to gnatlink, it will disable
            --  linking with all standard library files.

            No_Stdlib := True;

            Add_Switch (Argv, Compiler, And_Save => And_Save);
            Add_Switch (Argv, Binder, And_Save => And_Save);

         elsif Argv (2 .. Argv'Last) = "nostdinc" then

            --  Pass -nostdinc to the Compiler and to gnatbind

            No_Stdinc := True;
            Add_Switch (Argv, Compiler, And_Save => And_Save);
            Add_Switch (Argv, Binder, And_Save => And_Save);

            --  By default all switches with more than one character
            --  or one character switches which are not in 'a' .. 'z'
            --  (except 'C', 'F', 'M' and 'B') are passed to the compiler,
            --  unless we are dealing with a debug switch (starts with 'd')
            --  or an extended gnatmake switch (starts with 'e').

         elsif Argv (2) /= 'd'
           and then Argv (2) /= 'e'
           and then Argv (2 .. Argv'Last) /= "C"
           and then Argv (2 .. Argv'Last) /= "F"
           and then Argv (2 .. Argv'Last) /= "M"
           and then Argv (2 .. Argv'Last) /= "B"
           and then (Argv'Length > 2 or else Argv (2) not in 'a' .. 'z')
         then
            Add_Switch (Argv, Compiler, And_Save => And_Save);

         --  All other options are handled by Scan_Make_Switches

         else
            Scan_Make_Switches (Argv);
         end if;

      --  If not a switch it must be a file name

      else
         Add_File (Argv);
         Mains.Add_Main (Argv);
      end if;
   end Scan_Make_Arg;

   -----------------
   -- Switches_Of --
   -----------------

   function Switches_Of
     (Source_File      : Name_Id;
      Source_File_Name : String;
      Source_Index     : Int;
      Naming           : Naming_Data;
      In_Package       : Package_Id;
      Allow_ALI        : Boolean) return Variable_Value
   is
      Switches : Variable_Value;

      Defaults : constant Array_Element_Id :=
                   Prj.Util.Value_Of
                     (Name      => Name_Default_Switches,
                      In_Arrays =>
                      Packages.Table (In_Package).Decl.Arrays);

      Switches_Array : constant Array_Element_Id :=
                         Prj.Util.Value_Of
                           (Name      => Name_Switches,
                            In_Arrays =>
                              Packages.Table (In_Package).Decl.Arrays);

   begin
      Switches :=
        Prj.Util.Value_Of
          (Index     => Source_File,
           Src_Index => Source_Index,
           In_Array  => Switches_Array);

      if Switches = Nil_Variable_Value then
         declare
            Name        : String (1 .. Source_File_Name'Length + 3);
            Last        : Positive := Source_File_Name'Length;
            Spec_Suffix : constant String :=
                            Get_Name_String (Naming.Ada_Spec_Suffix);
            Body_Suffix : constant String :=
                            Get_Name_String (Naming.Ada_Body_Suffix);
            Truncated   : Boolean := False;

         begin
            Name (1 .. Last) := Source_File_Name;

            if Last > Body_Suffix'Length
               and then Name (Last - Body_Suffix'Length + 1 .. Last) =
                                                                  Body_Suffix
            then
               Truncated := True;
               Last := Last - Body_Suffix'Length;
            end if;

            if not Truncated
              and then Last > Spec_Suffix'Length
              and then Name (Last - Spec_Suffix'Length + 1 .. Last) =
                                                                 Spec_Suffix
            then
               Truncated := True;
               Last := Last - Spec_Suffix'Length;
            end if;

            if Truncated then
               Name_Len := Last;
               Name_Buffer (1 .. Name_Len) := Name (1 .. Last);
               Switches :=
                 Prj.Util.Value_Of
                   (Index     => Name_Find,
                    Src_Index => 0,
                    In_Array  => Switches_Array);

               if Switches = Nil_Variable_Value
                 and then Allow_ALI
               then
                  Last := Source_File_Name'Length;

                  while Name (Last) /= '.' loop
                     Last := Last - 1;
                  end loop;

                  Name (Last + 1 .. Last + 3) := "ali";
                  Name_Len := Last + 3;
                  Name_Buffer (1 .. Name_Len) := Name (1 .. Name_Len);
                  Switches :=
                    Prj.Util.Value_Of
                      (Index     => Name_Find,
                       Src_Index => 0,
                       In_Array  => Switches_Array);
               end if;
            end if;
         end;
      end if;

      if Switches = Nil_Variable_Value then
         Switches :=
           Prj.Util.Value_Of
             (Index     => Name_Ada,
              Src_Index => 0,
              In_Array  => Defaults);
      end if;

      return Switches;
   end Switches_Of;

   -----------
   -- Usage --
   -----------

   procedure Usage is
   begin
      if Usage_Needed then
         Usage_Needed := False;
         Makeusg;
      end if;
   end Usage;

   -----------------
   -- Verbose_Msg --
   -----------------

   procedure Verbose_Msg
     (N1     : Name_Id;
      S1     : String;
      N2     : Name_Id := No_Name;
      S2     : String  := "";
      Prefix : String := "  -> ")
   is
   begin
      if not Verbose_Mode then
         return;
      end if;

      Write_Str (Prefix);
      Write_Str ("""");
      Write_Name (N1);
      Write_Str (""" ");
      Write_Str (S1);

      if N2 /= No_Name then
         Write_Str (" """);
         Write_Name (N2);
         Write_Str (""" ");
      end if;

      Write_Str (S2);
      Write_Eol;
   end Verbose_Msg;

begin
   --  Make sure that in case of failure, the temp files will be deleted

   Prj.Com.Fail    := Make_Failed'Access;
   MLib.Fail       := Make_Failed'Access;
   Makeutl.Do_Fail := Make_Failed'Access;
end Make;
