[3/4] Darwin : Allow for configuring Darwin to use embedded runpath.

Message ID 20211117210319.92514-4-iain@sandoe.co.uk
State New
Headers
Series Darwin: Replace environment runpath with embedded [PR88590]. |

Commit Message

Iain Sandoe Nov. 17, 2021, 9:03 p.m. UTC
  Recent Darwin versions place contraints on the use of run paths
specified in environment variables.  This breaks some assumptions
in the GCC build.

This change allows the user to configure a Darwin build to use
'@rpath/libraryname.dylib' in library names and then to add an
embedded runpath to executables (and libraries with dependents).

The embedded runpath is added by default unless:

1. the user adds an explicit -rpath / -Wl,-rpath,....
2. the user adds '-nodefaultrpath'.

For an installed compiler, it means that any executable built with
that compiler will reference the runtimes installed with the
compiler (equivalent to hard-coding the library path into the name
of the library).

During build-time configurations  any "-B" entries will be added to
the runpath thus the newly-built libraries will be found by exes.

Since the install name is set in libtool, that decision needs to be
available here (but might also cause dependent ones in Makefiles,
so we need to export a conditional).

This facility is not available for Darwin 8 or earlier, however the
existing environment variable runpath does work there.

We default this on for systems where the external DYLD_LIBRARY_PATH
does not work and off for Darwin 8 or earlier.  For systems that can
use either method, if the value is unset, we use the default (which
is currently DYLD_LIBRARY_PATH).

ChangeLog:

	* configure: Regenerate.
	* configure.ac: Do not add default runpaths to GCC exes
	when we are building -static-libstdc++/-static-libgcc (the
	default).
	* libtool.m4: Add 'enable-darwin-at-runpath'.  Act  on the
	enable flag to alter Darwin libraries to use @rpath names.

gcc/ChangeLog:

	* aclocal.m4: Regenerate.
	* configure: Regenerate.

libatomic/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* testsuite/Makefile.in: Regenerate.

libcc1/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.

libffi/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.

libgcc/ChangeLog:

	* config/t-slibgcc-darwin: Generate libgcc_s
	with an @rpath name.

libgfortran/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Handle Darwin rpaths

libgomp/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.

libhsail-rt/ChangeLog:

	* configure: Regenerate.

libitm/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.

libobjc/ChangeLog:

	* configure: Regenerate.
	* configure.ac: Handle Darwin rpaths.

liboffloadmic/ChangeLog:

	* configure: Regenerate.
	* plugin/Makefile.in: Regenerate.
	* plugin/aclocal.m4: Regenerate.
	* plugin/configure: Regenerate.

libphobos/ChangeLog:

	* configure: Regenerate.
	* libdruntime/Makefile.am: Handle Darwin rpaths.
	* libdruntime/Makefile.in: Regenerate.
	* src/Makefile.am: Handle Darwin rpaths.
	* src/Makefile.in: Regenerate.

libquadmath/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Handle Darwin rpaths.

libsanitizer/ChangeLog:

	* asan/Makefile.am: Handle Darwin rpaths.
	* asan/Makefile.in: Regenerate.
	* configure: Regenerate.
	* hwasan/Makefile.am: Handle Darwin rpaths.
	* hwasan/Makefile.in: Regenerate.
	* lsan/Makefile.am: Handle Darwin rpaths.
	* lsan/Makefile.in: Regenerate.
	* tsan/Makefile.am: Handle Darwin rpaths.
	* tsan/Makefile.in: Regenerate.
	* ubsan/Makefile.am: Handle Darwin rpaths.
	* ubsan/Makefile.in: Regenerate.

libssp/ChangeLog:

	* Makefile.am: Handle Darwin rpaths.
	* Makefile.in: Regenerate.
	* configure: Regenerate.

libstdc++-v3/ChangeLog:

	* configure: Regenerate.
	* src/Makefile.am: Handle Darwin rpaths.
	* src/Makefile.in: Regenerate.

Darwin, libtool : Provide a mechanism to enable embedded rpaths.

