Skip to content

Commit dd612d2

Browse files
committed
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] #46976 [1] https://github.com/JuliaLang/julia/pull/46976/files#diff-8c5c98f26f3f7aac8905a1074c5bec11a57e9b9c7c556791deac5a3b27cc096fR379 [2] https://github.com/JuliaLang/julia/blob/master/Makefile#L430
1 parent 31b12a6 commit dd612d2

File tree

3 files changed

+64
-35
lines changed

3 files changed

+64
-35
lines changed

Make.inc

+17-4
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,19 @@ LIBGCC_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_shlibdir)/$(L
15121512
endif
15131513
LIBGCC_INSTALL_DEPLIB := $(call dep_lib_path,$(libdir),$(private_shlibdir)/$(LIBGCC_NAME))
15141514

1515+
# We only bother to define this on Linux, as that's the only platform that does libstdc++ probing
1516+
# On all other platforms, the LIBSTDCXX_*_DEPLIB variables will be empty.
1517+
ifeq ($(OS),Linux)
1518+
LIBSTDCXX_NAME := libstdc++.so.6
1519+
ifeq ($(USE_SYSTEM_CSL),1)
1520+
LIBSTDCXX_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_private_shlibdir)/$(LIBSTDCXX_NAME))
1521+
else
1522+
LIBSTDCXX_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_shlibdir)/$(LIBSTDCXX_NAME))
1523+
endif
1524+
LIBSTDCXX_INSTALL_DEPLIB := $(call dep_lib_path,$(libdir),$(private_shlibdir)/$(LIBSTDCXX_NAME))
1525+
endif
1526+
1527+
15151528
# USE_SYSTEM_LIBM and USE_SYSTEM_OPENLIBM causes it to get symlinked into build_private_shlibdir
15161529
ifeq ($(USE_SYSTEM_LIBM),1)
15171530
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
15341547
# That second point will no longer be true for most deps once they are placed within Artifacts directories.
15351548
# Note that we prefix `libjulia-codegen` and `libjulia-internal` with `@` to signify to the loader that it
15361549
# should not automatically dlopen() it in its loading loop.
1537-
LOADER_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_BUILD_DEPLIB):@$(LIBJULIACODEGEN_BUILD_DEPLIB):
1538-
LOADER_DEBUG_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_BUILD_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_BUILD_DEPLIB):
1539-
LOADER_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_INSTALL_DEPLIB):
1540-
LOADER_DEBUG_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_INSTALL_DEPLIB):
1550+
LOADER_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBSTDCXX_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_BUILD_DEPLIB):@$(LIBJULIACODEGEN_BUILD_DEPLIB):
1551+
LOADER_DEBUG_BUILD_DEP_LIBS = $(LIBGCC_BUILD_DEPLIB):$(LIBM_BUILD_DEPLIB):@$(LIBSTDCXX_BUILD_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_BUILD_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_BUILD_DEPLIB):
1552+
LOADER_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBSTDCXX_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_INSTALL_DEPLIB):
1553+
LOADER_DEBUG_INSTALL_DEP_LIBS = $(LIBGCC_INSTALL_DEPLIB):$(LIBM_INSTALL_DEPLIB):@$(LIBSTDCXX_INSTALL_DEPLIB):@$(LIBJULIAINTERNAL_DEBUG_INSTALL_DEPLIB):@$(LIBJULIACODEGEN_DEBUG_INSTALL_DEPLIB):
15411554

15421555
# Colors for make
15431556
ifndef VERBOSE

Makefile

-6
Original file line numberDiff line numberDiff line change
@@ -412,12 +412,6 @@ ifeq ($(OS), Linux)
412412
-$(PATCHELF) --set-rpath '$$ORIGIN' $(DESTDIR)$(private_shlibdir)/libLLVM.$(SHLIB_EXT)
413413
endif
414414

415-
# Replace libstdc++ path, which is also moving from `lib` to `../lib/julia`.
416-
ifeq ($(OS),Linux)
417-
$(call stringreplace,$(DESTDIR)$(shlibdir)/libjulia.$(JL_MAJOR_MINOR_SHLIB_EXT),\*libstdc++\.so\.6$$,*$(call dep_lib_path,$(shlibdir),$(private_shlibdir)/libstdc++.so.6))
418-
endif
419-
420-
421415
ifneq ($(LOADER_BUILD_DEP_LIBS),$(LOADER_INSTALL_DEP_LIBS))
422416
# Next, overwrite relative path to libjulia-internal in our loader if $$(LOADER_BUILD_DEP_LIBS) != $$(LOADER_INSTALL_DEP_LIBS)
423417
ifeq ($(JULIA_BUILD_MODE),release)

