@@ -350,7 +350,8 @@ static char *libstdcxxprobe(void)
350350}
351351#endif
352352
353- void * libjulia_internal = NULL ;
353+ void * libjulia_internal = NULL ;
354+ void * libjulia_codegen = NULL ;
354355__attribute__((constructor )) void jl_load_libjulia_internal (void ) {
355356 // Only initialize this once
356357 if (libjulia_internal != NULL ) {
@@ -364,18 +365,14 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) {
364365 int deps_len = strlen (& dep_libs [1 ]);
365366 char * curr_dep = & dep_libs [1 ];
366367
367- void * cxx_handle ;
368-
369368 // We keep track of "special" libraries names (ones whose name is prefixed with `@`)
370369 // which are libraries that we want to load in some special, custom way.
371370 // The current list is:
372- // special_library_names = {
373- // libstdc++,
374- // libjulia-internal,
375- // libjulia-codegen,
376- // }
371+ // libstdc++
372+ // libjulia-internal
373+ // libjulia-codegen
374+ const int NUM_SPECIAL_LIBRARIES = 3 ;
377375 int special_idx = 0 ;
378- char * special_library_names [3 ] = {NULL };
379376 while (1 ) {
380377 // try to find next colon character; if we can't, break out
381378 char * colon = strchr (curr_dep , ':' );
@@ -384,61 +381,30 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) {
384381
385382 // If this library name starts with `@`, don't open it here (but mark it as special)
386383 if (curr_dep [0 ] == '@' ) {
387- if (special_idx > sizeof (special_library_names )/sizeof (char * )) {
384+ special_idx += 1 ;
385+ if (special_idx > NUM_SPECIAL_LIBRARIES ) {
388386 jl_loader_print_stderr ("ERROR: Too many special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n" );
389387 exit (1 );
390388 }
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' ;
396389 }
397390
398391 // Skip to next dep
399392 curr_dep = colon + 1 ;
400393 }
401394
402395 // Assert that we have exactly the right number of special library names
403- if (special_idx != sizeof ( special_library_names )/ sizeof ( char * ) ) {
396+ if (special_idx != NUM_SPECIAL_LIBRARIES ) {
404397 jl_loader_print_stderr ("ERROR: Too few special library names specified, check LOADER_BUILD_DEP_LIBS and friends!\n" );
405398 exit (1 );
406399 }
407400
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-
413- #if defined(_OS_LINUX_ )
414- int do_probe = 1 ;
415- int done_probe = 0 ;
416- char * probevar = getenv ("JULIA_PROBE_LIBSTDCXX" );
417- if (probevar ) {
418- if (strcmp (probevar , "1" ) == 0 || strcmp (probevar , "yes" ) == 0 )
419- do_probe = 1 ;
420- else if (strcmp (probevar , "0" ) == 0 || strcmp (probevar , "no" ) == 0 )
421- do_probe = 0 ;
422- }
423- if (do_probe ) {
424- char * cxxpath = libstdcxxprobe ();
425- if (cxxpath ) {
426- cxx_handle = dlopen (cxxpath , RTLD_LAZY );
427- char * dlr = dlerror ();
428- if (dlr ) {
429- jl_loader_print_stderr ("ERROR: Unable to dlopen(cxxpath) in parent!\n" );
430- jl_loader_print_stderr3 ("Message: " , dlr , "\n" );
431- exit (1 );
432- }
433- free (cxxpath );
434- done_probe = 1 ;
435- }
436- }
437- if (!done_probe ) {
438- load_library (bundled_libstdcxx_path , lib_dir , 1 );
439- }
440- #endif
441-
401+ // Now that we've asserted that we have the right number of special
402+ // libraries, actually run a loop over the deps loading them in-order.
403+ // If it's a special library, we do slightly different things, especially
404+ // for libstdc++, where we actually probe for a system libstdc++ and
405+ // load that if it's newer.
406+ special_idx = 0 ;
407+ curr_dep = & dep_libs [1 ];
442408 while (1 ) {
443409 // try to find next colon character; if we can't, break out
444410 char * colon = strchr (curr_dep , ':' );
@@ -448,8 +414,56 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) {
448414 // Chop the string at the colon so it's a valid-ending-string
449415 * colon = '\0' ;
450416
451- // If this library name starts with `@`, don't open it here
452- if (curr_dep [0 ] != '@' ) {
417+ // If this library name starts with `@`, it's a special library
418+ // and requires special handling:
419+ if (curr_dep [0 ] == '@' ) {
420+ // Skip the `@` for future function calls.
421+ curr_dep += 1 ;
422+
423+ // First special library to be loaded is `libstdc++`; perform probing here.
424+ if (special_idx == 0 ) {
425+ #if defined(_OS_LINUX_ )
426+ int do_probe = 1 ;
427+ int probe_successful = 0 ;
428+
429+ // Check to see if the user has disabled libstdc++ probing
430+ char * probevar = getenv ("JULIA_PROBE_LIBSTDCXX" );
431+ if (probevar ) {
432+ if (strcmp (probevar , "1" ) == 0 || strcmp (probevar , "yes" ) == 0 )
433+ do_probe = 1 ;
434+ else if (strcmp (probevar , "0" ) == 0 || strcmp (probevar , "no" ) == 0 )
435+ do_probe = 0 ;
436+ }
437+ if (do_probe ) {
438+ char * cxxpath = libstdcxxprobe ();
439+ if (cxxpath ) {
440+ void * cxx_handle = dlopen (cxxpath , RTLD_LAZY );
441+ const char * dlr = dlerror ();
442+ if (dlr ) {
443+ jl_loader_print_stderr ("ERROR: Unable to dlopen(cxxpath) in parent!\n" );
444+ jl_loader_print_stderr3 ("Message: " , dlr , "\n" );
445+ exit (1 );
446+ }
447+ free (cxxpath );
448+ probe_successful = 1 ;
449+ }
450+ }
451+ // If the probe rejected the system libstdc++ (or didn't find one!)
452+ // just load our bundled libstdc++ as identified by curr_dep;
453+ if (!probe_successful ) {
454+ load_library (curr_dep , lib_dir , 1 );
455+ }
456+ #endif
457+ } else if (special_idx == 1 ) {
458+ // This special library is `libjulia-internal`
459+ libjulia_internal = load_library (curr_dep , lib_dir , 1 );
460+ } else if (special_idx == 2 ) {
461+ // This special library is `libjulia-codegen`
462+ libjulia_codegen = load_library (curr_dep , lib_dir , 0 );
463+ }
464+ special_idx ++ ;
465+ } else {
466+ // Otherwise, just load it as "normal"
453467 load_library (curr_dep , lib_dir , 1 );
454468 }
455469
0 commit comments