How to Compile Custom Glibc Versions on Linux
Download the required glibc source release archive from the official GNU glibc FTP repository at https://ftp.gnu.org/gnu/glibc/.
Extract the downloaded tarball, create an out-of-tree build directory inside the extracted source folder, and prepare a separate installation target directory to avoid conflicting with system glibc files:
tar -xf glibc-2.27.tar.gz
cd glibc-2.27
mkdir build_output
sudo mkdir -p /opt/custom_glibc/glibc-2.27
Navigate too the build directory, set compile flags to enable debug symbols and suppress comon warnings for older glibc releases, run the configure script with your target install prefix, then compile and install:
cd build_output
CFLAGS="-g -g3 -ggdb -gdwarf-5 -Og -Wno-error=dangling-else -Wno-error=maybe-uninitialized" \
CXXFLAGS="-g -g3 -ggdb -gdwarf-5 -Og -Wno-error=dangling-else -Wno-error=maybe-uninitialized" \
../configure --prefix=/opt/custom_glibc/glibc-2.27
# Uncomment the line below only for ARM64 cross-compilation after loading cross-toolchain environment variables
# $CROSS_COMPILE_CONFIG_FLAGS
make -j$(nproc)
sudo make install
Create a system-wide symlink for the compiled glibc dynamic loader in the system library directory:
sudo ln -s /opt/custom_glibc/glibc-2.27/lib/ld-2.27.so /lib64/27-linux-x86-64.so.2
Verify the new loader is present by listing contents of /lib64:
user@dev-workstation:~/workspace$ ls -l /lib64 | grep linux-x86-64
lrwxrwxrwx 1 root root 45 Aug 22 14:32 27-linux-x86-64.so.2 -> /opt/custom_glibc/glibc-2.27/lib/ld-2.27.so
lrwxrwxrwx 1 root root 45 Aug 22 10:08 31-linux-x86-64.so.2 -> /opt/custom_glibc/glibc-2.31/lib/ld-2.31.so
lrwxrwxrwx 1 root root 35 Nov 12 2023 ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.35.so
Older glibc versions often throw compilation errors when built with newer GCC toolchains, most can be resolved with small source code modifications.
Common Compilation Errors & Fixes
Dangling Else Error in nis_call.c
Sample error output:
nis_call.c: In function ‘nis_server_cache_add’:
nis_call.c:682:6: error: suggest explicit braces to avoid ambiguous ‘else’ [-Werror=dangling-else]
if (*loc != NULL)
^
cc1: all warnings being treated as errors
make[2]: *** [../o-iterator.mk:9:/opt/custom_glibc/glibc-2.27/nis/nis_call.o] Error 1
make[2]: Leaving directory ‘/home/user/workspace/glibc-2.27/nis’
make[1]: *** [Makefile:214:nis/others] Error 2
make[1]: Leaving directory ‘/home/user/workspace/glibc-2.27’
make: *** [Makefile:9:all] Error 2
Fix: Add explicit curly braces around the if/else block at the reported line number in nis_call.c to resolve the ambiguous syntax.
Common Symbol Versioning Errer in regexp.c
Sample error output:
-o /opt/custom_glibc/glibc-2.27/misc/regexp.os -MD -MP -MF /opt/custom_glibc/glibc-2.27/misc/regexp.os.dt -MT /opt/custom_glibc/glibc-2.27/misc/regexp.os
/tmp/cc7xq2f9.s: Assembler messages:
/tmp/cc7xq2f9.s: error: `loc1@GLIBC_2.2.5' can't be versioned to common symbol 'loc1'
/tmp/cc7xq2f9.s: error: `loc2@GLIBC_2.2.5' can't be versioned to common symbol 'loc2'
/tmp/cc7xq2f9.s: error: `locs@GLIBC_2.2.5' can't be versioned to common symbol 'locs'
make[2]: *** [../o-iterator.mk:9:/opt/custom_glibc/glibc-2.27/misc/regexp.os] Error 1
make[2]: Leaving directory ‘/home/user/workspace/glibc-2.27/misc’
make[1]: *** [Makefile:214:misc/subdir_lib] Error 2
make[1]: Leaving directory ‘/home/user/workspace/glibc-2.27’
make: *** [Makefile:9:all] Error 2
Fix: Modify the global variable declarations in misc/regexp.c from:
char *loc1;
char *loc2;
char *locs;
to:
char *loc1 __attribute__ ((nocommon));
char *loc2 __attribute__ ((nocommon));
char *locs __attribute__ ((nocommon));
You can also add -fno-common to the CFLAGS varible as an alternative fix for this error.