We need to be able to build libraries with install names that begin
with @rpath so that we can use rpaths in DSOs that depend on
them.  Since the install name is set in libtool, that decision needs
to be available here (but might also cause dependent ones in
Makefiles, so we need to export a conditional).
---
 configure                         |   5 +
 configure.ac                      |   5 +
 gcc/aclocal.m4                    |  50 +++++++
 gcc/configure                     | 157 +++++++++++++++++++--
 libatomic/Makefile.am             |   6 +-
 libatomic/Makefile.in             |   5 +-
 libatomic/configure               |  82 ++++++++++-
 libatomic/testsuite/Makefile.in   |   1 +
 libbacktrace/configure            |  80 ++++++++++-
 libcc1/Makefile.am                |   9 ++
 libcc1/Makefile.in                |  12 +-
 libcc1/configure                  | 157 +++++++++++++++++++--
 libffi/Makefile.am                |   7 +-
 libffi/Makefile.in                |   6 +-
 libffi/configure                  | 157 +++++++++++++++++++--
 libgcc/config.host                |  22 ++-
 libgcc/config/t-darwin-rpath      |   5 +
 libgcc/config/t-slibgcc-darwin    |  13 +-
 libgfortran/Makefile.am           |   3 +
 libgfortran/Makefile.in           |  30 ++--
 libgfortran/configure             | 155 ++++++++++++++++++--
 libgfortran/configure.ac          |   4 +-
 libgomp/Makefile.am               |   6 +-
 libgomp/Makefile.in               |   3 +-
 libgomp/configure                 | 151 ++++++++++++++++++--
 libitm/Makefile.am                |   5 +-
 libitm/Makefile.in                |   3 +-
 libitm/configure                  | 171 ++++++++++++++++++++---
 libobjc/configure                 |  96 +++++++++++--
 libobjc/configure.ac              |  14 +-
 liboffloadmic/configure           | 199 +++++++++++++++++++++-----
 liboffloadmic/plugin/Makefile.in  |   2 +-
 liboffloadmic/plugin/aclocal.m4   |   2 +-
 liboffloadmic/plugin/configure    | 199 +++++++++++++++++++++-----
 libphobos/configure               | 151 ++++++++++++++++++--
 libphobos/libdruntime/Makefile.am |   5 +-
 libphobos/libdruntime/Makefile.in |   3 +-
 libphobos/src/Makefile.am         |   5 +-
 libphobos/src/Makefile.in         |   3 +-
 libquadmath/Makefile.am           |   6 +-
 libquadmath/Makefile.in           |   4 +-
 libquadmath/configure             | 225 +++++++++++++++++++++++++++++-
 libquadmath/configure.ac          |   2 +
 libsanitizer/asan/Makefile.am     |   6 +-
 libsanitizer/asan/Makefile.in     |   5 +-
 libsanitizer/configure            | 157 +++++++++++++++++++--
 libsanitizer/hwasan/Makefile.am   |   6 +-
 libsanitizer/hwasan/Makefile.in   |   5 +-
 libsanitizer/lsan/Makefile.am     |   7 +-
 libsanitizer/lsan/Makefile.in     |   6 +-
 libsanitizer/tsan/Makefile.am     |   6 +-
 libsanitizer/tsan/Makefile.in     |   5 +-
 libsanitizer/ubsan/Makefile.am    |   6 +-
 libsanitizer/ubsan/Makefile.in    |   5 +-
 libssp/Makefile.am                |   5 +-
 libssp/Makefile.in                |   3 +-
 libssp/configure                  |  82 ++++++++++-
 libstdc++-v3/configure            | 169 +++++++++++++++++++---
 libstdc++-v3/src/Makefile.am      |   6 +-
 libstdc++-v3/src/Makefile.in      |   3 +-
 libtool.m4                        |  64 ++++++++-
 libvtv/configure                  | 171 ++++++++++++++++++++---
 lto-plugin/Makefile.in            |   1 -
 lto-plugin/configure              |  80 ++++++++++-
 zlib/configure                    |  82 ++++++++++-
 67 files changed, 2780 insertions(+), 532 deletions(-)
 create mode 100644 libgcc/config/t-darwin-rpath
  

