GLIBCXX version not found

Hi, I have a shared C library I compiled myself. When trying to ccall in Julia, it throws the following error:

julia> ccall((:test, "./<...>.so"), Cvoid, ())
ERROR: could not load library "./<...>.so"
/home/redacted/Applications/julia-1.8.0-beta3/bin/../lib/julia/libstdc++.so.6: 
version `GLIBCXX_3.4.30' not found (required by /home/redact/Workspace/<...>/build/<...>.so)

Calling strings ~/Applications/julia-1.8.0-beta3/lib/julia/libstdc++.so | grep GLIBCXX_3.4. indeed confirms that the highest GLIBCXX available to julia is GLIBCCXX_3.4.29, not 30.

On my own system I can obviously just copy my systems libstdc++.so into Julias folder, which fixes the error. However, most of my users willl be using a shipped-with-julia libstdc++.so library that may be even older than 3.4.29.

What is the accepted way of addressing this without modifying the local Julia library folder? How can I tell Julia to use a newer one?

I’m (slowly) working on it.

2 Likes

Side note

I doubt it’s pure C if you have GLIBCXX symbols.

I have a similar problem when importing some Python packages via PyCall that use their own binaries which are linked to a different libstdc++ version. The underlying issue seems to be tied to the fact that Julia always loads its own libstdc++ library on startup which might be older than binaries coming from another source expect it to be.

Can you elaborate a little more on how you plan to solve this?

1 Like

We have to update our libstdc++ which is ongoing work. :slight_smile:

As a shorter-term fix (that doesn’t require updating Julia), one can try to arrange the python libraries they use to use the same gcc version as Julia was compiled with. If you are using CondaPkg on Linux, this looks like

if VERSION <= v"1.6.2"
    # GLIBCXX_3.4.26
    cxx_version = ">=3.4,<9.2"
else
    # GLIBCXX_3.4.29
    cxx_version = ">=3.4,<11.4"
end

CondaPkg.add("libstdcxx-ng", version=cxx_version)

borrowing from https://github.com/cjdoris/PythonCall.jl/compare/main..cxx-compat#diff-22bffae9c7708a5fa205669c9c428ac479d0e9ea2a7ae6a867bae5a89a0f353dR55-R73. See also Add constraints from julia process into Conda version resolution (somehow?) · Issue #43 · cjdoris/CondaPkg.jl · GitHub for a discussion of how to fix this for PythonCall. Probably there’s a way to do this with PyCall as well.

Also, as discussed there, I think scipy v1.9 introduced a dependence on a later gcc version, so one can also try just making sure they are using scipy v1.8.

2 Likes

Yes, but this will force everyone to update Julia which might not be desired. I consider it unfortunate that all binary packages buried in anything that is imported into Julia will have to work with whatever binaries where shipped with Julia, even if they actually provide their own as is the case with all conda packages. However, I don’t know if this can be avoided.

Yes, this is my temporary solution to this. However, there might be thousands of these kind of issues with other conda packages. Essentially, this requires everyone using Conda within Julia to regularly update to the newest Julia version as soon as it is available and then hope that the conda binaries do not “catch up” to Julia’s too fast.

This is additionally enforced by the fact that afaik PyCall currently does not support distinct python environments which would allow more convenient pining of conda packages to specific versions.

1 Like

Yeah, I agree that always updating Julia doesn’t sound like the right fix. I think the right fix is to use whatever constraints Julia imposes on the environment in the version resolution of the python packages. That’s exactly why I filed Add constraints from julia process into Conda version resolution (somehow?) · Issue #43 · JuliaPy/CondaPkg.jl · GitHub.

Yes, I would use PythonCall instead which does.

Good advice, I will look into this!

1 Like

Indeed, if I get around to merging that branch and making a release of PythonCall, this issue should be a thing of the past - it will be silently fixed for you.

1 Like

Here is a workaround for Conda / PyCall / PyPlot (used in Plots ci), before we can transition to CondaPkg / PythonCall / PythonPlot:

1 Like