From 0b211609bb9790cf86edc08b256df42d0c480df1 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Thu, 19 Jan 2023 04:25:15 +0000 Subject: [PATCH] Move `libstdc++` path into `LOADER_*_DEP_LIBS` After adding `libstdc++` probing into the Julia loader [0], we originally made the assumption that the `libstdc++` that is shipped with `julia` would always be co-located with `libjulia.so` [1]. This is not the case when building with `USE_SYSTEM_CSL=1`, however, where we sequester system libraries in `usr/lib/julia`, even at build-time. The path to `libstdc++.so` has already been getting altered when moving from build-time to install time via `stringreplace` [2], but after further thought, I decided that it would be better to just use the pre-existing `LOADER_*_DEP_LIBS` mechanism to communicate to the loader what the correct relative path to `libstdc++.so` is. This also allows the single `stringreplace` to update all of our "special" library paths. [0] https://github.com/JuliaLang/julia/pull/46976 [1] https://github.com/JuliaLang/julia/pull/46976/files#diff-8c5c98f26f3f7aac8905a1074c5bec11a57e9b9c7c556791deac5a3b27cc096fR379 [2] https://github.com/JuliaLang/julia/blob/master/Makefile#L430 --- Make.inc | 21 +++++++++++--- Makefile | 6 ---- cli/loader_lib.c | 72 +++++++++++++++++++++++++++++++----------------- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/Make.inc b/Make.inc index 24f5964e9dcc0..a7cd154aa347e 100644 --- a/Make.inc +++ b/Make.inc @@ -1512,6 +1512,19 @@ LIBGCC_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_shlibdir)/$(L endif LIBGCC_INSTALL_DEPLIB := $(call dep_lib_path,$(libdir),$(private_shlibdir)/$(LIBGCC_NAME)) +# We only bother to define this on Linux, as that's the only platform that does libstdc++ probing +# On all other platforms, the LIBSTDCXX_*_DEPLIB variables will be empty. +ifeq ($(OS),Linux) +LIBSTDCXX_NAME := libstdc++.so.6 +ifeq ($(USE_SYSTEM_CSL),1) +LIBSTDCXX_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_private_shlibdir)/$(LIBSTDCXX_NAME)) +else +LIBSTDCXX_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_shlibdir)/$(LIBSTDCXX_NAME)) +endif +LIBSTDCXX_INSTALL_DEPLIB := $(call dep_lib_path,$(libdir),$(private_shlibdir)/$(LIBSTDCXX_NAME)) +endif + + # USE_SYSTEM_LIBM and USE_SYSTEM_OPENLIBM causes it to get symlinked into build_private_shlibdir ifeq ($(USE_SYSTEM_LIBM),1) LIBM_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_private_shlibdir)/$(LIBMNAME).$(SHLIB_EXT)) @@ -1534,10 +1547,10 @@ LIBM_INSTALL_DEPLIB := $(call dep_lib_path,$(libdir),$(private_shlibdir)/$(LIBMN # That second point will no longer be true for most deps once they are placed within Artifacts directories. # Note that we prefix `libjulia-codegen` and `libjulia-internal` with `@` to signify to the loader that it # should not automatically dlopen() it in its loading loop. -LOADER_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_BUILD_DEPLIB):@$(LIBJULIACODEGEN_BUILD_DEPLIB): -LOADER_DEBUG_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_BUILD_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_BUILD_DEPLIB): -LOADER_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_INSTALL_DEPLIB): -LOADER_DEBUG_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_INSTALL_DEPLIB): +LOADER_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBSTDCXX_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_BUILD_DEPLIB):@$(LIBJULIACODEGEN_BUILD_DEPLIB): +LOADER_DEBUG_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBSTDCXX_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_BUILD_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_BUILD_DEPLIB): +LOADER_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBSTDCXX_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_INSTALL_DEPLIB): +LOADER_DEBUG_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBSTDCXX_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_INSTALL_DEPLIB): # Colors for make ifndef VERBOSE diff --git a/Makefile b/Makefile index c31517c4f1e3a..68185e49ba57b 100644 --- a/Makefile +++ b/Makefile @@ -412,12 +412,6 @@ ifeq ($(OS), Linux) -$(PATCHELF) --set-rpath '$$ORIGIN' $(DESTDIR)$(private_shlibdir)/libLLVM.$(SHLIB_EXT) endif - # Replace libstdc++ path, which is also moving from `lib` to `../lib/julia`. -ifeq ($(OS),Linux) - $(call stringreplace,$(DESTDIR)$(shlibdir)/libjulia.$(JL_MAJOR_MINOR_SHLIB_EXT),\*libstdc++\.so\.6$$,*$(call dep_lib_path,$(shlibdir),$(private_shlibdir)/libstdc++.so.6)) -endif - - ifneq ($(LOADER_BUILD_DEP_LIBS),$(LOADER_INSTALL_DEP_LIBS)) # Next, overwrite relative path to libjulia-internal in our loader if $$(LOADER_BUILD_DEP_LIBS) != $$(LOADER_INSTALL_DEP_LIBS) ifeq ($(JULIA_BUILD_MODE),release) diff --git a/cli/loader_lib.c b/cli/loader_lib.c index 3fed0c794a900..11448583a7992 100644 --- a/cli/loader_lib.c +++ b/cli/loader_lib.c @@ -366,6 +366,50 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) { void *cxx_handle; + // We keep track of "special" libraries names (ones whose name is prefixed with `@`) + // which are libraries that we want to load in some special, custom way. + // The current list is: + // special_library_names = { + // libstdc++, + // libjulia-internal, + // libjulia-codegen, + // } + int special_idx = 0; + char * special_library_names[3] = {NULL}; + while (1) { + // try to find next colon character; if we can't, break out + char * colon = strchr(curr_dep, ':'); + if (colon == NULL) + break; + + // If this library name starts with `@`, don't open it here (but mark it as special) + if (curr_dep[0] == '@') { + if (special_idx > sizeof(special_library_names)/sizeof(char *)) { + jl_loader_print_stderr("ERROR: Too many special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n"); + exit(1); + } + special_library_names[special_idx] = curr_dep + 1; + special_idx += 1; + + // Chop the string at the colon so it's a valid-ending-string + *colon = '\0'; + } + + // Skip to next dep + curr_dep = colon + 1; + } + + // Assert that we have exactly the right number of special library names + if (special_idx != sizeof(special_library_names)/sizeof(char *)) { + jl_loader_print_stderr("ERROR: Too few special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n"); + exit(1); + } + + // Unpack our special library names. This is why ordering of library names matters. + char * bundled_libstdcxx_path = special_library_names[0]; + libjulia_internal = load_library(special_library_names[1], lib_dir, 1); + void *libjulia_codegen = load_library(special_library_names[2], lib_dir, 0); + #if defined(_OS_LINUX_) int do_probe = 1; int done_probe = 0; @@ -391,16 +435,10 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) { } } if (!done_probe) { - const static char bundled_path[256] = "\0*libstdc++.so.6"; - load_library(&bundled_path[2], lib_dir, 1); + load_library(bundled_libstdcxx_path, lib_dir, 1); } #endif - // We keep track of "special" libraries names (ones whose name is prefixed with `@`) - // which are libraries that we want to load in some special, custom way, such as - // `libjulia-internal` or `libjulia-codegen`. - int special_idx = 0; - char * special_library_names[2] = {NULL}; while (1) { // try to find next colon character; if we can't, break out char * colon = strchr(curr_dep, ':'); @@ -410,16 +448,8 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) { // Chop the string at the colon so it's a valid-ending-string *colon = '\0'; - // If this library name starts with `@`, don't open it here (but mark it as special) - if (curr_dep[0] == '@') { - if (special_idx > sizeof(special_library_names)/sizeof(char *)) { - jl_loader_print_stderr("ERROR: Too many special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n"); - exit(1); - } - special_library_names[special_idx] = curr_dep + 1; - special_idx += 1; - } - else { + // If this library name starts with `@`, don't open it here + if (curr_dep[0] != '@') { load_library(curr_dep, lib_dir, 1); } @@ -427,14 +457,6 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) { curr_dep = colon + 1; } - if (special_idx != sizeof(special_library_names)/sizeof(char *)) { - jl_loader_print_stderr("ERROR: Too few special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n"); - exit(1); - } - - // Unpack our special library names. This is why ordering of library names matters. - libjulia_internal = load_library(special_library_names[0], lib_dir, 1); - void *libjulia_codegen = load_library(special_library_names[1], lib_dir, 0); const char * const * codegen_func_names; const char *codegen_liberr; if (libjulia_codegen == NULL) {