Comments

Joseph Myers Nov. 17, 2021, 10:50 p.m. UTC | #1
On Wed, 17 Nov 2021, Iain Sandoe via Gcc-patches wrote:

> 	* libtool.m4: Add 'enable-darwin-at-runpath'.  Act  on the
> 	enable flag to alter Darwin libraries to use @rpath names.

To confirm: has this been sent to upstream libtool (which has recently 
acquired a new maintainer, so hopefully might become a bit more active at 
dealing with the backlog of patches)?
  
Iain Sandoe Nov. 17, 2021, 11:30 p.m. UTC | #2
> On 17 Nov 2021, at 22:50, Joseph Myers <joseph@codesourcery.com> wrote:
> 
> On Wed, 17 Nov 2021, Iain Sandoe via Gcc-patches wrote:
> 
>> 	* libtool.m4: Add 'enable-darwin-at-runpath'.  Act  on the
>> 	enable flag to alter Darwin libraries to use @rpath names.
> 
> To confirm: has this been sent to upstream libtool (which has recently 
> acquired a new maintainer, so hopefully might become a bit more active at 
> dealing with the backlog of patches)?

No. it has not
(a) I was not aware of the new maintainer
(b) the background problem does seem a pretty GCC-specific issue.

If we are going to try and reconcile GCC’s local libtool for more generic Darwin
use, then I fear that is going to take quite significant work over a period of time
(since it will need much more wide testing than GCC).

Having said that, it would be good to have a more up-to-date upstream libtool
the current source has a lot of ancient content - as with all things it’s just a
question of resources.   It’s unlikely to be on my radar in time for GCC12.

Iain
  
Jonathan Wakely Nov. 18, 2021, 3:34 p.m. UTC | #3
On Wed, 17 Nov 2021 at 21:28, Iain Sandoe via Libstdc++ <
libstdc++@gcc.gnu.org> wrote:

> this refers to the libstdc++ changes (mostly a regeneration from the
> libtool
> change) but a small addition to Makefile.am to add @loader_path as a
> default for libstdc++ to find its dependent libs.
>


The libstdc++ part looks OK.
  
Joseph Myers Nov. 18, 2021, 9:49 p.m. UTC | #4
On Wed, 17 Nov 2021, Iain Sandoe via Gcc-patches wrote:

> If we are going to try and reconcile GCC’s local libtool for more 
> generic Darwin use, then I fear that is going to take quite significant 
> work over a period of time (since it will need much more wide testing 
> than GCC).

The goal isn't any kind of merging GCC's libtool with upstream right now.  
But, once the new maintainer has got through the patch backlog, we'd like 
to be in a position where the starting point for a libtool update in GCC 
is simply taking upstream libtool and reverting libtool commit 
3334f7ed5851ef1e96b052f2984c4acdbf39e20c to deal with a mismatch of 
--with-sysroot interpretations - but not needing any local changes other 
than that reversion.  If each local libtool patch gets submitted upstream 
before being applied to GCC, that reduces the chances of missing some 
significant local change that needs to be reapplied when updating libtool 
(given that GCC is apparently using libtool commit 
2c9c38d8a12eb0a2ce7fe9c3862523026c3d5622 from 2009, it may well be 
nontrivial to figure out whether a given local change is actually relevant 
with a new libtool version or not).
  

Patch

diff --git a/configure.ac b/configure.ac
index bed60bcaf72..bd79a2ffcb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1769,6 +1769,11 @@  AC_ARG_WITH(boot-ldflags,
  if test "$poststage1_libs" = ""; then
    poststage1_ldflags="-static-libstdc++ -static-libgcc"
  fi])
+if test "x$enable_darwin_at_rpath" = "xyes"; then
+  if test "x$host_shared" != "xyes"; then 
+    poststage1_ldflags="$poststage1_ldflags -nodefaultrpath"
+  fi
+fi 
 AC_SUBST(poststage1_ldflags)
 
 # GCC GRAPHITE dependency isl.


diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am
index 0f3cd6f7121..cde856e532e 100644
--- a/libatomic/Makefile.am
+++ b/libatomic/Makefile.am
@@ -65,8 +65,12 @@  libatomic_version_script =
 libatomic_version_dep =
 endif
 libatomic_version_info = -version-info $(libtool_VERSION)
+if ENABLE_DARWIN_AT_RPATH
+libatomic_darwin_rpath = -Wl,-rpath,@loader_path
+endif
 
-libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) $(lt_host_flags)
+libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) \
+	$(lt_host_flags) $(libatomic_darwin_rpath) 
 libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \
 	fenv.c fence.c flag.c
 
diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am
index 49a9543ea7d..aa07d5923bb 100644
--- a/libcc1/Makefile.am
+++ b/libcc1/Makefile.am
@@ -55,6 +55,9 @@  marshall_c_source = marshall-c.hh
 marshall_cxx_source = marshall-cp.hh
 
 libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
+if ENABLE_DARWIN_AT_RPATH
+libcc1plugin_la_LDFLAGS += -Wl,-rpath,@loader_path
+endif
 libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \
 	$(shared_source) $(marshall_c_source)
 libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C)
@@ -65,6 +68,9 @@  libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@
 
 libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym
+if ENABLE_DARWIN_AT_RPATH
+libcp1plugin_la_LDFLAGS += -Wl,-rpath,@loader_path
+endif
 libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \
 	$(shared_source) $(marshall_cxx_source)
 libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX)
@@ -76,6 +82,9 @@  libcp1plugin_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
 libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym
+if ENABLE_DARWIN_AT_RPATH
+libcc1_la_LDFLAGS += -Wl,-rpath,@loader_path
+endif
 libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \
 		compiler.cc compiler.hh names.cc names.hh $(shared_source) \
 		$(marshall_c_source) $(marshall_cxx_source)

diff --git a/libffi/Makefile.am b/libffi/Makefile.am
index c6d6f849c53..d2ae0c04c7b 100644
--- a/libffi/Makefile.am
+++ b/libffi/Makefile.am
@@ -214,7 +214,12 @@  libffi.map: $(top_srcdir)/libffi.map.in
 	$(COMPILE) -D$(TARGET) -DGENERATE_LIBFFI_MAP \
 	 -E -x assembler-with-cpp -o $@ $(top_srcdir)/libffi.map.in
 
-libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS)
+if ENABLE_DARWIN_AT_RPATH
+libffi_darwin_rpath = -Wl,-rpath,@loader_path
+endif
+libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) \
+	$(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) \
+	$(libffi_darwin_rpath)
 libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
 
 AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src

diff --git a/libffi/Makefile.in b/libffi/Makefile.in
index 5524a6a571e..34e77a45d1a 100644
--- a/libffi/Makefile.in
+++ b/libffi/Makefile.in
@@ -597,7 +597,11 @@  AM_CFLAGS = -Wall -g -fexceptions $(CET_FLAGS) $(am__append_2)
 @LIBFFI_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@libffi_version_dep = libffi.map
 @LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@libffi_version_dep = libffi.map-sun
 libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
-libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS)
+@ENABLE_DARWIN_AT_RPATH_TRUE@libffi_darwin_rpath = -Wl,-rpath,@loader_path
+libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) \
+	$(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) \
+	$(libffi_darwin_rpath)
+
 libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
 AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
 AM_CCASFLAGS = $(AM_CPPFLAGS) $(CET_FLAGS)


diff --git a/libgcc/config.host b/libgcc/config.host
index 168535b1780..5306a509ff8 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -214,7 +214,27 @@  esac
 case ${host} in
 *-*-darwin*)
   asm_hidden_op=.private_extern
