Skip to content

Commit

Permalink
Consistently use RUNPATH in our libraries
Browse files Browse the repository at this point in the history
When loading dependencies on Linux, we can either use `RPATH` or
`RUNPATH` as a list of relative paths to search for libraries.  The
difference, for our purposes, mainly lies within how this interacts with
`LD_LIBRARY_PATH`: `RPATH` is searched first, then `LD_LIBRARY_PATH`,
then `RUNPATH`.  So by using `RUNPATH` here, we are explicitly allowing
ourselves to be overridden by `LD_LIBRARY_PATH`.  This is fine, as long
as we are consistent across our entire library line, however in the
`v1.8.0` release, there was an inconsistency, reported in [0].

The inconsistency occured because of the following confluence of factors:

 - Ancient `ld` builds (such as the one used in our build environment)
   do not default to using `RUNPATH`, but instead use `RPATH`.
 - `patchelf`, when it rewrites the RPATH, will default to using
   `RUNPATH` instead.
 - We were only using `patchelf` on `libjulia-internal`, not on
   `libjulia-codegen`, which was newly added in `v1.8`.

These three factors together caused us to ship a binary with `RUNPATH`
in `libjulia-internal`, but `RPATH` in `libjulia-codegen`, which caused
loading to fail in [0] due to first `libjulia-internal` being loaded,
(which brought in the external `libstdc++`), then `libjulia-codegen`
failed to load (because it found an incompatible `libstdc++`), causing
the mysterious compiler error.

This PR fixes this twofold; first, when building the libraries in the
first place, we pass `--enable-new-dtags` to the linker to encourage it
to use `runpath` when possible.  This removes the possibility for a
missing `patchelf` invocation to break things in this way.  Second, we
apply `patchelf` properly to `libjulia-codegen` as well.

[0] #46409
  • Loading branch information
staticfloat committed Aug 23, 2022
1 parent 18fa383 commit bb9dd4f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
15 changes: 9 additions & 6 deletions Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,9 @@ else
NO_WHOLE_ARCHIVE := -Wl,--no-whole-archive
endif

# Initialize these once, then add to them in OS-specific blocks
JLIBLDFLAGS :=

ifeq ($(OS), Linux)
OSLIBS += -Wl,--no-as-needed -ldl -lrt -lpthread -latomic -Wl,--export-dynamic,--as-needed,--no-whole-archive
# Detect if ifunc is supported
Expand All @@ -1236,14 +1239,14 @@ ifneq ($(SANITIZE),1)
JLDFLAGS += -Wl,-no-undefined
endif
ifeq (-Bsymbolic-functions, $(shell $(LD) --help | grep -o -e "-Bsymbolic-functions"))
JLIBLDFLAGS := -Wl,-Bsymbolic-functions
else
JLIBLDFLAGS :=
JLIBLDFLAGS += -Wl,-Bsymbolic-functions
endif
ifeq (--enable-new-dtags, $(shell $(LD) --help | grep -o -e "--enable-new-dtags"))
JLIBLDFLAGS += -Wl,--enable-new-dtags
endif

# Linker doesn't detect automatically that Julia doesn't need executable stack
JLIBLDFLAGS += -Wl,-z,noexecstack
else ifneq ($(OS), Darwin)
JLIBLDFLAGS :=
endif

ifeq ($(OS), FreeBSD)
Expand All @@ -1266,7 +1269,7 @@ OSLIBS += -framework CoreFoundation
WHOLE_ARCHIVE := -Xlinker -all_load
NO_WHOLE_ARCHIVE :=
HAVE_SSP := 1
JLIBLDFLAGS := -Wl,-compatibility_version,$(SOMAJOR) -Wl,-current_version,$(JULIA_MAJOR_VERSION).$(JULIA_MINOR_VERSION).$(JULIA_PATCH_VERSION)
JLIBLDFLAGS += -Wl,-compatibility_version,$(SOMAJOR) -Wl,-current_version,$(JULIA_MAJOR_VERSION).$(JULIA_MINOR_VERSION).$(JULIA_PATCH_VERSION)
endif

ifeq ($(OS), WINNT)
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,10 @@ endif
ifneq (,$(findstring $(OS),Linux FreeBSD))
ifeq ($(JULIA_BUILD_MODE),release)
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-internal.$(SHLIB_EXT)
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-codegen.$(SHLIB_EXT)
else ifeq ($(JULIA_BUILD_MODE),debug)
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-internal-debug.$(SHLIB_EXT)
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-codegen-debug.$(SHLIB_EXT)
endif
endif

Expand Down

0 comments on commit bb9dd4f

Please sign in to comment.