Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile with older libc (version `GLIBC_2.14' not found)

I have to compile a program on a current ubuntu (12.04). This program should then run on a cluster using CentOS with an older Kernel (2.6.18). I cannot compile on the cluster directly, unfortunately. If I just compile and copy the program without any changes I get the error message "kernel too old".

The way I understood it, the reason for this is not so much the Kernel version, but the version of libc that was used for compilation. So I tried to compile my program dynamically linking the libc from the cluster and statically linking everything else.

Research

There are already a lot of questions about this on SO but none of the answers really worked for me. So here is my research on that topic:

  • This question explains the reason for the Kernel too old message
  • This question is similar but more specialized and has no answers
  • Linking statically as proposed here didn't work because the libc is too old on the cluster. One answer also mentions to build using the old libc, but doesn't explain how to do this.
  • One way is to compile in a VM running an old OS. This worked but is complicated. I also read that you should not link libc statically
  • Apparently it is possible to compile for a different libc version with the option -rpath but this did not work for me (see below)

Current state

I copied the following files from the cluster into the directory /path/to/copied/libs

  • libc-2.5.so
  • libgcc_s.so.1
  • libstdc++.so.6

and am compiling with the options -nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s

The output of ldd on the compiled binary is

mybin: /path/to/copied/libs/libc.so.6: version `GLIBC_2.14' not found (required by mybin) mybin: /path/to/copied/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mybin) linux-vdso.so.1 =>  (0x00007ffff36bb000) libc.so.6 => /path/to/copied/libs/libc.so.6 (0x00007fbe3789a000) libstdc++.so.6 => /path/to/copied/libs/libstdc++.so.6 (0x00007fbe37599000) libgcc_s.so.1 => /path/to/copied/libs/libgcc_s.so.1 (0x00007fbe3738b000) /lib64/ld-linux-x86-64.so.2 (0x00007fbe37bf3000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbe37071000) 

I'm somewhat confused by the error, because it uses the correct path (i.e. the libc from the cluster) but still complains about a missing glibc version. When running ldd on the cluster it returns not a dynamic executable and running the binary results in the same two errors mentioned above. It also looks like there are other libraries included (linux-vdso.so.1, ld-linux-x86-64.so.2 and libm.so.6). Should I use the older versions for those as well?

So now I have two main questions:

  • Is this even the correct approach here?
  • If yes: how do I link the old libc correctly?
like image 981
Flogo Avatar asked May 30 '12 11:05

Flogo


People also ask

How do I find libc version?

The process for checking your installed version of libc will be the same regardless of your Linux distro. Simply use the ldd command as seen below. $ ldd --version ldd (Ubuntu GLIBC 2.35-0ubuntu3) 2.35 ... As you can see from the first line of the output and in the previous screenshot, we have version 2.35 installed.

Is libc automatically linked?

libc is always searched automatically.

Is libc installed?

Here's how to check if a library is installed: Type ldconfig -p | grep libc++ into the terminal. It does not matter what system you are using. If libc++ is not installed, the terminal will not say anything.


1 Answers

See this answer.

Is this even the correct approach here

No: you can't use mismatched versions of glibc as your link command does. You used crt0.o and ld-linux.so from new (system-installed) libc, but libc.so.6 from an old (copied from cluster) libc. That is just not going to work.

like image 182
Employed Russian Avatar answered Oct 04 '22 15:10

Employed Russian