-  tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic t-slibgcc-darwin"
+  tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin "
+  tmake_file="$tmake_file t-libgcc-pic t-slibgcc-darwin "
+  # We are not using libtool to build the libs here, so we need to replicate
+  # a little of the logic around setting Darwin rpaths.  Setting an explicit
+  # yes or no is honoured, otherwise we choose a suitable default.
+  # Sadly, this has to be kept in line with the rules in libtool.m4.
+  if test "x$enable_darwin_at_rpath" = "xyes"; then
+    tmake_file="$tmake_file t-darwin-rpath "
+  elif test "x$enable_darwin_at_rpath" = "x"; then
+    echo "enable_darwin_at_rpath is unset" 1>&2
+    case ${host} in
+      *-darwin[45678]*) ;;
+      *-darwin9* | *-darwin1[01234]*) ;; # We might default these on later.
+      *-darwin*)
+        echo "but is needed after macOS 10.11 (setting it on)" 1>&2
+        tmake_file="$tmake_file t-darwin-rpath "
+        ;;
+    esac
+  else
+    echo "enable_darwin_at_rpath is '$enable_darwin_at_rpath'" 1>&2
+  fi
   extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o"
   ;;
 *-*-dragonfly*)

diff --git a/libgcc/config/t-darwin-rpath b/libgcc/config/t-darwin-rpath
new file mode 100644
index 00000000000..7cf63d9cb6b
--- /dev/null
+++ b/libgcc/config/t-darwin-rpath
@@ -0,0 +1,5 @@ 
+# Use @rpath and add a search path to exes and dylibs that depend on this.
+SHLIB_RPATH = @rpath
+
+# Which does not work for Darwin < 9
+HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=10.5
diff --git a/libgcc/config/t-slibgcc-darwin b/libgcc/config/t-slibgcc-darwin
index bd1e9631c17..b800a9aa175 100644
--- a/libgcc/config/t-slibgcc-darwin
+++ b/libgcc/config/t-slibgcc-darwin
@@ -10,17 +10,16 @@  SHLIB_OBJS = @shlib_objs@
 SHLIB_DIR = @multilib_dir@
 SHLIB_LC = -lc
 
-# Darwin only searches in /usr/lib for shared libraries, not in subdirectories,
-# so the libgcc variants have different names not different locations.
-# Note that this version is used for the loader, not the linker; the linker
-# uses the stub versions named by the versioned members of $(INSTALL_FILES).
+# Instead of using @shlib_slibdir@, use @rpath and add a search path to exes
+# and dylibs that depend on this.
+SHLIB_RPATH = @shlib_slibdir@
 
 SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -dynamiclib -nodefaultlibs \
-	-install_name @shlib_slibdir@/$(SHLIB_INSTALL_NAME) \
+	-install_name $(SHLIB_RPATH)/$(SHLIB_INSTALL_NAME) \
 	-single_module -o $(SHLIB_DIR)/$(SHLIB_SONAME) \
 	-Wl,-exported_symbols_list,$(SHLIB_MAP) \
-	$(SHLIB_VERSTRING) \
-	@multilib_flags@ $(SHLIB_OBJS) $(SHLIB_LC)
+	$(SHLIB_VERSTRING) -nodefaultrpath \
+	@multilib_flags@ @shlib_objs@ $(SHLIB_LC)
 
 SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
 SHLIB_MKMAP_OPTS = -v leading_underscore=1

diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index 008f2e7549c..e036b88119e 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -29,6 +29,9 @@  else
 version_arg =
 version_dep =
 endif
+if ENABLE_DARWIN_AT_RPATH
+extra_ldflags_libgfortran += -Wl,-rpath,@loader_path
+endif
 
 gfor_c_HEADERS = ISO_Fortran_binding.h
 gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include

diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index f8b2a06d63e..4dca7e532bf 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -53,9 +53,13 @@  else
 libgomp_version_script =
 libgomp_version_dep =
 endif
+
 libgomp_version_info = -version-info $(libtool_VERSION)
+if ENABLE_DARWIN_AT_RPATH
+libgomp_darwin_rpath = -Wl,-rpath,@loader_path
+endif
 libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \
-        $(lt_host_flags)
+        $(lt_host_flags) $(libgomp_darwin_rpath)
 libgomp_la_DEPENDENCIES = $(libgomp_version_dep)
 libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS)
 
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index 22cb2136a08..7a45add6a36 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -546,8 +546,9 @@  nodist_toolexeclib_HEADERS = libgomp.spec
 @LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver
 @LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver-sun
 libgomp_version_info = -version-info $(libtool_VERSION)
+@ENABLE_DARWIN_AT_RPATH_TRUE@libgomp_darwin_rpath = -Wl,-rpath,@loader_path
 libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \
-        $(lt_host_flags)
+        $(lt_host_flags) $(libgomp_darwin_rpath)
 
 libgomp_la_DEPENDENCIES = $(libgomp_version_dep)
 libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS)

diff --git a/libitm/Makefile.am b/libitm/Makefile.am
index 3f31ad30556..053a54fb093 100644
--- a/libitm/Makefile.am
+++ b/libitm/Makefile.am
@@ -54,7 +54,10 @@  libitm_version_info = -version-info $(libtool_VERSION)
 # want or need libstdc++.
 libitm_la_DEPENDENCIES = $(libitm_version_dep)
 libitm_la_LINK = $(LINK) $(libitm_la_LDFLAGS)
-libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script)
+if ENABLE_DARWIN_AT_RPATH
+libitm_darwin_rpath = -Wl,-rpath,@loader_path
+endif
+libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) $(libitm_darwin_rpath)
 
 libitm_la_SOURCES = \
 	aatree.cc alloc.cc alloc_c.cc alloc_cpp.cc barrier.cc beginend.cc \


diff --git a/libobjc/configure.ac b/libobjc/configure.ac
index c1104db85f0..92b77dc1700 100644
--- a/libobjc/configure.ac
+++ b/libobjc/configure.ac
@@ -148,10 +148,20 @@  m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
 # extra LD Flags which are required for targets
 ACX_LT_HOST_FLAGS
 case "${host}" in
-  *-darwin*)
-    # Darwin needs -single_module when linking libobjc
+  *-darwin[[4567]]*)
+    # Earlier Darwin versions need -single_module when linking libobjc; they
+    # do not support @rpath.
     extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module'
     ;;
+  *-darwin*)
+    # Otherwise, single_module is the default and multi-module is ignored and
+    # obsolete.
+    if test "x$enable_darwin_at_rpath" = "xyes"; then
+      extra_ldflags_libobjc='$(lt_host_flags) -Wl,-rpath,@loader_path'
+    else
+      extra_ldflags_libobjc='$(lt_host_flags)'
+    fi
+    ;;
   *-cygwin*|*-mingw*)
     # Tell libtool to build DLLs on Windows
     extra_ldflags_libobjc='$(lt_host_flags)'


diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am
index 4f802f723d6..86ac110466b 100644
--- a/libsanitizer/asan/Makefile.am
+++ b/libsanitizer/asan/Makefile.am
@@ -60,7 +60,11 @@  libasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
 endif
 libasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
 
-libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan)
+if ENABLE_DARWIN_AT_RPATH
+libasan_darwin_rpath = -Wl,-rpath,@loader_path
+endif
+libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
+	$(link_libasan) $(libasan_darwin_rpath)
 
 libasan_preinit.o: asan_preinit.o
 	cp $< $@

diff --git a/libsanitizer/hwasan/Makefile.am b/libsanitizer/hwasan/Makefile.am
index e12c0a0ce71..d73bcac782a 100644
--- a/libsanitizer/hwasan/Makefile.am
+++ b/libsanitizer/hwasan/Makefile.am
@@ -46,7 +46,11 @@  libhwasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
 endif
 libhwasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
 
-libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libhwasan)
+if ENABLE_DARWIN_AT_RPATH
+libhwasan_darwin_rpath = -Wl,-rpath,@loader_path
+endif
+libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
+	$(link_libhwasan) $(libhwasan_darwin_rpath)
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
 # values defined in terms of make variables, as is the case for CC and

