Relationship between GLIBCXX(libstdc++.so.6) and gcc version - c++

[Situation]
I'm developing a c++ library. I had a issue with the GLIBCXX version.
Before, I developed on version machine GLIBCXX_3.4.22.
But my library is not working on the target machine which has GLIBCXX_3.4.19.
So, I downgraded gcc version from 5.2.x to 4.8.x and GLIBCXX version from 3.4.22 to 3.4.19.
It successfully ran on the target machine.
But my development machine(ubuntu) boot fails because other libraries can't find GLIBCXX 3.4.22 version which is already linked to that version.
So, I re-installed GLIBCXX 3.4.22 but gcc version is still 4.8.5.
[Question]
Does my library compiled on gcc-4.8.5 not use GLIBCXX_3.4.22 version? Is it fine to develop on this environment (gcc 4.8.5, GLIBCXX_3.4.22)?
What is the relationship between gcc(compile) version and GLIBCXX(GLIBC) version on the linux machine.
Where can I check the correct version compatibility mapping information between gcc and GLIBCXX(GLIBC)?

libstdc++ (which is where the GLIBCXX_* versioned symbols are from) has been ABI compatible from GCC 3.4.0 to now.
Your library will use the latest symbol versions from libstdc++ at the time of compile. The compiler version does not matter, except
GCC 5.1 added C++11 support with a "dual ABI" in libstdc++. Code compiled in C++11 mode will use symbols with the [abi:cxx11] tag, and that may not interoperate with code compiled without C++11 (whether from an older compiler without C++11 support, or a newer compiler set to use an older standard).
https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
If you need to build binaries that run on older systems, I would recommend setting up an older distribution inside a container and building in there, with all old libraries. This way, nothing newer from your development system can leak into them.

Related

Who determine GLIBCXX_version when build a binary using g++?

