[PATCH v2 2/6] configure: Parametrize runtime libraries to support compiler-rt

Adhemerval Zanella adhemerval.zanella@linaro.org
Wed Feb 25 18:31:13 GMT 2026


Historically, the build system has hardcoded references to `-lgcc` and
`-lgcc_eh`, explicitly assuming the use of the GCC runtime.  This
prevents building glibc with alternative toolchains, specifically clang
configured with `--rtlib=compiler-rt`, where these libraries are
replaced by `libclang_rt.builtins`.

This patch introduces a mechanism to dynamically detect the compiler's
underlying runtime library.

The logic works as follows:

1. It queries the compiler using `-print-libgcc-file-name`.
2. It parses the output path to determine if `libgcc` or `compiler-rt`
   is in use.
3. Based on this detection, it parametrizes the build variables for
   the static runtime and exception handling libraries (replacing
   hardcoded `-lgcc` and `-lgcc_eh`).

This ensures that the build system correctly links against the active
compiler runtime—whether it is the traditional libgcc or LLVM's
compiler-rt—without requiring manual overrides.
---
 Makeconfig       | 12 ++++++------
 configure        | 34 ++++++++++++++++++++++++++++++++++
 configure.ac     | 20 ++++++++++++++++++++
 dlfcn/Makefile   |  2 +-
 elf/Makefile     |  4 ++--
 support/Makefile |  4 ++--
 6 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/Makeconfig b/Makeconfig
index 01d02180b9..6a05e1d973 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -716,20 +716,20 @@ else
 endif
 libgcc_eh := -Wl,--as-needed -lgcc_s $(libunwind) -Wl,--no-as-needed
 gnulib-arch =
-gnulib = -lgcc $(gnulib-arch)
-gnulib-tests := -lgcc $(libgcc_eh)
+gnulib = $(libgcc-name) $(gnulib-arch)
+gnulib-tests := $(libgcc-name) $(libgcc_eh)
 gnulib-extralibdir = $(dir $(shell $(CC) -print-file-name=libgcc_s.so$(libgcc_s.so-version)))
 static-gnulib-arch =
 # By default, elf/static-stubs.o, instead of -lgcc_eh, is used to
 # statically link programs.  When --disable-shared is used, we use
 # -lgcc_eh since elf/static-stubs.o isn't sufficient.
 ifeq (yes,$(build-shared))
-static-gnulib = -lgcc $(static-gnulib-arch)
+static-gnulib = $(libgcc-name) $(static-gnulib-arch)
 else
-static-gnulib = -lgcc -lgcc_eh $(static-gnulib-arch)
+static-gnulib = $(libgcc-name) $(libgcc_eh-name) $(static-gnulib-arch)
 endif
-static-gnulib-tests := -lgcc -lgcc_eh $(libunwind)
-libc.so-gnulib := -lgcc
+static-gnulib-tests := $(libgcc-name) $(libgcc_eh-name) $(libunwind)
+libc.so-gnulib := $(libgcc-name)
 endif
 +preinit = $(addprefix $(csu-objpfx),crti.o)
 +postinit = $(addprefix $(csu-objpfx),crtn.o)
diff --git a/configure b/configure
index 2b9425232e..672b1abad8 100755
--- a/configure
+++ b/configure
@@ -9368,6 +9368,40 @@ printf "%s\n" "$libc_cv_have_libgcc_s" >&6; }
 config_vars="$config_vars
 have-libgcc_s = $libc_cv_have_libgcc_s"
 
+# Check which runtime library compiler uses
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the usable compiler runtime library" >&5
+printf %s "checking for the usable compiler runtime library... " >&6; }
+if test ${libc_cv_runtime_library+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e)   libc_cv_libgcc_usable=no
+  libgcc_name=`${CC-cc} $CFLAGS $CPPFLAGS -print-libgcc-file-name | sed 's:.*/::'`
+  case "$libgcc_name" in
+    libgcc*)
+      libc_cv_libgcc=-lgcc
+      libc_cv_libgcc_eh=-lgcc_eh
+      libc_cv_runtime_library=libgcc
+      ;;
+    libclang_rt*)
+      libc_cv_libgcc=-lclang_rt.builtins
+      libc_cv_libgcc_eh=
+      libc_cv_runtime_library=compiler-rt
+      ;;
+    *) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "non supported compiler runtime library
+See 'config.log' for more details" "$LINENO" 5; } ;;
+  esac ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_runtime_library" >&5
+printf "%s\n" "$libc_cv_runtime_library" >&6; }
+config_vars="$config_vars
+libgcc-name = $libc_cv_libgcc"
+config_vars="$config_vars
+libgcc_eh-name = $libc_cv_libgcc_eh"
+
 # Check if compiler runtime library provides __sfp_handle_exceptions
 
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __sfp_handle_exceptions support" >&5
diff --git a/configure.ac b/configure.ac
index 39d32ecf7f..aa50f28e60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2134,6 +2134,26 @@ AC_CACHE_CHECK([whether $CC can link against -lgcc_s], libc_cv_have_libgcc_s, [d
   LIBS="$old_LIBS"])
 LIBC_CONFIG_VAR([have-libgcc_s], [$libc_cv_have_libgcc_s])
 
