link.c: Add flag __gnat_separate_run_path_options.
authorNicolas Setton <setton@adacore.com>
Wed, 22 Apr 2009 10:33:15 +0000 (10:33 +0000)
committerArnaud Charlet <charlet@gcc.gnu.org>
Wed, 22 Apr 2009 10:33:15 +0000 (12:33 +0200)
2009-04-22  Nicolas Setton  <setton@adacore.com>

* link.c: Add flag __gnat_separate_run_path_options.

* mlib.adb (Separate_Run_Path_Options): New subprogram.

* mlib.ads (Separate_Run_Path_Options): Declare.

* gnatcmd.adb (Process_Link): Add support for emitting one "rpath"
switch per directory, rather than one "rpath" switch listing all
directories.

* gnatlink.adb (Process_Binder_File): Likewise.

* make.adb (Gnatmake): Likewise.

From-SVN: r146561

gcc/ada/ChangeLog
gcc/ada/gnatcmd.adb
gcc/ada/gnatlink.adb
gcc/ada/link.c
gcc/ada/make.adb
gcc/ada/mlib.adb
gcc/ada/mlib.ads

index 37133323623a251026285c10a8d7584c12782830..a70a712677a3f7f445e837dc9a12cbd9f250ec55 100644 (file)
@@ -1,3 +1,19 @@
+2009-04-22  Nicolas Setton  <setton@adacore.com>
+
+       * link.c: Add flag __gnat_separate_run_path_options.
+
+       * mlib.adb (Separate_Run_Path_Options): New subprogram.
+
+       * mlib.ads (Separate_Run_Path_Options): Declare.
+
+       * gnatcmd.adb (Process_Link): Add support for emitting one "rpath"
+       switch per directory, rather than one "rpath" switch listing all
+       directories.
+
+       * gnatlink.adb (Process_Binder_File): Likewise.
+
+       * make.adb (Gnatmake): Likewise.
+
 2009-04-22  Hristian Kirtchev  <kirtchev@adacore.com>
 
        * exp_ch6.adb (Make_Build_In_Place_Call_In_Assignment): Code cleanup.
index a412551859eaa2f5b878f1f41da817f127fc289e..66c71486788ccfa5ce7dba12287cdf360158e808 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1996-2008, Free Software Foundation, Inc.         --
+--          Copyright (C) 1996-2009, 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- --
@@ -976,54 +976,80 @@ procedure GNATCmd is
                Current : Natural;
 
             begin
-               --  First, compute the exact length for the switch
+               if MLib.Separate_Run_Path_Options then
 
-               for Index in
-                 Library_Paths.First .. Library_Paths.Last
-               loop
-                  --  Add the length of the library dir plus one for the
-                  --  directory separator.
+                  --  We are going to create one switch of the form
+                  --  "-Wl,-rpath,dir_N" for each directory to consider.
 
-                  Length :=
-                    Length +
-                      Library_Paths.Table (Index)'Length + 1;
-               end loop;
+                  --  One switch for each library directory
 
-               --  Finally, add the length of the standard GNAT library dir
+                  for Index in
+                    Library_Paths.First .. Library_Paths.Last
+                  loop
+                     Last_Switches.Increment_Last;
+                     Last_Switches.Table
+                       (Last_Switches.Last) := new String'
+                       (Path_Option.all &
+                        Last_Switches.Table (Index).all);
+                  end loop;
 
