Issue
I want to understand what's happening under the hood when using a newer GCC than the "default" version for a given version of Ubuntu.
- Starting with a plain Ubuntu 18.04, I have:
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
- Then I install gcc-11 (via the toolchains/test ppa repo) and I get:
/usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so
I also notice that the system-provided version gets overriden!
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.29
- I can compile a hello-world application with
g++-11
, and get the following vialdd
:
ldd a.out
linux-vdso.so.1 (0x00007ffc79ff7000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd378546000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd378155000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd377db7000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd378b55000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd377b9f000)
So it's linking to the system-installed version of libstdc++
, instead of the compiler-provided version. The binary runs just fine.
My questions are:
- Is this expected to work or I'm just lucky with my tiny example? What can possibly go wrong?
- Why is the system-provided library overriden? With what?
- If there's a build of GCC-11 for Ubuntu 18.04, does it mean it's guaranteed to work in Ubuntu 18.04?
- In what way do the two libstdc++ libraries (system-provided and gcc-11-provided) differ?
- What about other libraries, like libgcc_s.so? The same happens, there's the "system" provided one, and the "GCC-provided" one.
- Do I need to worry about the remaining libs that are present in ldd? (libc, libm, linux-vsdo). It seems there's only one version in the system, but I wonder if they get overriden when installing GCC.
Thanks!
Solution
After all the great info I got from the comments, I think I got a good enough understanding to answer the question. Thanks everyone!
If the
libstdc++
has the same major version (the one in the SONAME), then they are backwards-compatible. Meaning that something built on a olderlibstdc++
is guaranteed to run on a newerlibstdc++
.The opposite is not true in general - the library is not forward-compatible. If a new symbol is introduced in a new library, it naturally doesn't exist in the older library. This can be reproduced as follows:
Start on Ubuntu 20.04.
Copy the example code from here.
Compile it with the default GCC 9 and
-std=c++17
.This binary runs fine on Ubuntu 20.04.
Now, copy that binary over to a stock Ubuntu 18.04.
You'll get a "symbol not found error":
./a.out: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./a.out)
- When you install a new GCC on Ubuntu, it will override the system-wide libstdc++ (possibly other libs?) with the GCC-provided
libstdc++
(so they are identical). This will ensure that whatever you build on that machine will also run there.
Answered By - user1011113