diff --git a/libsanitizer/lsan/Makefile.am b/libsanitizer/lsan/Makefile.am
index 6ff28ff5eea..34a9f7b9977 100644
--- a/libsanitizer/lsan/Makefile.am
+++ b/libsanitizer/lsan/Makefile.am
@@ -41,8 +41,11 @@  if LIBBACKTRACE_SUPPORTED
 liblsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
 endif
 liblsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_liblsan)
-
+if ENABLE_DARWIN_AT_RPATH
+liblsan_darwin_rpath = -Wl,-rpath,@loader_path
+endif
+liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
+	$(link_liblsan) $(liblsan_darwin_rpath)
 liblsan_preinit.o: lsan_preinit.o
 	cp $< $@
 

diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am
index ae588a67df6..eed8f321b3c 100644
--- a/libsanitizer/tsan/Makefile.am
+++ b/libsanitizer/tsan/Makefile.am
@@ -58,7 +58,11 @@  libtsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
 libtsan_la_DEPENDENCIES +=$(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
 endif
 libtsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libtsan)
+if ENABLE_DARWIN_AT_RPATH
+libtsan_darwin_rpath = -Wl,-rpath,@loader_path
+endif
+libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
+	$(link_libtsan) $(libtsan_darwin_rpath)
 
 libtsan_preinit.o: tsan_preinit.o
 	cp $< $@

diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am
index d480f26adc0..0bfae37ba09 100644
--- a/libsanitizer/ubsan/Makefile.am
+++ b/libsanitizer/ubsan/Makefile.am
@@ -36,7 +36,11 @@  if LIBBACKTRACE_SUPPORTED
 libubsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la
 endif
 libubsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libubsan)
+if ENABLE_DARWIN_AT_RPATH
+libubsan_darwin_rpath = -Wl,-rpath,@loader_path
+endif
+libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
+	$(link_libubsan) $(libubsan_darwin_rpath)
 
 # Use special rules for files that require RTTI support.
 ubsan_handlers_cxx.% ubsan_type_hash.% ubsan_type_hash_itanium.% : AM_CXXFLAGS += -frtti

diff --git a/libssp/Makefile.am b/libssp/Makefile.am
index 6045c320cfa..1155e987a9b 100644
--- a/libssp/Makefile.am
+++ b/libssp/Makefile.am
@@ -49,8 +49,11 @@  libssp_la_SOURCES = \
 	vsnprintf-chk.c vsprintf-chk.c
 libssp_la_LIBADD = 
 libssp_la_DEPENDENCIES = $(version_dep) $(libssp_la_LIBADD)
+if ENABLE_DARWIN_AT_RPATH
+libssp_darwin_rpath = -Wl,-rpath,@loader_path
+endif
 libssp_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
-		    $(version_arg) $(lt_host_flags)
+		    $(version_arg) $(lt_host_flags) $(libssp_darwin_rpath)
 
 libssp_nonshared_la_SOURCES = \
 	ssp-local.c

diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index f27d3f8c87e..77e7cedb17a 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -122,8 +122,12 @@  libstdc___la_DEPENDENCIES = \
 	$(top_builddir)/src/c++17/libc++17convenience.la \
 	$(top_builddir)/src/c++20/libc++20convenience.la
 
+if ENABLE_DARWIN_AT_RPATH
+libstdc___darwin_rpath = -Wl,-rpath,@loader_path
+endif
+
 libstdc___la_LDFLAGS = \
-	-version-info $(libtool_VERSION) ${version_arg} -lm
+	-version-info $(libtool_VERSION) ${version_arg} -lm $(libstdc___darwin_rpath)
 
 libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags)
 
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 05b25ed5e9d..c4eb9e8c546 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -534,8 +534,9 @@  libstdc___la_DEPENDENCIES = \
 	$(top_builddir)/src/c++17/libc++17convenience.la \
 	$(top_builddir)/src/c++20/libc++20convenience.la
 
+@ENABLE_DARWIN_AT_RPATH_TRUE@libstdc___darwin_rpath = -Wl,-rpath,@loader_path
 libstdc___la_LDFLAGS = \