-               Length := Length + MLib.Utl.Lib_Directory'Length;
-               Option := new String (1 .. Length);
-               Option (1 .. Path_Option'Length) := Path_Option.all;
-               Current := Path_Option'Length;
+                  --  One switch for the standard GNAT library dir.
 
-               --  Put each library dir followed by a dir separator
+                  Last_Switches.Increment_Last;
+                  Last_Switches.Table
+                    (Last_Switches.Last) := new String'
+                    (Path_Option.all & MLib.Utl.Lib_Directory);
 
-               for Index in
-                 Library_Paths.First .. Library_Paths.Last
-               loop
-                  Option
-                    (Current + 1 ..
+               else
+                  --  First, compute the exact length for the switch
+
+                  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) :=
-                      Library_Paths.Table (Index).all;
-                  Current :=
-                    Current +
-                      Library_Paths.Table (Index)'Length + 1;
-                  Option (Current) := Path_Separator;
-               end loop;
+                         Library_Paths.Table (Index)'Length + 1;
+                     Option (Current) := Path_Separator;
+                  end loop;
 
-               --  Finally put the standard GNAT library dir
+                  --  Finally put the standard GNAT library dir
 
-               Option
-                 (Current + 1 ..
-                    Current + MLib.Utl.Lib_Directory'Length) :=
-                   MLib.Utl.Lib_Directory;
+                  Option
+                    (Current + 1 ..
+                       Current + MLib.Utl.Lib_Directory'Length) :=
+                      MLib.Utl.Lib_Directory;
 
-               --  And add the switch to the last switches
+                  --  And add the switch to the last switches
 
-               Last_Switches.Increment_Last;
-               Last_Switches.Table (Last_Switches.Last) :=
-                 Option;
+                  Last_Switches.Increment_Last;
+                  Last_Switches.Table (Last_Switches.Last) :=
+                    Option;
+               end if;
             end;
          end if;
       end if;
index 72d9068d15b02d72cc171df6acde8d853c61a37d..eb255d9fc08fa104e616aa1427350bfd92678746 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1996-2008, Free Software Foundation, Inc.         --
+--          Copyright (C) 1996-2009, 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- --
@@ -761,6 +761,12 @@ procedure Gnatlink is
       --  Predicate indicating whether this target uses the GNU linker. In
       --  this case we must output a GNU linker compatible response file.
 
+      Separate_Run_Path_Options : Boolean;
+      for Separate_Run_Path_Options'Size use Character'Size;
+      pragma Import
+        (C, Separate_Run_Path_Options, "__gnat_separate_run_path_options");
+      --  Whether separate rpath options should be emitted for each directory
+
       Opening : aliased constant String := """";
       Closing : aliased constant String := '"' & ASCII.LF;
       --  Needed to quote object paths in object list files when GNU linker
@@ -1255,78 +1261,101 @@ procedure Gnatlink is
                                  --  Look for an eventual run_path_option in
                                  --  the linker switches.
 
-                                 for J in reverse 1 .. Linker_Options.Last loop
-                                    if Linker_Options.Table (J) /= null
-                                      and then
-                                        Linker_Options.Table (J)'Length
-                                                  > Run_Path_Opt'Length
-                                      and then
-                                        Linker_Options.Table (J)
-                                          (1 .. Run_Path_Opt'Length) =
-                                                                Run_Path_Opt
-                                    then
-                                       --  We have found a already specified
-                                       --  run_path_option: we will add to this
-                                       --  switch, because only one
-                                       --  run_path_option should be specified.
-
-                                       Run_Path_Opt_Index := J;
-                                       exit;
-                                    end if;
-                                 end loop;
-
-                                 --  If there is no run_path_option, we need
-                                 --  to add one.
-
-                                 if Run_Path_Opt_Index = 0 then
+                                 if Separate_Run_Path_Options then
                                     Linker_Options.Increment_Last;
-                                 end if;
+                                    Linker_Options.Table
+                                      (Linker_Options.Last) :=
+                                      new String'
+                                        (Run_Path_Opt
+                                         & File_Path
+                                           (1 .. File_Path'Length
+                                            - File_Name'Length));
 
-                                 if GCC_Index = 0 then
-                                    if Run_Path_Opt_Index = 0 then
+                                    if GCC_Index /= 0 then
+                                       Linker_Options.Increment_Last;
                                        Linker_Options.Table
                                          (Linker_Options.Last) :=
-                                           new String'
-                                              (Run_Path_Opt
-                                                & File_Path
-                                                  (1 .. File_Path'Length
-                                                         - File_Name'Length));
-
-                                    else
-                                       Linker_Options.Table
-                                         (Run_Path_Opt_Index) :=
-                                           new String'
-                                             (Linker_Options.Table
-                                                 (Run_Path_Opt_Index).all
-                                              & Path_Separator
-                                              & File_Path
-                                                 (1 .. File_Path'Length
-                                                       - File_Name'Length));
+                                         new String'
+                                           (Run_Path_Opt
+                                            & File_Path (1 .. GCC_Index));
                                     end if;
-
                                  else
+                                    for J in reverse
+                                      1 .. Linker_Options.Last
+                                    loop
+                                       if Linker_Options.Table (J) /= null
+                                         and then
+                                           Linker_Options.Table (J)'Length
+                                           > Run_Path_Opt'Length
+                                         and then
+                                           Linker_Options.Table (J)
+                                           (1 .. Run_Path_Opt'Length) =
+                                           Run_Path_Opt
+                                       then
+                                          --  We have found a already specified
+                                          --  run_path_option: we will add to
+                                          --  this switch, because only one
+                                          --  run_path_option should be
+                                          --  specified.
+
+                                          Run_Path_Opt_Index := J;
+                                          exit;
+                                       end if;
+                                    end loop;
+
+                                    --  If there is no run_path_option, we need
+                                    --  to add one.
+
                                     if Run_Path_Opt_Index = 0 then
-                                       Linker_Options.Table
-                                         (Linker_Options.Last) :=
-                                           new String'(Run_Path_Opt
-                                             & File_Path
+                                       Linker_Options.Increment_Last;
+                                    end if;
+
+                                    if GCC_Index = 0 then
+                                       if Run_Path_Opt_Index = 0 then
+                                          Linker_Options.Table
+                                            (Linker_Options.Last) :=
+                                            new String'
+                                              (Run_Path_Opt
+                                               & File_Path
+                                                 (1 .. File_Path'Length
+                                                  - File_Name'Length));
+
+                                       else
+                                          Linker_Options.Table
+                                            (Run_Path_Opt_Index) :=
+                                            new String'
+                                              (Linker_Options.Table
+                                                   (Run_Path_Opt_Index).all
+                                               & Path_Separator
+                                               & File_Path
                                                  (1 .. File_Path'Length
-                                                       - File_Name'Length)
-                                             & Path_Separator
-                                             & File_Path (1 .. GCC_Index));
+                                                  - File_Name'Length));
+                                       end if;
 
                                     else
-                                       Linker_Options.Table
-                                         (Run_Path_Opt_Index) :=
-                                           new String'
-                                            (Linker_Options.Table
-                                                (Run_Path_Opt_Index).all
-                                             & Path_Separator
-                                             & File_Path
+                                       if Run_Path_Opt_Index = 0 then
+                                          Linker_Options.Table
+                                            (Linker_Options.Last) :=
+                                            new String'(Run_Path_Opt
+                                              & File_Path
+                                                (1 .. File_Path'Length
+                                                 - File_Name'Length)
+                                              & Path_Separator
+                                              & File_Path (1 .. GCC_Index));
+
+                                       else
+                                          Linker_Options.Table
+                                            (Run_Path_Opt_Index) :=
+                                            new String'
+                                              (Linker_Options.Table
+                                                   (Run_Path_Opt_Index).all
+                                               & Path_Separator
+                                               & File_Path
                                                  (1 .. File_Path'Length
-                                                       - File_Name'Length)
-                                             & Path_Separator
-                                             & File_Path (1 .. GCC_Index));
+                                                  - File_Name'Length)
+                                               & Path_Separator
+                                               & File_Path (1 .. GCC_Index));
+                                       end if;
                                     end if;
                                  end if;
                               end if;
index 5dd2c80d9010dedc87591c833fec66a8e59b44a2..c36d8e78a42d375c52f46c776299069fc2d3868b 100644 (file)
@@ -65,6 +65,9 @@
 /*  using_gnu_linker is set to 1 when the GNU linker is used under this     */
 /*  target.                                                                 */
 
+/*  separate_run_path_options is set to 1 when separate "rpath" arguments   */
+/*  must be passed to the linker for each directory in the rpath.           */
+
 /*  RESPONSE FILE & GNU LINKER                                              */
 /*  --------------------------                                              */
 /*  objlist_file_supported and using_gnu_link used together tell gnatlink   */
@@ -88,6 +91,7 @@ unsigned char __gnat_objlist_file_supported = 1;
 char __gnat_shared_libgnat_default = STATIC;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (sgi)
 const char *__gnat_object_file_option = "-Wl,-objectlist,";
@@ -97,6 +101,7 @@ unsigned char __gnat_objlist_file_supported = 1;
 char __gnat_shared_libgnat_default = STATIC;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (__WIN32)
 const char *__gnat_object_file_option = "";
@@ -106,6 +111,7 @@ unsigned char __gnat_objlist_file_supported = 1;
 char __gnat_shared_libgnat_default = STATIC;
 unsigned char __gnat_using_gnu_linker = 1;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (__hpux__)
 const char *__gnat_object_file_option = "-Wl,-c,";
@@ -115,6 +121,7 @@ unsigned char __gnat_objlist_file_supported = 1;
 char __gnat_shared_libgnat_default = STATIC;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (_AIX)
 const char *__gnat_object_file_option = "-Wl,-f,";
@@ -124,6 +131,7 @@ const unsigned char __gnat_objlist_file_supported = 1;
 char __gnat_shared_libgnat_default = STATIC;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (VMS)
 const char *__gnat_object_file_option = "";
@@ -133,6 +141,7 @@ int __gnat_link_max = 2147483647;
 unsigned char __gnat_objlist_file_supported = 0;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".olb";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (sun)
 const char *__gnat_object_file_option = "";
@@ -142,6 +151,7 @@ int __gnat_link_max = 2147483647;
 unsigned char __gnat_objlist_file_supported = 0;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (__FreeBSD__)
 const char *__gnat_object_file_option = "";
@@ -151,6 +161,7 @@ int __gnat_link_max = 8192;
 unsigned char __gnat_objlist_file_supported = 1;
 unsigned char __gnat_using_gnu_linker = 1;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (__APPLE__)
 const char *__gnat_object_file_option = "-Wl,-filelist,";
@@ -160,6 +171,7 @@ int __gnat_link_max = 262144;
 unsigned char __gnat_objlist_file_supported = 1;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 1;
 
 #elif defined (linux) || defined(__GLIBC__)
 const char *__gnat_object_file_option = "";
@@ -169,6 +181,7 @@ int __gnat_link_max = 8192;
 unsigned char __gnat_objlist_file_supported = 1;
 unsigned char __gnat_using_gnu_linker = 1;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #elif defined (__svr4__) && defined (i386)
 const char *__gnat_object_file_option = "";
@@ -178,6 +191,7 @@ int __gnat_link_max = 2147483647;
 unsigned char __gnat_objlist_file_supported = 0;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 
 #else
 
@@ -190,4 +204,5 @@ int __gnat_link_max = 2147483647;
 unsigned char __gnat_objlist_file_supported = 0;
 unsigned char __gnat_using_gnu_linker = 0;
 const char *__gnat_object_library_extension = ".a";
+unsigned char __gnat_separate_run_path_options = 0;
 #endif
index 49896cb05b357c78456a0993ef67af5584ab4f8c..559baeb0d46be3bcf716db5dd5402df2b8ab5856 100644 (file)
@@ -36,6 +36,7 @@ with Gnatvsn;  use Gnatvsn;
 with Hostparm; use Hostparm;
 with Makeusg;
 with Makeutl;  use Makeutl;
+with MLib;
 with MLib.Prj;
 with MLib.Tgt; use MLib.Tgt;
 with MLib.Utl;
@@ -6361,53 +6362,85 @@ package body Make is
                            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;
+                           if MLib.Separate_Run_Path_Options then
+
+                              --  We are going to create one switch of the form
+                              --  "-Wl,-rpath,dir_N" for each directory to
+                              --  consider.
+
+                              --  One switch for each library directory
+
+                              for Index in
+                                Library_Paths.First .. Library_Paths.Last
+                              loop
+                                 Linker_Switches.Increment_Last;
+                                 Linker_Switches.Table
+                                   (Linker_Switches.Last) := new String'
+                                   (Path_Option.all &
+                                    Library_Paths.Table (Index).all);
+                              end loop;
 
-                           --  Finally, add the length of the standard GNAT
-                           --  library dir.
+                              --  One switch for 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;
+                              Linker_Switches.Increment_Last;
+                              Linker_Switches.Table
+                                (Linker_Switches.Last) := new String'
+                                (Path_Option.all & MLib.Utl.Lib_Directory);
 
-                           --  Put each library dir followed by a dir separator
+                           else
+                              --  We are going to create one switch of the form
+                              --  "-Wl,-rpath,dir_1:dir_2:dir_3"
+
+                              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;
 
-                           for Index in
-                             Library_Paths.First .. Library_Paths.Last
-                           loop
-                              Option
-                                (Current + 1 ..
+                              --  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) :=
-                                Library_Paths.Table (Index).all;
-                              Current :=
-                                Current +
-                                Library_Paths.Table (Index)'Length + 1;
-                              Option (Current) := Path_Separator;
-                           end loop;
+                                     Library_Paths.Table (Index)'Length + 1;
+                                 Option (Current) := Path_Separator;
+                              end loop;
 
-                           --  Finally put the standard GNAT library dir
+                              --  Finally put the standard GNAT library dir
 
-                           Option
-                             (Current + 1 ..
-                                Current + MLib.Utl.Lib_Directory'Length) :=
-                             MLib.Utl.Lib_Directory;
+                              Option
+                                (Current + 1 ..
+                                   Current + MLib.Utl.Lib_Directory'Length) :=
+                                  MLib.Utl.Lib_Directory;
 
-                           --  And add the switch to the linker switches
+                              --  And add the switch to the linker switches
 
-                           Linker_Switches.Increment_Last;
-                           Linker_Switches.Table (Linker_Switches.Last) :=
-                             Option;
+                              Linker_Switches.Increment_Last;
+                              Linker_Switches.Table (Linker_Switches.Last) :=
+                                Option;
+                           end if;
                         end;
                      end if;
 
index 5a8a66128b21937ce0d7d2119f41ec676007d9ac..22d24ab243d4b7be621ab15e0af2109bac62b084 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                     Copyright (C) 1999-2008, AdaCore                     --
+--                     Copyright (C) 1999-2009, AdaCore                     --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -442,6 +442,19 @@ package body MLib is
       end if;
    end Major_Id_Name;
 
+   -------------------------------
+   -- Separate_Run_Path_Options --
+   -------------------------------
+
+   function Separate_Run_Path_Options return Boolean is
+      Separate_Paths : Boolean;
+      for Separate_Paths'Size use Character'Size;
+      pragma Import (C, Separate_Paths, "__gnat_separate_run_path_options");
+
+   begin
+      return Separate_Paths;
+   end Separate_Run_Path_Options;
+
 --  Package elaboration
 
 begin
index 684e6e70c37a85f06e3f7e086684f3cff2b83284..0aa62d21574f090e7c560c8c8f3fc985b16131f9 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---                     Copyright (C) 1999-2008, AdaCore                     --
+--                     Copyright (C) 1999-2009, AdaCore                     --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -84,6 +84,10 @@ package MLib is
    --  For example, if Lib_Filename is "libtoto.so" and Lib_Version is
    --  "libtoto.so.1.2", then "libtoto.so.1" is returned.
 
+   function Separate_Run_Path_Options return Boolean;
+   --  Return True if separate rpath arguments must be passed to the linker
+   --  for each directory in the rpath.
+
 private
 
    Preserve : Attribute := Time_Stamps;