CentOS: Using GCC 4.7 from devtoolset results in l

2020-06-16 05:33发布

问题:

I am using the devtoolset-1.0 for CentOS 6.3 in order to upgrade temporarily the GCC version. Although I am now able to compile my C++ application, the final binary is missing some symbols:

$ ldd -d -r myapp
$     [..]
$     libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003216e00000)
$     [..]
$ undefined symbol: _ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_    (./myapp)
$ undefined symbol: _ZNSt8__detail15_List_node_base7_M_hookEPS0_      (./myapp)
$ undefined symbol: _ZNSt8__detail15_List_node_base9_M_unhookEv (./myapp)

I figured out, that these are some new functions, which aren't found in the 'old' libstdc++, but in a newer libstdc++. On my system, both libstdc++ (default version 4.4.7) and devtoolset-1.0-libstdc++-devel (4.7 via devtoolset) are installed. Interestingly, the libstdc++ from devtoolset links agains to the old one:

$ cat /opt/centos/devtoolset-1.0/root/usr/lib/gcc/x86_64-redhat-linux/4.7.0/libstdc++.so
$ /* GNU ld script
$    Use the shared library, but some functions are only in
$    the static library, so try that secondarily.  */
$ OUTPUT_FORMAT(elf64-x86-64)
$ INPUT ( /usr/lib64/libstdc++.so.6 -lstdc++_nonshared )

What I actually want is to replace the libstdc++ binding, but I don't know how to achieve that. I already tried to set LD_LIBRARY_PATH and pointing to the devtoolset directory, but the libstdc++ was still set to the old location. Also a symbolic link did not result in a success, because it is a ld script and not actual shared library.

回答1:

the final binary is missing some symbols

That looks like a bug in devtoolset-1-gcc, which I assume has been fixed in more recent versions of devtoolset.

Interestingly, the libstdc++ from devtoolset links agains to the old one:

Yes, that's how the devtoolset gcc is supposed to work (see this answer for more details).

What I actually want is to replace the libstdc++ binding, but I don't know how to achieve that.

You can't do that with the devtoolset of GCC, because it doesn't even have a new libstdc++.so library. As you found, that file is actually a linker script, which links your binary to libstdc++_nonshared.a /usr/lib64/libstdc++.so

Since there is no new libstdc++.so you can't link to it.



回答2:

The GCC compiler and its libraries (very specially g++ and corresponding libstdc++ runtime) need to match. Compiling with a newer compiler will (very often, practically guaranteed if a new version of the language is supported) give binaries that don't work with an older library. Older binaries might work with a newer library, no guarantees here.