[PATCH v2 2/6] configure: Parametrize runtime libraries to support compiler-rt
Sam James
sam@gentoo.org
Wed Mar 11 06:15:59 GMT 2026
Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:
> 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.
I'm a little surprised this is all that's needed. Thanks.
Reviewed-by: Sam James <sam@gentoo.org>
> ---
> 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))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 418 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20260311/a9a4a504/attachment-0001.sig>
More information about the Libc-alpha
mailing list