I am building an self-made shared library using G++ 4.9.3 on Centos 6.8.
This library uses boost::interprocess::file_lock and version of boost is 1.41.0.
I am not working on multiple environment.. I just use a device and I've never changed build environment after I built the library.
When I build library, g++ build it well. But when I run it by linking with an binary, it shows
"./a.out: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./libmylib.so)".
So, I checked which versions supported by the libstdc++ and it show it doesn't support GLIBCXX upper than 3.4.13.
GLIBCXX_3.4.13 is the latest version of /usr/lib64/libstdc++.so.6 supports.
Even though I am working on a device and its libstdc++ doesn't support GLIBCXX_3.4.15, the library build from my device requires GLIBCXX_3.4.15.
And another binaries doesn't require GLIBCXX_3.4.15 even if I use same compiler(g++4.9.3). They just work well.
How can the library notice it should use GLIBCXX_3.4.15?
Is it differed by source code?
Does compiler tell the library such as "you require to use GLIBCXX_3.4.15 because you use some special grammar in your code"?
I want know who determine which version of GLIBCXX to use for a binary.
It depends on the version of GCC, the compiler flags, and the source code. Symbols such as GLIBCXX_3.4.15 are only referenced if a specific feature is used in a program. The list of features for this particular symbol version is rather large. You can get a sense of what features are relevant using this command (which you have to run against the newer libstdc++, i.e. the one that comes with GCC 4.9):
$ readelf -sW libstdc++.so.6 | awk '/#GLIBCXX_3.4.15/{print $8}' \
| sort -u \
| c++filt
If you want to run your program with the unmodified libstdc++.so.6 version that comes with Red Hat Enterprise Linux or CentOS, you can use Developer Toolset (which is also available as a supported part of Red Hat Enterprise Linux. Developer Toolset avoids dependencies on newer symbol versions by using the old (C++98 era) C++ ABI and providing statically linked copies of functions which are not part of the system libstdc++ version for the particular target operating system version.

New version of g++ with an older version of libstdc++

I am running Linux CentOS 7.3 which comes with g++ 4.8.5. I would like to use g++ 7.1.0 to compile some C++ software. But the C++ program compiled with g++ 7.1.0 is using the headers from the standard library that comes with g++ 7.1.0 and the libstdc++.so which also comes with it which make things really painful.
Is there a way to use g++ 7.1.0 and still use the standard library (both headers and libstdc++.so) from g++ 4.8.5 installed with CentOS?
Is there a way to use g++ 7.1.0 and still use the standard library (both headers and libstdc++.so) from g++ 4.8.5 installed with CentOS?
Don't do that (the ABI of libstdc++ from GCC 4.8 & GCC 7 are likely to be different). Instead consider perhaps linking the C++ standard library (from GCC 7.1) statically (and other libraries dynamically, notably those in C including libc.so, not C++).
BTW, how did you get  g++-7.1? You could consider compiling GCC 7 (from its source code) on your CentOS 7 (or get some packaged version of it), then you'll have the right libstdc++
Read more about shared libraries, e.g. read Drepper's paper How To Write Shared Libraries and learn more about the -rpath option passed to ld (often using -Wl,-rpath to g++).
The libstdc++ ABI changed between gcc4 and gcc5 so that's not going to work. If you are using gcc7 you should install libstdc++ 7. You can have both versions installed at the same time
Developer Toolset is designed for this scenario, but it is currently at GCC version 6:
https://www.softwarecollections.org/en/scls/rhscl/devtoolset-6/
Its C++ compiler has been configured in such a way that the programs it compiles are linked dynamically against the system libstdc++, using a backwards-compatible ABI, and only the library code for new C++ features not yet supported by the system library is linked statically. This gives maximum compatibility and allows compiled applications to run without DTS.

How to safely deploy an application built with an upgraded compiler

I have an application that is deployed on a centos 6.7 plateform and built with the native C++ compiler of the distribution, that is gcc 4.4.7. Now for some reasons ( actually, upgrade to Qt 5.7 ), i need to use a modern compiler with C++11 features fully supported, let's say gcc 4.8.2 from devtoolset-2. Another possibility was to built a new version of gcc from the sources. According to https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html the 4.8.3 (but 4.8.2 is not mentionned ) version of gcc is backward compatible with the libstdc++.6.0.13 ( default c++ lib in centos 6.7 ).
I have recompiled the application with this new gcc 4.8.2 version and everything seems to run fine in the dev environment. The app use the default system c++, gcc and c libs.
However, when it comes to deployment on centos 6.7 ( after a fresh install for example ) i ask myself how safe it is to do so ? Instead on relying on ABI compatibility , would it be better to provide the latest C++ and C libraries that are compatible with the version of gcc that was used to build my app ?
Nice to see someone else doing this - I recently started doing it too!
My answer is not very authoritative, but for what it's worth, I rebuild all C++ libraries that I'll be linking against, and deploy those with my application. I also redistribute libstdc++ and libgcc_s, putting them in a special place out of the way (/usr/lib/myApplicationName/...). I ensure that my application links against all of these redistributed libraries instead of whatever's native.
I had a concern that libc compatibility might be a problem, but I haven't found that I need to do anything about any C libraries, or with libc itself.
Update: Turns out I didn't even need to do this, because I'm using devtoolset; FML.

Pyinstaller GLIBC_2.15 not found

Generated an executable on Linux 32-bit Ubuntu 11 and tested it on a 32-bit Ubuntu 10 and it failed with a "GLIBC_2.15" not found.
Cyrhon FAQ section says:
Under Linux, I get runtime dynamic linker errors, related to libc. What should I do? The executable that PyInstaller builds is not
fully static, in that it still depends on the system libc. Under
Linux, the ABI of GLIBC is backward compatible, but not forward
compatible. So if you link against a newer GLIBC, you can't run the
resulting executable on an older system. The supplied binary
bootloader should work with older GLIBC. However, the libpython.so and
other dynamic libraries still depends on the newer GLIBC. The solution
is to compile the Python interpreter with its modules (and also
probably bootloader) on the oldest system you have around, so that it
gets linked with the oldest version of GLIBC.
and
How to get recent Python environment working on old Linux distribution? The issue is that Python and its modules has to be
compiled against older GLIBC. Another issue is that you probably want
to use latest Python features and on old Linux distributions there is
only available really old Python version (e.g. on Centos 5 is
available Python 2.4).

Can I target older linux with newer gcc/clang? C++

Right now I compile my C++ software on a certain old version of linux (SLED 10) using the provided gcc and it can run on most newer versions as they have a newer glibc. Problem is, that old gcc doesn't support C++11 and I'd really like to use the new features.
Now I have some ideas, but I'm sure others have the same need. What's actually worked for you?
Ideas:
Build on a newer system, static link to newer glibc. (Not possible, right?)
Build on a newer system, compile and link against an older glibc.
Build on an older system using an updated gcc, link against older glibc.
Build on a newer system, dynamic link to newer glibc, set RPath and provide our glibc with installer.
As a bonus, my software also support plugins and has an SDK. I'd really prefer that my customers could compile against my libraries without a huge hassle.
Thanks in advance. Ideas welcome, proven solutions preferred.
Build with the newer gcc. Either install the new compiler on the old machine or comile on your new machine and install the necessary dynamic libraries on the old machine.
Note that multiple versions of libc (and also libstdc++) are supported on a single machine since they are typically versioned (i.e. libc.so.5, libc.so.6, etc)