AdaCore / gprbuild

GPRbuild is an advanced build system designed to help automate the construction of multi-language systems.
Other
65 stars 21 forks source link

Extra space in -rpath option #141

Closed simonjwright closed 3 months ago

simonjwright commented 1 year ago

This is on macOS, and I know you don't support it, but I'm hoping you'll be able to point me in the right direction.

When building a shared library, gprbuild v23.0.0 issues

/opt/gcc-12.2.0/bin/gcc
 -dynamiclib
 -shared-libgcc
 -o /Users/simon/tmp/so/a-26821216/ada/lib/libtest.dylib
 -L/opt/gcc-12.2.0/lib/gcc/x86_64-apple-darwin15/12.2.0//adalib
 -Wl,-install_name,@rpath/libtest.dylib
 -Wl,-rpath, /opt/gcc-12.2.0/lib/gcc/x86_64-apple-darwin15/12.2.0/adalib
 -Wl,-rpath, /opt/gcc-12.2.0/lib
 /Users/simon/tmp/so/a-26821216/ada/.build/hello.o
 /Users/simon/tmp/so/a-26821216/ada/.build/number.o
 b__test.o
 -lgnat-12
 -Wl,-v
 -Wl,-exported_symbols_list,/private/var/folders/ch/k_zwspdx3qsfbt1_x21zld6m0000gn/T/GNAT-TEMP-000013.TMP.def

which results in

/usr/bin/ld
 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/
 -dynamic
 -arch x86_64
 -macosx_version_min 13.0.0
 -o /Users/simon/tmp/so/a-26821216/ada/lib/libtest.dylib
 -L/opt/gcc-12.2.0/lib/gcc/x86_64-apple-darwin15/12.2.0//adalib
 -L/opt/gcc-12.2.0/lib/gcc/x86_64-apple-darwin15/12.2.0
 -L/opt/gcc-12.2.0/lib/gcc/x86_64-apple-darwin15/12.2.0/../../..
 -install_name @rpath/libtest.dylib
 -rpath  /opt/gcc-12.2.0/lib/gcc/x86_64-apple-darwin15/12.2.0/adalib
 -rpath  /opt/gcc-12.2.0/lib
 /Users/simon/tmp/so/a-26821216/ada/.build/hello.o
 /Users/simon/tmp/so/a-26821216/ada/.build/number.o
 b__test.o
 -lgnat-12
 -v
 -exported_symbols_list /private/var/folders/ch/k_zwspdx3qsfbt1_x21zld6m0000gn/T/GNAT-TEMP-000013.TMP.def
 -dylib
 -lemutls_w
 -lgcc
 -lSystem
 -U
 ___emutls_get_address
 -exported_symbol
 ___emutls_get_address
 -U
 ___emutls_register_common
 -exported_symbol
 ___emutls_register_common
 -no_compact_unwind

Please note the extra space after the -Wl,-rpath, options passed to gcc, and the resulting 2 spaces after the -rpath options passed to ld.

The result is that a program that uses the dynamic library fails,

$ ./main
dyld[76411]: Library not loaded: @rpath/libgnat-12.dylib
  Referenced from: <131C7F7E-4DFF-342A-858E-4046353B152C> /Users/simon/tmp/so/a-26821216/ada/lib/libtest.dylib
  Reason: tried: ' /opt/gcc-12.2.0/lib/gcc/x86_64-apple-darwin15/12.2.0/adalib/libgnat-12.dylib' (no such file), ' /opt/gcc-12.2.0/lib/libgnat-12.dylib' (no such file), '/Users/simon/tmp/so/a-26821216//ada/lib/libgnat-12.dylib' (no such file), '/Users/simon/tmp/so/a-26821216//ada/lib/libgnat-12.dylib' (no such file), '/usr/local/lib/libgnat-12.dylib' (no such file), '/usr/lib/libgnat-12.dylib' (no such file, not in dyld cache)
Abort trap: 6

(note the space in Reason: tried: ' /opt...).

Other gprbuilds tried:

simonjwright commented 1 year ago

This issue arose because of changes made in June 2022 in commit 2da92f4ab, TN: V517-017, Change-Id: I9f4a290ce1fcfa9b47c60930d7d0c17d5e5314e4.

This change was to "Allow multiply values in Run_Path_Option attribute in gprlib". I don't understand what can have given rise to this, because none of the Run_Path_Options in linker.xml have more than one occurrence for a specific configuration.

Maybe it's to do with something like this SO question, where you want to tell gcc e.g. -Wl,-rpath,<path> -Wl,--enable-new-dtags? though I've have thought that would need another option, since there can clearly be only one <path> per -rpath.

Why do I get the problem? because here any spaces inserted are passed to gcc in a single argument, and how that gets interpreted in the handover to the linker isn't obvious.

My first reaction would be to revert this commit, but of course I don't know what problem V517-017 was addressing.

For now, I'll just do this (change to v23.0.0)

diff --git a/src/gprlib.adb b/src/gprlib.adb
index d7547b1d..20abd33a 100644
--- a/src/gprlib.adb
+++ b/src/gprlib.adb
@@ -923,7 +923,7 @@ procedure Gprlib is
          if Separate_Run_Path_Options then
             for J in 1 .. Rpath.Last_Index loop
                Options_Table.Append
-                 (Concat_Paths (Path_Option, " ") & ' ' & Rpath (J));
+                 (Concat_Paths (Path_Option, " ") & Rpath (J));
             end loop;

          else

which relies on there being only one Path_Option.

simonjwright commented 3 months ago

I've just retried this; with GCC 13.2.0, gprbuild 24.0.0, Command Line Tools 14.2/15.3 the problem does not occur. So I think we can close?

t-14 commented 3 months ago

This works for us. Let's close.