-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix executable and more library RPATHs on FreeBSD #27627
Conversation
Make.inc
Outdated
else | ||
RPATH := | ||
endif | ||
RPATH += -Wl,-rpath,'$$ORIGIN/$(build_libdir_rel)' -Wl,-rpath-link,$(build_shlibdir) -Wl,-z,origin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be more concise by initializing RPATH
to the shared subset, then, if on FreeBSD
, adding on the FreeBSD
-specific part. Ordering shouldn't matter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I wasn't sure if the order mattered, that's why I did it this way.
julia-deps: | $$(build_libdir)/$(1).so | ||
$$(build_libdir)/$(1).so: | $$(build_libdir) | ||
$$(INSTALL_M) $$(GCCPATH)/$(1).so* $$(build_libdir) | ||
JL_PRIVATE_LIBS-0 += $(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add a note here saying why we need this, and why we must install the libraries into $(private_libdir)
on FreeBSD explicitly like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Makefile
Outdated
# Set libgfortran's RPATH to ORIGIN instead of GCCPATH | ||
for lib in $(DESTDIR)$(private_libdir)/libgfortran*$(SHLIB_EXT)*; do \ | ||
$(build_depsbindir)/patchelf --set-rpath '$$ORIGIN' $$lib; \ | ||
done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we actually only need to do this for libgfortran
, or do we need to do it for libgcc_s
and friends as well? If only libgfortran
, I think we should add a more explicit note saying why we need to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just libgfortran
in this case; of the GCC library clan, it's the only with its RPATH set. If we don't fix it, it fails to find libgcc_s
and libquadmath
on systems without the GCC port installed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right; that makes sense. Weird how it's the only one. I would put your comment here into the comment in Makefile
.
Makefile
Outdated
ifneq ($(OS), WINNT) | ||
# Run fixup-libgfortran on all platforms but Windows and FreeBSD | ||
# On FreeBSD we're getting and fixing these libraries earlier | ||
ifeq (,$(findstring $(OS),FreeBSD WINNT)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would explain why we fix the libraries earlier. Something like "FreeBSD
doesn't link to the compiler-provided libgcc_s
by default, which causes problems, so we copy our compiler's libgcc_s
into our lib
directory at the beginning of the build" or something like that.
First of all, we need to add libgfortran, libgcc_s, and libquadmath to `JL_PRIVATE_LIBS-0` instead of `JL_LIBS`. This ensures that they get installed into `lib/julia`, where our dependencies are supposed to live, instead of `lib`, where only libjulia should live. Now we need to call `fixup-rpath.sh` on more directories. Currently we're only calling it on `lib`, but we also need to call it on `lib/julia` and even on `bin`, because FreeBSD seems to load libraries based on the executable's RPATH rather than libjulia's RPATH. AND, speaking of the executable's RPATH, we need to make sure we have `lib/julia` in there; currently we only have `lib`. So in an isolated environment outside of the build directory, Julia won't be able to load any of its dependencies, which is bad. This is accomplished with a simple adjustment in `Make.inc`. To make sure that our dependencies can find each other properly, we need to add `RPATH_ESCAPED_ORIGIN` to `LDFLAGS` in `CONFIGURE_COMMON`. That way, every dependency that uses `configure` will get its RPATH set appropriately.
545442e
to
c9258e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beautiful
The FreeBSD CI failure worried me a bit but I did a local |
Yeah, looks to be unrelated. |
First of all, we need to add libgfortran, libgcc_s, and libquadmath to `JL_PRIVATE_LIBS-0` instead of `JL_LIBS`. This ensures that they get installed into `lib/julia`, where our dependencies are supposed to live, instead of `lib`, where only libjulia should live. Now we need to call `fixup-rpath.sh` on more directories. Currently we're only calling it on `lib`, but we also need to call it on `lib/julia` and even on `bin`, because FreeBSD seems to load libraries based on the executable's RPATH rather than libjulia's RPATH. AND, speaking of the executable's RPATH, we need to make sure we have `lib/julia` in there; currently we only have `lib`. So in an isolated environment outside of the build directory, Julia won't be able to load any of its dependencies, which is bad. This is accomplished with a simple adjustment in `Make.inc`. To make sure that our dependencies can find each other properly, we need to add `RPATH_ESCAPED_ORIGIN` to `LDFLAGS` in `CONFIGURE_COMMON`. That way, every dependency that uses `configure` will get its RPATH set appropriately. (cherry picked from commit 07edead)
First of all, we need to add libgfortran, libgcc_s, and libquadmath to `JL_PRIVATE_LIBS-0` instead of `JL_LIBS`. This ensures that they get installed into `lib/julia`, where our dependencies are supposed to live, instead of `lib`, where only libjulia should live. Now we need to call `fixup-rpath.sh` on more directories. Currently we're only calling it on `lib`, but we also need to call it on `lib/julia` and even on `bin`, because FreeBSD seems to load libraries based on the executable's RPATH rather than libjulia's RPATH. AND, speaking of the executable's RPATH, we need to make sure we have `lib/julia` in there; currently we only have `lib`. So in an isolated environment outside of the build directory, Julia won't be able to load any of its dependencies, which is bad. This is accomplished with a simple adjustment in `Make.inc`. To make sure that our dependencies can find each other properly, we need to add `RPATH_ESCAPED_ORIGIN` to `LDFLAGS` in `CONFIGURE_COMMON`. That way, every dependency that uses `configure` will get its RPATH set appropriately. (cherry picked from commit 07edead)
First of all, we need to add libgfortran, libgcc_s, and libquadmath to
JL_PRIVATE_LIBS-0
instead ofJL_LIBS
. This ensures that they get installed intolib/julia
, where our dependencies are supposed to live, instead oflib
, where only libjulia should live.Now we need to call
fixup-rpath.sh
on more directories. Currently we're only calling it onlib
, but we also need to call it onlib/julia
and even onbin
, because FreeBSD seems to load libraries based on the executable's RPATH rather than libjulia's RPATH.AND, speaking of the executable's RPATH, we need to make sure we have
lib/julia
in there; currently we only havelib
. So in an isolated environment outside of the build directory, Julia won't be able to load any of its dependencies, which is bad. This is accomplished with a simple adjustment inMake.inc
.To make sure that our dependencies can find each other properly, we need to add
RPATH_ESCAPED_ORIGIN
toLDFLAGS
inCONFIGURE_COMMON
. That way, every dependency that usesconfigure
will get its RPATH set appropriately.