+# Check which runtime library compiler uses
+AC_CACHE_CHECK([for the usable compiler runtime library], [libc_cv_runtime_library], [dnl
+  libc_cv_libgcc_usable=no
+  libgcc_name=`${CC-cc} $CFLAGS $CPPFLAGS -print-libgcc-file-name | sed 's:.*/::'`
+  case "$libgcc_name" in
+    libgcc*)
+      libc_cv_libgcc=-lgcc
+      libc_cv_libgcc_eh=-lgcc_eh
+      libc_cv_runtime_library=libgcc
+      ;;
+    libclang_rt*)
+      libc_cv_libgcc=-lclang_rt.builtins
+      libc_cv_libgcc_eh=
+      libc_cv_runtime_library=compiler-rt
+      ;;
+    *) AC_MSG_FAILURE([non supported compiler runtime library]) ;;
+  esac])
+LIBC_CONFIG_VAR([libgcc-name], [$libc_cv_libgcc])
+LIBC_CONFIG_VAR([libgcc_eh-name], [$libc_cv_libgcc_eh])
+
 # Check if compiler runtime library provides __sfp_handle_exceptions
 LIBC_TRY_CC_AND_TEST_LINK([for __sfp_handle_exceptions support],
   [void __sfp_handle_exceptions (int); __sfp_handle_exceptions (0)],
diff --git a/dlfcn/Makefile b/dlfcn/Makefile
index 14de193ab8..00341dd476 100644
--- a/dlfcn/Makefile
+++ b/dlfcn/Makefile
@@ -187,7 +187,7 @@ $(objpfx)bug-atexit1.out: $(objpfx)bug-atexit1-lib.so
 $(objpfx)bug-atexit2.out: $(objpfx)bug-atexit2-lib.so
 
 ifneq (,$(CXX))
-LDLIBS-bug-atexit3-lib.so = -lstdc++ -lgcc_eh
+LDLIBS-bug-atexit3-lib.so = -lstdc++ $(libgcc_eh)
 $(objpfx)bug-atexit3-lib.so: $(libsupport)
 $(objpfx)bug-atexit3.out: $(objpfx)bug-atexit3-lib.so
 endif
diff --git a/elf/Makefile b/elf/Makefile
index 1a0ed49bc3..bd7ae54632 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1513,7 +1513,7 @@ $(objpfx)librtld.map: $(objpfx)dl-allobjs.os $(common-objpfx)libc_pic.a
 		echo ".globl $$symbol"; \
 		echo "$$symbol:"; \
 	done | $(CC) -o $@T.o $(ASFLAGS) -c -x assembler -
-	$(reloc-link) -o $@.o $@T.o '-Wl,-(' $^ -lgcc '-Wl,-)' -Wl,-Map,$@T
+	$(reloc-link) -o $@.o $@T.o '-Wl,-(' $^ $(gnulib) '-Wl,-)' -Wl,-Map,$@T
 	rm -f %@T.o $@.o
 	mv -f $@T $@
 
@@ -1543,7 +1543,7 @@ $(objpfx)rtld-libc.a: $(objpfx)librtld.mk FORCE
 	$(MAKE) -f $< -f rtld-Rules
 
 $(objpfx)librtld.os: $(objpfx)dl-allobjs.os $(objpfx)rtld-libc.a
-	$(LINK.o) -nostdlib -nostartfiles -r -o $@ '-Wl,-(' $^ -lgcc '-Wl,-)' \
+	$(LINK.o) -nostdlib -nostartfiles -r -o $@ '-Wl,-(' $^ $(gnulib) '-Wl,-)' \
 		  -Wl,-Map,$@.map
 
 generated += librtld.map librtld.mk rtld-libc.a librtld.os.map
diff --git a/support/Makefile b/support/Makefile
index 3a20ecfc71..b83350180c 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -316,14 +316,14 @@ CFLAGS-temp_file.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
 
 ifeq (,$(CXX))
 LINKS_DSO_PROGRAM = links-dso-program-c
-LDLIBS-links-dso-program-c = -lgcc
+LDLIBS-links-dso-program-c = $(gnulib)
 ifeq ($(have-libgcc_s),yes)
 CFLAGS-links-dso-program-c.c += -fexceptions
 LDLIBS-links-dso-program-c += -lgcc_s $(libunwind)
 endif
 else
 LINKS_DSO_PROGRAM = links-dso-program
-LDLIBS-links-dso-program = -lstdc++ -lgcc -lgcc_s $(libunwind)
+LDLIBS-links-dso-program = -lstdc++ $(gnulib) $(libgcc_s) $(libunwind)
 endif
 
 ifeq (yes,$(have-selinux))
-- 
2.43.0



More information about the Libc-alpha mailing list