cli/loader_lib.c

+47-25
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,50 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) {
366366

367367
void *cxx_handle;
368368

369+
// We keep track of "special" libraries names (ones whose name is prefixed with `@`)
370+
// which are libraries that we want to load in some special, custom way.
371+
// The current list is:
372+
// special_library_names = {
373+
// libstdc++,
374+
// libjulia-internal,
375+
// libjulia-codegen,
376+
// }
377+
int special_idx = 0;
378+
char * special_library_names[3] = {NULL};
379+
while (1) {
380+
// try to find next colon character; if we can't, break out
381+
char * colon = strchr(curr_dep, ':');
382+
if (colon == NULL)
383+
break;
384+
385+
// If this library name starts with `@`, don't open it here (but mark it as special)
386+
if (curr_dep[0] == '@') {
387+
if (special_idx > sizeof(special_library_names)/sizeof(char *)) {
388+
jl_loader_print_stderr("ERROR: Too many special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n");
389+
exit(1);
390+
}
391+
special_library_names[special_idx] = curr_dep + 1;
392+
special_idx += 1;
393+
394+
// Chop the string at the colon so it's a valid-ending-string
395+
*colon = '\0';
396+
}
397+
398+
// Skip to next dep
399+
curr_dep = colon + 1;
400+
}
401+
402+
// Assert that we have exactly the right number of special library names
403+
if (special_idx != sizeof(special_library_names)/sizeof(char *)) {
404+
jl_loader_print_stderr("ERROR: Too few special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n");
405+
exit(1);
406+
}
407+
408+
// Unpack our special library names. This is why ordering of library names matters.
409+
char * bundled_libstdcxx_path = special_library_names[0];
410+
libjulia_internal = load_library(special_library_names[1], lib_dir, 1);
411+
void *libjulia_codegen = load_library(special_library_names[2], lib_dir, 0);
412+
369413
#if defined(_OS_LINUX_)
370414
int do_probe = 1;
371415
int done_probe = 0;
@@ -391,16 +435,10 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) {
391435
}
392436
}
393437
if (!done_probe) {
394-
const static char bundled_path[256] = "\0*libstdc++.so.6";
395-
load_library(&bundled_path[2], lib_dir, 1);
438+
load_library(bundled_libstdcxx_path, lib_dir, 1);
396439
}
397440
#endif
398441

399-
// We keep track of "special" libraries names (ones whose name is prefixed with `@`)
400-
// which are libraries that we want to load in some special, custom way, such as
401-
// `libjulia-internal` or `libjulia-codegen`.
402-
int special_idx = 0;
403-
char * special_library_names[2] = {NULL};
404442
while (1) {
405443
// try to find next colon character; if we can't, break out
406444
char * colon = strchr(curr_dep, ':');
@@ -410,31 +448,15 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) {
410448
// Chop the string at the colon so it's a valid-ending-string
411449
*colon = '\0';
412450

413-
// If this library name starts with `@`, don't open it here (but mark it as special)
414-
if (curr_dep[0] == '@') {
415-
if (special_idx > sizeof(special_library_names)/sizeof(char *)) {
416-
jl_loader_print_stderr("ERROR: Too many special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n");
417-
exit(1);
418-
}
419-
special_library_names[special_idx] = curr_dep + 1;
420-
special_idx += 1;
421-
}
422-
else {
451+
// If this library name starts with `@`, don't open it here
452+
if (curr_dep[0] != '@') {
423453
load_library(curr_dep, lib_dir, 1);
424454
}
425455

426456
// Skip ahead to next dependency
427457
curr_dep = colon + 1;
428458
}
429459

430-
if (special_idx != sizeof(special_library_names)/sizeof(char *)) {
431-
jl_loader_print_stderr("ERROR: Too few special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n");
432-
exit(1);
433-
}
434-
435-
// Unpack our special library names. This is why ordering of library names matters.
436-
libjulia_internal = load_library(special_library_names[0], lib_dir, 1);
437-
void *libjulia_codegen = load_library(special_library_names[1], lib_dir, 0);
438460
const char * const * codegen_func_names;
439461
const char *codegen_liberr;
440462
if (libjulia_codegen == NULL) {

0 commit comments

Comments
 (0)