From 3b81743f8901ad7bf8055d461c3cb6d1e7e13e8a Mon Sep 17 00:00:00 2001 From: Nicolas Setton Date: Wed, 22 Apr 2009 10:33:15 +0000 Subject: [PATCH] link.c: Add flag __gnat_separate_run_path_options. 2009-04-22 Nicolas Setton * 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 | 16 +++++ gcc/ada/gnatcmd.adb | 104 ++++++++++++++++++----------- gcc/ada/gnatlink.adb | 153 +++++++++++++++++++++++++------------------ gcc/ada/link.c | 15 +++++ gcc/ada/make.adb | 109 +++++++++++++++++++----------- gcc/ada/mlib.adb | 15 ++++- gcc/ada/mlib.ads | 6 +- 7 files changed, 277 insertions(+), 141 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 37133323623..a70a712677a 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,19 @@ +2009-04-22 Nicolas Setton + + * 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 * exp_ch6.adb (Make_Build_In_Place_Call_In_Assignment): Code cleanup. diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb index a412551859e..66c71486788 100644 --- a/gcc/ada/gnatcmd.adb +++ b/gcc/ada/gnatcmd.adb @@ -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); + + 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 + 1; + Option (Current) := Path_Separator; + end loop; + + -- Finally put the standard GNAT library dir - 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; + Current + MLib.Utl.Lib_Directory'Length) := + MLib.Utl.Lib_Directory; - -- Finally put the standard GNAT library dir + -- And add the switch to the last switches - Option - (Current + 1 .. - Current + MLib.Utl.Lib_Directory'Length) := - MLib.Utl.Lib_Directory; - - -- 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; diff --git a/gcc/ada/gnatlink.adb b/gcc/ada/gnatlink.adb index 72d9068d15b..eb255d9fc08 100644 --- a/gcc/ada/gnatlink.adb +++ b/gcc/ada/gnatlink.adb @@ -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)); + 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. - 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)); + 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.Increment_Last; end if; - else - if Run_Path_Opt_Index = 0 then - Linker_Options.Table - (Linker_Options.Last) := - new String'(Run_Path_Opt - & File_Path + 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) - & Path_Separator - & File_Path (1 .. GCC_Index)); + - 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)); + 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; diff --git a/gcc/ada/link.c b/gcc/ada/link.c index 5dd2c80d901..c36d8e78a42 100644 --- a/gcc/ada/link.c +++ b/gcc/ada/link.c @@ -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 diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb index 49896cb05b3..559baeb0d46 100644 --- a/gcc/ada/make.adb +++ b/gcc/ada/make.adb @@ -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. + if MLib.Separate_Run_Path_Options then - Length := - Length + - Library_Paths.Table (Index)'Length + 1; - end loop; + -- We are going to create one switch of the form + -- "-Wl,-rpath,dir_N" for each directory to + -- consider. - -- Finally, add the length of the standard GNAT - -- library dir. + -- One switch for each library directory - Length := Length + MLib.Utl.Lib_Directory'Length; - Option := new String (1 .. Length); - Option (1 .. Path_Option'Length) := Path_Option.all; - Current := Path_Option'Length; + 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; - -- Put each library dir followed by a dir separator + -- One switch for the standard GNAT library dir. + + Linker_Switches.Increment_Last; + Linker_Switches.Table + (Linker_Switches.Last) := new String' + (Path_Option.all & MLib.Utl.Lib_Directory); + + 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; + + -- 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 - 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; + Current + MLib.Utl.Lib_Directory'Length) := + MLib.Utl.Lib_Directory; - -- Finally put the standard GNAT library dir + -- And add the switch to the linker switches - 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; + Linker_Switches.Increment_Last; + Linker_Switches.Table (Linker_Switches.Last) := + Option; + end if; end; end if; diff --git a/gcc/ada/mlib.adb b/gcc/ada/mlib.adb index 5a8a66128b2..22d24ab243d 100644 --- a/gcc/ada/mlib.adb +++ b/gcc/ada/mlib.adb @@ -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 diff --git a/gcc/ada/mlib.ads b/gcc/ada/mlib.ads index 684e6e70c37..0aa62d21574 100644 --- a/gcc/ada/mlib.ads +++ b/gcc/ada/mlib.ads @@ -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;