I am building a shared library on Linux, which serves as a "plugin" to some software (to be specific, it extends Mathematica).
I find that if I build on Ubuntu 16.04, the resulting library does not work on RHEL 7.6. However, if I build on RHEL 7.6, the library works both on RHEL and Ubuntu.
By "does not work", I mean that Mathematica refuses to load it, but it only gives a generic and unuseful "failed to load" error message.
I have eliminated a number of factors that could break compatibility, and I cannot find any more. This question is about what else might affect compatibility than what I list below.
The library is written in a mix of C and C++, but it exports a C interface. It is built with -static-libstdc++
and -static-libgcc
. If I use ldd
on the .so
file, the only dependencies it lists are:
linux-vdso.so.1 => (0x00007ffc757b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa286e62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa287854000)
One potential source of incompatibility is the glibc
version. I looked at the symbols in the library using nm -gC
, and the highest GLIBC version reference I see when I build on Ubuntu is 2.14. RHEL 7.6 has glibc 2.17, i.e. newer than 2.14. Thus I do not believe that the incompatibility is due to glibc.
What else is there that can cause a shared object compiled on Ubuntu 16.04 not to load on RHEL 7.6?
Update: I managed to coax Mathematica to give a more descriptive error (it was a not very well documented feature), so I have a concrete error message. The same could also be seen with @Ctx's suggestion to set LD_DEBUG=all
.
The error is:
IGraphM.so: undefined symbol: _ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE
(IGraphM.so
is my library.)
This function would seem to be part of libstdc++ unless I am mistaken. Why does this error occur if I specified -static-libstdc++
and verified that ldd
does not list libstdc++?
Update 2:
Per the advice by SergeyA and this QA, I compiled after defining _GLIBCXX_USE_CXX11_ABI=0
. This does fix the incompatibility.
But I still do not understand why. The error message complains about a missing symbol. Where is this symbol normally loaded from? I was under the impression that if I use -static-libstdc++
, then it should be contained within my library. This seems to be wrong.
While I seem to have a practical solution for the incompatibility for this specific case, I would appreciate some explanations so in the future I can solve similar problems on my own.