You can compile binaries that work with older glibc versions by forcing gcc to use older headers (I use glibc 2.2 headers when I do Linux etpro builds.) The headers choose the correct symbol to use for certain functions, and the linker will then stamp on the appropriate version for that symbol, so if your headers only use the glibc 2.2-specific stuff, you’ll avoid the glibc 2.3 dependency.
Quick example:
glibc 2.3’s ctype functions (e.g. tolower(), toupper()) use some special helper functions that previous versions of glibc didn’t provide (which are called from the tolower() function defined in ctype.h), so when using the glibc 2.3 headers you end up requiring glibc 2.3:
required from libc.so.6:
0x0d696911 0x00 06 GLIBC_2.1
0x09691f73 0x00 05 GLIBC_2.1.3
0x0d696913 0x00 04 GLIBC_2.3
0x0d696910 0x00 02 GLIBC_2.0
[...]
SYMBOL TABLE:
[...]
00000000 F *UND* 00000071 __ctype_tolower_loc@@GLIBC_2.3
00000000 F *UND* 00000071 __ctype_toupper_loc@@GLIBC_2.3
00000000 F *UND* 00000071 __ctype_b_loc@@GLIBC_2.3
If you use glibc 2.2’s headers to compile, the newer ctype functions aren’t used, the symbols for the helper functions aren’t referenced, and you get a build that’ll work on older systems:
required from libc.so.6:
0x0d696911 0x00 05 GLIBC_2.1
0x09691f73 0x00 03 GLIBC_2.1.3
0x0d696910 0x00 02 GLIBC_2.0
[...]
SYMBOL TABLE:
[...]
00000000 O *UND* 00000004 __ctype_tolower@@GLIBC_2.0
00000000 O *UND* 00000004 __ctype_toupper@@GLIBC_2.0
You can tell gcc to use a different set of system headers like so:
gcc -nostdinc -I/path/to/alternate/glibc/headers -I/path/to/gcc/headers
…and you can easily find the path of gcc’s own headers (for e.g. stdinc.h) with:
gcc --print-file-name=include
I do something like this in the etpro makefiles:
ifeq ($(BUILDHOST)-$(WIN32),portal-0)
CFLAGS_COMMON += -nostdinc -I/usr/local/glibc-2.2-headers -I$(GCC_HEADERS)
ifeq ($(GCC3),1)
CFLAGS_COMMON += -pedantic -std=c99
endif
endif
[...]
GCC_HEADERS=$(shell $(CC) --print-file-name=include)
There is one caveat to this: when generating dependencies, gcc -MM won’t work as expected (it’ll work like gcc -M), because it won’t treat the glibc 2.2 headers as “systemâ€? headers.