------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                                 M A K E                                  --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2004 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 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 Gnatvsn;
with Output;   use Output;
with Prj;      use Prj;
with Prj.Com;
with Prj.Env;
with Prj.Ext;
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);
   --  Inserts Source_File at the end of Q. Provide Source_Unit when
   --  possible for external use (gnatdist).

   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);
   --  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;
   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.

   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.


   --  Package Mains is used to store the mains specified on the command line
   --  and to retrieve them when a project file is used, to verify that the
   --  files exist and that they belong to a project file.

   package Mains is

      --  Mains are stored in a table. An index is used to retrieve the mains
      --  from the table.

      procedure Add_Main (Name : String);
      --  Add one main to the table

      procedure Delete;
      --  Empty the table

      procedure Reset;
      --  Reset the index to the beginning of the table

      function Next_Main return String;
      --  Increase the index and return the next main.
      --  If table is exhausted, return an empty string.

   end Mains;

   --  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");

   type Linker_Options_Data is record
      Project : Project_Id;
      Options : String_List_Id;
   end record;

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

   --  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";

   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.

   Bind_Shared_Known : Boolean := False;
   --  Set to True after the first time Bind_Shared is computed

   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; --  Arbitrary

   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.

   ----------------------
   -- Marking Routines --
   ----------------------

   Marking_Label : Byte := 1;
   --  Value to mark the source files

   procedure Mark (Source_File : File_Name_Type);
   --  Mark Source_File. Marking is used to signal that Source_File has
   --  already been inserted in the Q.

   function Is_Marked (Source_File : File_Name_Type) return Boolean;
   --  Returns True if Source_File was previously marked.

   -------------------
   -- 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 then 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.

   type Project_Array is array (Positive range <>) of Project_Id;
   No_Projects : constant Project_Array := (1 .. 0 => No_Project);

   procedure Recursive_Compute_Depth
     (Project : Project_Id;
      Visited : Project_Array;
      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 Is_External_Assignment (Argv : String) return Boolean;
   --  Verify that an external assignment switch is syntactically correct.
   --  Correct forms are
   --      -Xname=value
   --      -X"name=other value"
   --  Assumptions: 'First = 1, Argv (1 .. 2) = "-X"
   --  When this function returns True, the external assignment has
   --  been entered by a call to Prj.Ext.Add, so that in a project
   --  file, External ("name") will return "value".

   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;
      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.

   procedure Test_If_Relative_Path
     (Switch             : in out String_Access;
      Parent             : String_Access;
      Including_L_Switch : Boolean := True);
   --  Test if Switch is a relative search path switch.
   --  If it is, fail if Parent is null, otherwise prepend the path with
   --  Parent. This subprogram is only called when using project files.
   --  For gnatbind switches, Including_L_Switch is False, because the
   --  argument of the -L switch is not a path.

   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 a global variable.

   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;
      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;
      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;
      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 : 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 Opt.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 Opt.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;
      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,
            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 Opt.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 Opt.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;
      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 :=
                                               Opt.Check_Object_Consistency;
         begin
            Opt.Check_Object_Consistency := False;
            Text := Read_Library_Info (Lib_File);
            Opt.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 Opt.Operating_Mode /= Opt.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 Opt.Check_Switches then

            --  First, collect all the switches

            Collect_Arguments (Source_File, 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 Opt.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 Opt.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 Opt.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 Opt.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;
      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,
            --  we simply add the saved gcc switches.

            if Arguments_Project = No_Project then

               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,
                     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;
      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
      function Compile
        (S    : Name_Id;
         L    : Name_Id;
         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.

      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

      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;

      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.

      procedure Collect_Arguments_And_Compile (Source_File : File_Name_Type);
      --  Collect arguments from project file (if any) and 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.

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

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

      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.

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

      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.

      -----------------
      -- 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;

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

      procedure Collect_Arguments_And_Compile (Source_File : File_Name_Type) is
      begin

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

         if not Arguments_Collected then
            Collect_Arguments (Source_File, 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
            Prj.Env.Set_Ada_Paths (Arguments_Project, True);

            if 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.Flag1 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).Flag1 := 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,
                            Arguments (1 .. Last_Argument));

         else
            --  If this is a source outside of any project file, make sure
            --  it will be compiled in the 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,
                            Arguments (1 .. Last_Argument));
         end if;
      end Collect_Arguments_And_Compile;

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

      function Compile
        (S    : Name_Id;
         L    : Name_Id;
         Args : Argument_List) return Process_Id
      is
         Comp_Args : Argument_List (Args'First .. Args'Last + 8);
         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 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));

         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 Opt.Check_Source_Files to True to ensure that source file
      --  time stamps are checked, and we set Opt.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).

      Opt.Check_Source_Files := True;
      Opt.All_Sources        := False;

      Insert_Q (Main_Source);
      Mark (Main_Source);

      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
            Extract_From_Q (Source_File, Source_Unit);
            Full_Source_File := Osint.Full_Source_Name (Source_File);
            Lib_File         := Osint.Lib_File_Name (Source_File);
            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, 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
                        Get_Name_String (Full_Source_File);

                        for J in reverse 1 .. Name_Len loop
                           if Name_Buffer (J) = '.' then
                              Name_Buffer (J + 1 .. J + 3) := "ali";
                              Name_Len := J + 3;
                              exit;
                           end if;
                        end loop;

                        Lib_File := Name_Find;

                     --  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);

                  --  Make sure we could successfully start the compilation

                  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;

         --  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 :=
                                               Opt.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.

                  Opt.Check_Object_Consistency :=
                    Opt.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

                  Opt.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 Opt.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;

            --  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 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
               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 Opt.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);
                           Mark (Sfile);
                        end if;
                     end if;
                  end;
               end if;
            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);

                     elsif Is_Marked (Sfile) 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);
                        Mark (Sfile);
                     end if;
                  end loop;
               end loop;
            end if;
         end loop;

         if Opt.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 Opt.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

            --  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 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)
   is
      File : constant File_Name_Type := Q.Table (Q_Front).File;
      Unit : constant Unit_Name_Type := Q.Table (Q_Front).Unit;

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

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

   -----------------
   -- 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;

   --------------
   -- 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.

   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;
      Bind_Shared_Known := False;

      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.

         Opt.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_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.

               Mains.Reset;

               declare
                  Real_Main_Project : Project_Id := No_Project;
                  --  The project of the first main

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

               begin
                  --  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
                              declare
                                 Data : constant Project_Data :=
                                          Projects.Table (Main_Project);

                                 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);
                                 Real_Path : String_Access :=
                                   Locate_Regular_File
                                     (Main &
                                      Get_Name_String
                                        (Data.Naming.Current_Body_Suffix),
                                      "");
                              begin
                                 if Real_Path = null then
                                    Real_Path :=
                                      Locate_Regular_File
                                        (Main &
                                         Get_Name_String
                                           (Data.Naming.Current_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
                                    Normed_Path : constant String :=
                                      Normalize_Pathname
                                        (Real_Path.all,
                                         Case_Sensitive => False);
                                 begin
                                    Free (Real_Path);

                                    --  Fail if it is not the correct path

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

                                       Make_Failed
                                         ("""" & Main &
                                          """ is not a source of any project");
                                    end if;
                                 end;
                              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;
            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
            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));
                        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 Opt.Verbose_Mode then
         Write_Eol;
         Write_Str ("GNATMAKE ");
         Write_Str (Gnatvsn.Gnat_Version_String);
         Write_Str (" Copyright 1995-2004 Free Software Foundation, Inc.");
         Write_Eol;
      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 Opt.List_Dependencies then
         Opt.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;

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

      if Main_Project = No_Project then
         if Opt.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.

         Opt.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 Opt.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
            Make_Failed ("no sources to compile");
         end if;

         --  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;

         --  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 Opt.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 Opt.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,
                     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,
                          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 Opt.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   => " ",
                           The_Package => Builder_Package,
                           Program     => None);

                     elsif (not Opt.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 Opt.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,
                  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 Opt.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,
                  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 Opt.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 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).Flag1 :=
                    not MLib.Tgt.Library_Exists_For (Proj);

                  if Projects.Table (Proj).Flag1 then
                     if Opt.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 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 := Opt.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;

      --  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

         --  Increase the marking label to be sure to check sources
         --  for all executables.

         Marking_Label := Marking_Label + 1;

         --  Make sure it is not 0, which is the default value for
         --  a file that has never been marked.

         if Marking_Label = 0 then
            Marking_Label := 1;
         end if;

         --  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;

               --  Put in canonical case to detect suffixs such as ".EXE" on
               --  Windows or VMS.

               Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));

               --  If target has an executable suffix and it has not been
               --  specified then it is added here.

               if Executable_Suffix'Length /= 0
                 and then Name_Buffer
                          (Name_Len - Executable_Suffix'Length + 1 .. Name_Len)
                             /= Executable_Suffix
               then
                  --  Get back the original name to keep the case on Windows

                  Name_Buffer (1 .. Name_Len) :=
                    Linker_Switches.Table (J + 1).all;

                  --  Add the executable suffix

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

               else
                  --  Get back the original name to keep the case on Windows

                  Name_Buffer (1 .. Name_Len) :=
                    Linker_Switches.Table (J + 1).all;
               end if;

               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);
            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,
                  Compilation_Failures  => Compilation_Failures,
                  Check_Readonly_Files  => Opt.Check_Readonly_Files,
                  Do_Not_Execute        => Opt.Do_Not_Execute,
                  Force_Compilations    => Opt.Force_Compilations,
                  In_Place_Mode         => Opt.In_Place_Mode,
                  Keep_Going            => Opt.Keep_Going,
                  Initialize_ALI_Data   => True,
                  Max_Process           => Saved_Maximum_Processes);

               if Opt.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 Opt.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).Library
                          and then not Projects.Table (Proj1).Flag1
                        then
                           MLib.Prj.Check_Library (Proj1);
                        end if;

                        if Projects.Table (Proj1).Flag1 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).Flag1 := 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 Opt.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 Opt.Quiet_Output
                 and then not Library_Rebuilt
                 and then Osint.Number_Of_Files = 1
               then
                  Inform (Msg => "objects up to date.");

               elsif Opt.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 (Opt.Do_Not_Execute
                   or Opt.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 Opt.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);
            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 Opt.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 + 1);
               --  The arguments for the invocation of gnatbind

               Last_Arg : Natural := Binder_Switches.Last;
               --  Index of the last argument in Args

               Mapping_FD : File_Descriptor := Invalid_FD;
               --  A File Descriptor for an eventual mapping file

               Mapping_Path : Name_Id := No_Name;
               --  The path name of the 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
               --  If it is the first time the bind step is performed,
               --  check if there are shared libraries, so that gnatbind is
               --  called with -shared.

               if not Bind_Shared_Known then
                  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
                           Bind_Shared := Shared_Switch'Access;

                           if GCC_Version >= 3 then
                              Link_With_Shared_Libgcc :=
                                Shared_Libgcc_Switch'Access;
                           end if;

                           exit;
                        end if;
                     end loop;
                  end if;

                  Bind_Shared_Known := True;
               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 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
                     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;

                                    if OK then

                                       --  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;
                                    end if;

                                    if OK then

                                       --  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;
                                    end if;

                                    --  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 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), OK);
                     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), OK);
               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.Tgt.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_Package : Package_Id;
                     Options : Variable_Value;

                  begin
                     Linker_Opts.Init;

                     for Index in 1 .. Projects.Last loop
                        if Index /= Main_Project then
                           Linker_Package :=
                             Prj.Util.Value_Of
                               (Name => Name_Linker,
                                In_Packages =>
                                  Projects.Table (Index).Decl.Packages);
                           Options :=
                             Prj.Util.Value_Of
                               (Name => Name_Ada,
                                Attribute_Or_Array_Name => Name_Linker_Options,
                                In_Package => Linker_Package);

                           --  If attribute is present, add the project with
                           --  the attribute to table Linker_Opts.

                           if Options /= Nil_Variable_Value then
                              Linker_Opts.Increment_Last;
                              Linker_Opts.Table (Linker_Opts.Last) :=
                                (Project => Index, Options => Options.Values);
                           end if;
                        end if;
                     end loop;
                  end;

                  declare
                     Opt1    : Linker_Options_Data;
                     Opt2    : Linker_Options_Data;
                     Depth   : Natural;
                     Options : String_List_Id;
                     Option  : Name_Id;
                  begin
                     --  Sort the project by increasing depths

                     for Index in 1 .. Linker_Opts.Last loop
                        Opt1 := Linker_Opts.Table (Index);
                        Depth := Projects.Table (Opt1.Project).Depth;

                        for J in Index + 1 .. Linker_Opts.Last loop
                           Opt2 := Linker_Opts.Table (J);

                           if
                             Projects.Table (Opt2.Project).Depth < Depth
                           then
                              Linker_Opts.Table (Index) := Opt2;
                              Linker_Opts.Table (J) := Opt1;
                              Opt1 := Opt2;
                              Depth :=
                                Projects.Table (Opt1.Project).Depth;
                           end if;
                        end loop;

                        --  If Dir_Path has not been computed for this project,
                        --  do it now.

                        if Projects.Table (Opt1.Project).Dir_Path = null then
                           Projects.Table (Opt1.Project).Dir_Path :=
                             new String'
                               (Get_Name_String
                                  (Projects.Table (Opt1.Project). Directory));
                        end if;

                        Options := Opt1.Options;

                        --  Add each of the options to the linker switches

                        while Options /= Nil_String loop
                           Option := String_Elements.Table (Options).Value;
                           Options := String_Elements.Table (Options).Next;
                           Linker_Switches.Increment_Last;
                           Linker_Switches.Table (Linker_Switches.Last) :=
                             new String'(Get_Name_String (Option));

                           --  Object files and -L switches specified with
                           --  relative paths and must be converted to
                           --  absolute paths.

                           Test_If_Relative_Path
                             (Switch =>
                                Linker_Switches.Table (Linker_Switches.Last),
                              Parent => Projects.Table (Opt1.Project).Dir_Path,
                              Including_L_Switch => True);
                        end loop;
                     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 Opt.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 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 Opt.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,
                        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 Opt.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,
                        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;
      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
      Next_Arg : Positive;

   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.

      Opt.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;

      Next_Arg := 1;
      Scan_Args : while Next_Arg <= Argument_Count loop
         Scan_Make_Arg (Argument (Next_Arg), And_Save => True);
         Next_Arg := Next_Arg + 1;
      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 Opt.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 Opt.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 Opt.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

         --  Opt.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 Opt.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

         Recursive_Compute_Depth
           (Main_Project, Visited => No_Projects, Depth => 0);

      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;

      --  Set the marking label to a value that is not zero

      Marking_Label := 1;
   end Initialize;

   -----------------------------------
   -- Insert_Project_Sources_Into_Q --
   -----------------------------------

   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 Opt.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 Opt.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)
   is
   begin
      if Debug.Debug_Flag_Q then
         Write_Str ("   Q := Q + [ ");
         Write_Name (Source_File);
         Write_Str (" ] ");
         Write_Eol;
      end if;

      Q.Table (Q.Last).File := Source_File;
      Q.Table (Q.Last).Unit := Source_Unit;
      Q.Increment_Last;
   end Insert_Q;

   ----------------------------
   -- Is_External_Assignment --
   ----------------------------

   function Is_External_Assignment (Argv : String) return Boolean is
      Start     : Positive := 3;
      Finish    : Natural := Argv'Last;
      Equal_Pos : Natural;

   begin
      if Argv'Last < 5 then
         return False;

      elsif Argv (3) = '"' then
         if Argv (Argv'Last) /= '"' or else Argv'Last < 7 then
            return False;
         else
            Start := 4;
            Finish := Argv'Last - 1;
         end if;
      end if;

      Equal_Pos := Start;

      while Equal_Pos <= Finish and then Argv (Equal_Pos) /= '=' loop
         Equal_Pos := Equal_Pos + 1;
      end loop;

      if Equal_Pos = Start
        or else Equal_Pos >= Finish
      then
         return False;

      else
         Prj.Ext.Add
           (External_Name => Argv (Start .. Equal_Pos - 1),
            Value         => Argv (Equal_Pos + 1 .. Finish));
         return True;
      end if;
   end Is_External_Assignment;

   ---------------------
   -- 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;

   ---------------
   -- Is_Marked --
   ---------------

   function Is_Marked (Source_File : File_Name_Type) return Boolean is
   begin
      return Get_Name_Table_Byte (Source_File) = Marking_Label;
   end Is_Marked;

   ----------
   -- 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 Opt.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 Opt.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;

   -----------
   -- Mains --
   -----------

   package body Mains is

      package Names 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.Mains.Names");
      --  The table that stores the main

      Current : Natural := 0;
      --  The index of the last main retrieved from the table

      --------------
      -- Add_Main --
      --------------

      procedure Add_Main (Name : String) is
      begin
         Name_Len := 0;
         Add_Str_To_Name_Buffer (Name);
         Names.Increment_Last;
         Names.Table (Names.Last) := Name_Find;
      end Add_Main;

      ------------
      -- Delete --
      ------------

      procedure Delete is
      begin
         Names.Set_Last (0);
         Reset;
      end Delete;

      ---------------
      -- Next_Main --
      ---------------

      function Next_Main return String is
      begin
         if Current >= Names.Last then
            return "";

         else
            Current := Current + 1;
            return Get_Name_String (Names.Table (Current));
         end if;
      end Next_Main;

      procedure Reset is
      begin
         Current := 0;
      end Reset;

   end Mains;

   ----------
   -- Mark --
   ----------

   procedure Mark (Source_File : File_Name_Type) is
   begin
      Set_Name_Table_Byte (Source_File, Marking_Label);
   end Mark;

   --------------------
   -- 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;
      Visited : Project_Array;
      Depth   : Natural)
   is
      List : Project_List;
      Proj : Project_Id;
      OK : Boolean;
      New_Visited : constant Project_Array := Visited & Project;

   begin
      --  Nothing to do if there is no project

      if Project = No_Project then
         return;
      end if;

      --  If current depth of project is lower than Depth, adjust it

      if Projects.Table (Project).Depth < Depth then
         Projects.Table (Project).Depth := Depth;
      end if;

      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;

         OK := True;

         --  To avoid endless loops due to cycles with limited widts,
         --  do not revisit a project that is already in the chain of imports
         --  that brought us here.

         for J in Visited'Range loop
            if Visited (J) = Proj then
               OK := False;
               exit;
            end if;
         end loop;

         if OK then
            Recursive_Compute_Depth
              (Project => Proj,
               Visited => New_Visited,
               Depth => Depth + 1);
         end if;
      end loop;

      --  Visit a project being extended, if any

      Recursive_Compute_Depth
        (Project => Projects.Table (Project).Extends,
         Visited => New_Visited,
         Depth => Depth + 1);
   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 Opt.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.

            if Executable_Suffix'Length /= 0
              and then (Argv'Length <= Executable_Suffix'Length
                        or else Argv (Argv'Last - Executable_Suffix'Length + 1
                                        .. 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 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 Opt.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
               Opt.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

               Opt.No_Stdinc := True;
               Opt.No_Stdlib := True;
               Opt.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
            Opt.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: give the switch to both the compiler and
         --  the linker (except for -gnatxxx which is only for the compiler)

         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)
         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
            Opt.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
            Opt.Minimal_Recompilation := True;

         --  -u

         elsif Argv (2) = 'u'
           and then Argv'Last = 2
         then
            Unique_Compile   := True;
            Opt.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;
            Opt.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);
            Opt.Operating_Mode := Opt.Check_Semantics;
            Opt.Check_Object_Consistency := False;
            Opt.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.

            Opt.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

            Opt.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', and 'M') are passed to the compiler,
            --  unless we are dealing with a debug switch (starts with 'd')

         elsif Argv (2) /= 'd'
           and then Argv (2 .. Argv'Last) /= "C"
           and then Argv (2 .. Argv'Last) /= "F"
           and then Argv (2 .. Argv'Last) /= "M"
           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;
      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,
         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.Current_Spec_Suffix);
            Body_Suffix : constant String :=
                            Get_Name_String (Naming.Current_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,
                  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,
                        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, In_Array => Defaults);
      end if;

      return Switches;
   end Switches_Of;

   ---------------------------
   -- Test_If_Relative_Path --
   ---------------------------

   procedure Test_If_Relative_Path
     (Switch             : in out String_Access;
      Parent             : String_Access;
      Including_L_Switch : Boolean := True)
   is
   begin
      if Switch /= null then

         declare
            Sw : String (1 .. Switch'Length);
            Start : Positive;

         begin
            Sw := Switch.all;

            if Sw (1) = '-' then
               if Sw'Length >= 3
                 and then (Sw (2) = 'A'
                           or else Sw (2) = 'I'
                           or else (Including_L_Switch and then Sw (2) = 'L'))
               then
                  Start := 3;

                  if Sw = "-I-" then
                     return;
                  end if;

               elsif Sw'Length >= 4
                 and then (Sw (2 .. 3) = "aL"
                           or else Sw (2 .. 3) = "aO"
                           or else Sw (2 .. 3) = "aI")
               then
                  Start := 4;

               else
                  return;
               end if;

               --  Because relative path arguments to --RTS= may be relative
               --  to the search directory prefix, those relative path
               --  arguments are not converted.

               if not Is_Absolute_Path (Sw (Start .. Sw'Last)) then
                  if Parent = null or else Parent'Length = 0 then
                     Make_Failed
                       ("relative search path switches (""",
                        Sw,
                        """) are not allowed");

                  else
                     Switch :=
                       new String'
                         (Sw (1 .. Start - 1) &
                          Parent.all &
                          Directory_Separator &
                          Sw (Start .. Sw'Last));
                  end if;
               end if;

            else
               if not Is_Absolute_Path (Sw) then
                  if Parent = null or else Parent'Length = 0 then
                     Make_Failed
                       ("relative paths (""", Sw, """) are not allowed");

                  else
                     Switch :=
                       new String'(Parent.all & Directory_Separator & Sw);
                  end if;
               end if;
            end if;
         end;
      end if;
   end Test_If_Relative_Path;

   -----------
   -- 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 Opt.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
   Prj.Com.Fail := Make_Failed'Access;
   MLib.Fail    := Make_Failed'Access;
   --  Make sure that in case of failure, the temp files will be deleted
end Make;
