Today I compiled a ARM Toolchain on my Ubuntu Lucid Lynx 10.04 PC. As I passed that to my friend he got this message:
arm-elf-gcc: /lib/libc.so.6: version `GLIBC_2.11' not found (required by arm-elf-gcc)
Oh yeah, binary compatibility is sometimes hard in open source world. On the other side, why binary compatibility, we have the source! 😀 But of course, its easier to use binaries then compile the same on every machine…
I found out that the function mkstemps is used from the new glibc version:
$ readelf -a arm-elf-gcc | grep GLIBC_2.11
11: 0000000000000000 0 FUNC GLOBAL DEFAULT UND mkstemps@GLIBC_2.11 (4)
427: 0000000000000000 0 FUNC GLOBAL DEFAULT UND mkstemps@@GLIBC_2.11
008: 3 (GLIBC_2.3.4) 0 (*local*) 2 (GLIBC_2.2.5) 4 (GLIBC_2.11)
0x0030: Name: GLIBC_2.11 Flags: none Version: 4
The functions, namly mkstemps and mkstemps64, were added with glibc 2.11. Grepping showed that the function mkstemps is used inside the library “libiberty”. The configure script checks if the function is available on the host, if yes, it will use the hosts function, if not, it will build its own. As soon as the compiler descide to use the hosts mkstemps function, the resulting binary need glibc 2.11, which I would like to avoid.
The solution is pretty simple: Add the object file “mkstemps.o” to the variable REQUIRED_OFILES in Makefile.in. This forces the Makefile to compile its own mkstemps function, which will be prefered when gcc is linked.
$ vi libiberty/Makefile.in
REQUIRED_OFILES = ./mkstemps.o \
./regex.o ./cplus-dem.o ./cp-demangle.o ./md5.o ./sha1.o \
...
My gcc’s glibc requirement is now 2.4, which is much older then gcc 2.11! As a result my gcc runs even on very old linux systems 🙂