-O2 requires GLIBCXX_3.4.9?

Hi All,

Why does compiling with -O2 force the resulting binary to require GLIBCXX_3.4.9?

I need to run my binaries on this machine and when I compile with -O0 it seems
to work fine.

$ uname -a
Linux itrsrh.ldn.itrs 2.6.18-238.9.1.el5 #1 SMP Tue Apr 12 18:10:56 EDT 2011
i686 i686 i386 GNU/Linux
$ lsb_release -a
LSB Version: :core-4.0-ia32:core-4.0-noarch:graphics-4.0-ia32:graphics-4.0-
noarch:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 5.6 (Final)
Release: 5.6
Codename: Final

Any clues?

-Mohamed

Compile Log:

[dev@localhost clang]$ clang++ --version
clang version 3.1 (branches/release_31)
Target: i386-pc-linux-gnu
Thread model: posix
[dev@localhost clang]$ uname -a
Linux localhost.localdomain 2.6.18-308.11.1.el5PAE #1 SMP Tue Jul 10 09:29:33
EDT 2012 i686 i686 i386 GNU/Linux
[dev@localhost clang]$ lsb_release -a
LSB Version: :core-4.0-ia32:core-4.0-noarch:graphics-4.0-ia32:graphics-4.0-
noarch:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 5.8 (Final)
Release: 5.8
Codename: Final
[dev@localhost clang]$ clang++ -O2 -g -faddress-sanitizer -fno-omit-frame-
pointer -fno-inline -fstack-protector-all -fcatch-undefined-behavior -fno-limit-
debug-info test.cpp -o test_opts.o
[dev@localhost clang]$ ldd test_opts.o
        linux-gate.so.1 => (0x00b1e000)
        libstdc++.so.6 => /opt/gcc-4.4.6_install/lib/libstdc++.so.6 (0x002d1000)
        libm.so.6 => /lib/libm.so.6 (0x008e8000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x0092f000)
        libdl.so.2 => /lib/libdl.so.2 (0x00913000)
        libgcc_s.so.1 => /opt/gcc-4.4.6_install/lib/libgcc_s.so.1 (0x0029a000)
        libc.so.6 => /lib/libc.so.6 (0x0078d000)
        /lib/ld-linux.so.2 (0x00769000)
[dev@localhost clang]$ strings test_opts.o | grep GLIBC
GLIBC_2.0
GLIBC_2.2.3
GLIBC_2.2
GLIBCXX_3.4.9
GLIBCXX_3.4.11
GLIBCXX_3.4
GLIBC_2.4
GLIBC_2.1.3
[dev@localhost clang]$ clang++ -O0 -g -faddress-sanitizer -fno-omit-frame-
pointer -fno-inline -fstack-protector-all -fcatch-undefined-behavior -fno-limit-
debug-info test.cpp -o test_no-opt.o
[dev@localhost clang]$ ldd test_no-opt.o
        linux-gate.so.1 => (0x00229000)
        libstdc++.so.6 => /opt/gcc-4.4.6_install/lib/libstdc++.so.6 (0x00791000)
        libm.so.6 => /lib/libm.so.6 (0x008e8000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x0092f000)
        libdl.so.2 => /lib/libdl.so.2 (0x00913000)
        libgcc_s.so.1 => /opt/gcc-4.4.6_install/lib/libgcc_s.so.1 (0x00110000)
        libc.so.6 => /lib/libc.so.6 (0x0022a000)
        /lib/ld-linux.so.2 (0x00769000)
[dev@localhost clang]$ strings test_no-opt.o | grep GLIBC
GLIBC_2.0
GLIBC_2.2.3
GLIBC_2.2
GLIBCXX_3.4
GLIBC_2.4
GLIBC_2.1.3

Because -O2 enables certain compiler options that require a certain glibc version.

glibc is generally not backwards compatible. You cannot build on a new version and have a guarantee that it runs on older ones. If you want that, you should build against an older glibc.

Nikos Chantziaras <realnc@...> writes:

glibc is generally not backwards compatible. You cannot build on a new
version and have a guarantee that it runs on older ones. If you want
that, you should build against an older glibc.

Does anyone know how to solve this issue? I just need to it use the same glibc
that is being used when -O0 is specified.

-Mohamed

You are using the same glibc in both cases actually. Just with different internal defines.

Konstantin, hi,

So why can’t I run it on a system with an older version of glibc? This very confusing. Clearly, -O2 wants a newer version of glibc.

—Mohamed

glibc version compatibility is based on supported features. What that means is that -O0 does not depend on features not available on the older glibc. -O2 does, and the features it needs are not available on the older version.

In other words, the binary doesn't really say "I need version x.y.z of glibc", it rather says "I want this glibc to support features foo, bar and baz." If one of those features are not available, you get an error indicating the version of glibc that's required for those features to work.

So why can't I run it on a system with an older version of glibc? This very
confusing. Clearly, -O2 wants a newer version of glibc.

There's a good chance you will be able to run it if you make the
dynamic loader use the glibc you were linking against. In your case it
looks like that's in /opt/gcc-4.4.6_install/lib so this might work:

$ LD_LIBRARY_PATH=/opt/gcc-4.4.6_install/lib ./my_program

Other than that you'll have to convince clang to use the libraries and
headers in /usr during compilation. Some combination of --sysroot and
-gcc-toolchain options has a good chance of working, but I'm not sure
how to bake that knowledge into clang at build-time (it probably
depends on whether you're using CMake or autotools).

Tim.