@@ -30,6 +30,54 @@ function _atpyexit()
3030 return
3131end
3232
33+ # By default, ensure libstdc++ in the Conda environment is compatible with
34+ # the one linked in Julia. This is platform/version dependent, so needs to
35+ # occur at runtime.
36+ #
37+ # Allow the user to override the default. This is useful when the version
38+ # of libstdcxx linked in Julia is customized in the local installation of
39+ # Julia.
40+ #
41+ # To figure out cxx_version for a given Julia version, run
42+ # strings /path/to/julia/lib/julia/libstdc++.so.6 | grep GLIBCXX
43+ # then look at
44+ # https://gcc.gnu.org/onlinedocs/gcc-12.1.0/libstdc++/manual/manual/abi.html
45+ # for the highest GCC version compatible with the highest GLIBCXX version.
46+ function get_libstdcxx_version_bound ()
47+ # This list comes from: https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
48+ # Start with GCC 4.8, as it's extremely difficult to build Julia with anything older
49+ vers_mapping = Dict (
50+ 18 => v " 4.8.0" ,
51+ 19 => v " 4.8.3" ,
52+ 20 => v " 4.9.0" ,
53+ 21 => v " 5.1.0" ,
54+ 22 => v " 6.1.0" ,
55+ 23 => v " 7.1.0" ,
56+ 24 => v " 7.2.0" ,
57+ 25 => v " 8.1.0" ,
58+ 26 => v " 9.1.0" ,
59+ 27 => v " 9.2.0" ,
60+ 28 => v " 9.5.0" ,
61+ 29 => v " 11.3.0" ,
62+ 30 => v " 12.2.0" ,
63+ 31 => v " 13.1.0" ,
64+ )
65+ # Get the libstdcxx version that is currently loaded in this Julia process
66+ loaded_libstdcxx_version = Base. BinaryPlatforms. detect_libstdcxx_version ()
67+
68+ if loaded_libstdcxx_version != = nothing
69+ # Map it through to get a GCC version; if the version is unknown, we simply return
70+ # the highest GCC version we know about, which should be a fairly safe choice.
71+ max_version = get (vers_mapping, loaded_libstdcxx_version. patch, vers_mapping[maximum (keys (vers_mapping))])
72+ return get (ENV , " JULIA_PYTHONCALL_LIBSTDCXX_VERSION_BOUND" , " >=3.4,<=$(max_version. major) .$(max_version. minor) " )
73+ elseif haskey (ENV , " JULIA_PYTHONCALL_LIBSTDCXX_VERSION_BOUND" )
74+ return ENV [" JULIA_PYTHONCALL_LIBSTDCXX_VERSION_BOUND" ]
75+ else
76+ # Julia does not link against any version of libstdc++ known to Julia (e.g. using clang instead, or something not in the 3.4.x series)
77+ return nothing
78+ end
79+ end
80+
3381function init_context ()
3482
3583 CTX. is_embedded = haskey (ENV , " JULIA_PYTHONCALL_LIBPTR" )
@@ -60,24 +108,12 @@ function init_context()
60108 exe_path:: String
61109 else
62110 if Sys. islinux ()
63- # Ensure libstdc++ in the Conda environment is compatible with the one
64- # linked in Julia. This is platform/version dependent, so needs to occur at
65- # runtime.
66- #
67- # To figure out cxx_version for a given Julia version, run
68- # strings /path/to/julia/lib/julia/libstdc++.so.6 | grep GLIBCXX
69- # then look at
70- # https://gcc.gnu.org/onlinedocs/gcc-12.1.0/libstdc++/manual/manual/abi.html
71- # for the highest GCC version compatible with the highest GLIBCXX version.
72- if Base. VERSION <= v " 1.6.2"
73- # GLIBCXX_3.4.26
74- cxx_version = " >=3.4,<9.2"
75- else
76- # GLIBCXX_3.4.29
77- # checked up to v1.8.0
78- cxx_version = " >=3.4,<11.4"
111+ cxx_version = get_libstdcxx_version_bound ()
112+ if cxx_version != = nothing
113+ CondaPkg. add (" libstdcxx-ng" , version= cxx_version, channel= " conda-forge" , temp= true , file= joinpath (@__DIR__ , " .." , " .." , " CondaPkg.toml" ), resolve= false )
79114 end
80- CondaPkg. add (" libstdcxx-ng" , version= cxx_version, channel= " conda-forge" , temp= true , file= joinpath (@__DIR__ , " .." , " .." , " CondaPkg.toml" ), resolve= false )
115+ # if cxx_version is nothing, then we assume that Julia does not link against any version ob libstdc++ known by Julia, and so we do not
116+ # enforce a version bound.
81117 end
82118 # By default, we use Python installed by CondaPkg.
83119 exe_path = Sys. iswindows () ? joinpath (CondaPkg. envdir (), " python.exe" ) : joinpath (CondaPkg. envdir (), " bin" , " python" )
0 commit comments