-	-version-info $(libtool_VERSION) ${version_arg} -lm
+	-version-info $(libtool_VERSION) ${version_arg} -lm $(libstdc___darwin_rpath)
 
 libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags)
 @GLIBCXX_LDBL_ALT128_COMPAT_FALSE@@GLIBCXX_LDBL_COMPAT_TRUE@LTCXXCOMPILE64 = $(LTCXXCOMPILE)

diff --git a/libtool.m4 b/libtool.m4
index 17f8e5f3074..b474089fc3e 100644
--- a/libtool.m4
+++ b/libtool.m4
@@ -1039,6 +1039,47 @@  _LT_EOF
 m4_defun([_LT_DARWIN_LINKER_FEATURES],
 [
   m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+
+  # Publish an arg to allow the user to select that Darwin host (and target)
+  # libraries should be given install-names like @rpath/libfoo.dylib.  This
+  # requires that the user of the library then adds an 'rpath' to the DSO that
+  # needs access.
+  # NOTE: there are defaults below, for systems that support rpaths.  The person
+  # configuring can override the defaults for any system version that supports
+  # them - they are, however, forced off for system versions without support.
+  AC_ARG_ENABLE([darwin-at-rpath],
+    AS_HELP_STRING([--enable-darwin-at-path],
+      [install libraries with @rpath/library-name, requires rpaths to be added to executables]),
+  [if test "x$enable_darwin_at_rpath" = "xyes"; then
+    # This is not supported before macOS 10.5 / Darwin9.
+    case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in
+      UNSET,darwin[[45678]]*|UNSET,rhapsody*|10.[[01234]][[,.]]*)
+	echo "WARNING: Darwin @rpath library names are incompatible with macOS versions earlier than 10.5 (rpaths disabled)" 1>&AS_MESSAGE_LOG_FD
+	enable_darwin_at_rpath=no
+      ;;
+    esac
+   fi],
+  [case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in
+    # As above, before 10.5 / Darwin9 this does not work.
+     UNSET,darwin[[45678]]*|UNSET,rhapsody*|10.[[01234]][[,.]]*)
+       enable_darwin_at_rpath=no
+       ;;
+
+    # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use
+    # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key
+    # system executables (e.g. /bin/sh).  Force rpaths on for these systems.
+      UNSET,darwin1[[56789]]*|UNSET,darwin2*|10.1[[123456789]][[,.]]*|1[[12]].*[[,.]]* )
+      echo "@rpath library names are needed on macOS versions later than 10.11 (rpaths enabled)" 1>&AS_MESSAGE_LOG_FD
+      enable_darwin_at_rpath=yes
+      ;;
+    # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can
+    # work with either DYLD_LIBRARY_PATH or embedded rpaths.
+
+    esac
+  ])
+
+  AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test "x$enable_darwin_at_rpath" = "xyes"])
+
   _LT_TAGVAR(archive_cmds_need_lc, $1)=no
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_automatic, $1)=yes
@@ -1056,13 +1097,26 @@  m4_defun([_LT_DARWIN_LINKER_FEATURES],
   esac
   if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
-    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    if test "x$enable_darwin_at_rpath" = "xyes"; then
+      echo "using Darwin @rpath" 1>&AS_MESSAGE_LOG_FD
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dsymutil}"
+      _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}"
+      _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    else
+      echo "NOT using Darwin @rpath" 1>&AS_MESSAGE_LOG_FD
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+      _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+      _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
     m4_if([$1], [CXX],
 [   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
-      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      if test "x$enable_darwin_at_rpath" = "xyes"; then
+        _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name @rpath/\$soname \$verstring${_lt_dsymutil}"
+      else
+        _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      fi
       _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 ],[])

diff --git a/lto-plugin/Makefile.in b/lto-plugin/Makefile.in
index f8df31bb1e8..591a1624e98 100644
--- a/lto-plugin/Makefile.in
+++ b/lto-plugin/Makefile.in
@@ -323,7 +323,6 @@  prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 real_target_noncanonical = @real_target_noncanonical@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@