简体   繁体   中英

How to use alternate glibc with existing libstdc++?

I need to use a self-compiled version of glibc (2.18), newer than the default one on the system (2.15). I can compile&link a C++ program, but when I try to run it, I get errors about libstdc++.so.6 . (C programs seems to work just fine.) Do I need to recompile gcc against the newer glibc for this to work? Why? (Update: I figured this part out, but I have a few other questions at the bottom.)

Here is a sample C++ program:

#include <iostream>
int main()
{
    std::cout << "ok\n";
    return 0;
}

Following this answer , I compiled it with:

g++ -Wl,--rpath=/path/to/glibc-2.18/lib -Wl,--dynamic-linker=/path/to/glibc-2.18/lib/ld-2.18.so a.cpp

It compiles with no errors, then ldd says:

$ ldd a.out 
    linux-vdso.so.1 =>  (0x00007fff421fe000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3b96e7f000)
    libc.so.6 => /path/to/glibc-2.18/lib/libc.so.6 (0x00007f3b96ad1000)
    libm.so.6 => /path/to/glibc-2.18/lib/libm.so.6 (0x00007f3b967cf000)
    /path/to/glibc-2.18/lib/ld-2.18.so => /lib64/ld-linux-x86-64.so.2 (0x00007f3b9719d000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3b965b9000)

But when I try to run it:

$ ./a.out 
./a.out: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

This is confusing because it looks like ldd finds libstdc++.so.6 just fine (the specific version is libstdc++.so.6.0.16 ).

Update: The problem seems to have been (not sure) that the new 2.18 dynamic linker is using its own library path which includes only subfolders of /path/to/glibc-2.18/lib . I got the program to run by adding this new path, followed by the standard paths ( /lib', '/usr/lib , etc) to /path/to/glibc-2.18/etc/ld.so.conf and running /path/to/glibc-2.18/sbin/ldconfig . More questions:

  1. Do I absolutely need the new 2.18 dynamic linker to run a program with glibc-2.18 ? Can't the standard linker do it? (This would avoid me having to set up and continuously update the paths of the 2.18 dynamic linker.)

  2. If I compile with the 2.18 dynamic linker but without --rpath , the program doesn't work. Why?

  3. Should I be using -L/path/to/glibc-2.18/lib in the compilation command (in addition to --rpath and --dynamic-linker )?

Do I absolutely need the new 2.18 dynamic linker to run a program with glibc-2.18?

Yes (well, almost. See footnote).

This would avoid me having to set up and continuously update the paths of the 2.18 dynamic linker.

A common technique is to create a g++ shell wrapper, eg g++glibc2.18 , and encapsulate adding the necessary link arguments there. Then a simple make CXX=g++glibc2.18 would do the right thing.

Can't the standard linker do it?

No. See this answer for explanation.

If I compile with the 2.18 dynamic linker but without --rpath, the program doesn't work. Why?

See the same answer.

Should I be using -L/path/to/glibc-2.18/lib in the compilation command (in addition to --rpath and --dynamic-linker)?

Yes, if you want to use symbols that are present in glibc-2.18 but not present in your system library. Otherwise, no.

Footnote:

As an alternative, you could build your program without the special flags, then use "explicit loader invocation" to actually run it: /path/to/glibc-2.18/lib/ld-2.18.so /path/to/a.out .

Beware: this doesn't always work: if the program likes to re- exec itself (and under other rare conditions). You may also have trouble debugging it when it is invoked that way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM