I reached out on IRC, and got some feedback on this patch. In particular, Arsen thought the idea made some sense, but that while there was as-yet no long-term policy or design decision on this sort of thing, a proper --with-* flag would wrongly appear to instantly-stable, but a mere autoconf cache variable (which could still be sneakily overridden) would not convey that, reducing the chance of fostering incorrect stability expectations downstream.
(Having some trouble sending emails now it seems? This is yet another attempt. We'll see if it goes through.) On Fri, Jul 11, 2025, at 11:02 AM, John Ericson wrote: > Hello, this 4-year-old patch of mine was never reviewed. Per > https://github.com/NixOS/nixpkgs/pull/414299, we in a package set / distro, > Nixpkgs/NixOS, just began (albeit on an experimental basis) packaging GCC > with this patch (among others) applied. It would thus be nice to get it > applied upstream --- if changes are needed, of course we can make them and > resubmit. > > (The is also visible at > https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/gcc/ng/15/gcc/custom-threading-model.patch.) > > This is I think the conceptually simplest patch/series of the ones we have in > there, so a good one to start with. (I think it would be unnecessary > complicated to discuss them all at once.) > > Thanks in advance, > > John > > On Wed, Aug 18, 2021, at 4:38 PM, John Ericson wrote: >> From: John Ericson <g...@johnericson.me> >> >> Previously, they always scraped the thread mode from `$CC -v', now, that >> is the default but one may pass `--with-threads=MODEL` to be explicit >> instead. >> >> One use-case is bootstraping with a shorter critical path. The >> traditionally route was to build an entire "static stage" GCC, build >> libc, and then build GCC again supporting dynamic linking, >> multithreading, etc. But this is wasteful in that GCC itself is built >> twice. >> >> With this change, rather than having to mess with spec files we can just >> configure the runtime libraries the way we want directly. In turn, that >> opens to just building libgcc twice rather than all of GCC. >> >> Frankly, specs were always a rather indirect approach to coordinate this >> during GCC's bootstrap, since GCC itself really doesn't care what the >> threading model is, just that the runtime libraries agree among >> themselves. Relying on a hard-coded spec for this also keeps us one step >> further from the long-term goal of multi-target GCC, for what it's >> worth. >> >> For the record, "single stage" builds of GCC have some precedent in >> downstream packaging, for example with [1]. That one, as far as I can >> tell, builds libgcc once, but with the headers of the libc >> implementation provided and then cyclic linking down later. They are >> both fine approaches, but I don't think one should have to be forced >> into cyclic dependencies if they don't want to. That opens the door to >> non-terminating programs due to, e.g., atomics used in a threads >> implementation being lowered to threads absent hardware support. >> >> Finally, I understand that such custom bootstrapping is not officially >> supported. I don't mean to imply it should be --- a lot more cleanup >> work to the build system would be necessary before supporting it >> wouldn't be a huge additional maintainer burden --- I just hope to add a >> reasonable knob for those comfortable with doing unsupported things >> already. >> >> [1]: https://github.com/richfelker/musl-cross-make >> --- >> config/gthr.m4 | 32 ++++++++++++++++++++++++++++++++ >> libatomic/configure.ac | 4 +--- >> libgcc/configure.ac | 4 +--- >> libphobos/m4/druntime/os.m4 | 2 +- >> libstdc++-v3/acinclude.m4 | 8 +++----- >> 5 files changed, 38 insertions(+), 12 deletions(-) >> >> diff --git a/config/gthr.m4 b/config/gthr.m4 >> index 4b937306ad0..c585b618e40 100644 >> --- a/config/gthr.m4 >> +++ b/config/gthr.m4 >> @@ -5,6 +5,35 @@ dnl Public License, this file may be distributed as part of >> a program >> dnl that contains a configuration script generated by Autoconf, under >> dnl the same distribution terms as the rest of that program. >> >> +dnl Define thread model >> + >> +dnl usage: GCC_AC_THREAD_MODEL >> +AC_DEFUN([GCC_AC_THREAD_MODEL], >> +[ >> +# With threads >> +# Pass with no value to take from compiler's metadata >> +# Pass with a value to specify a thread package >> +# 'single' means single threaded -- without threads. >> +AC_ARG_WITH(threads, >> +[AS_HELP_STRING([[--with-threads=MODEL]], >> + [specify thread model for this GCC >> + runtime library])],, >> +[with_threads='']) >> + >> +if test x"$with_threads" = x'yes'; then >> + AC_MSG_ERROR([Cannot pass bare --with-threads, must pass explicit >> --with-threads=MODEL]) >> +elif test x"$with_threads" = x'no'; then >> + target_thread_file=single >> +elif test x"$with_threads" = ''; then >> + AC_MSG_CHECKING([for thread model used by GCC]) >> + target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'` >> + AC_MSG_RESULT([$target_thread_file]) >> +else >> + target_thread_file=$with_threads >> +fi >> +]) >> + >> + >> dnl Define header location by thread model >> >> dnl usage: GCC_AC_THREAD_HEADER([thread_model]) >> @@ -22,6 +51,9 @@ case $1 in >> tpf) thread_header=config/s390/gthr-tpf.h ;; >> vxworks) thread_header=config/gthr-vxworks.h ;; >> win32) thread_header=config/i386/gthr-win32.h ;; >> + *) >> + AC_MSG_ERROR([No known header for threading model '$1'.]) >> + ;; >> esac >> AC_SUBST(thread_header) >> ]) >> diff --git a/libatomic/configure.ac b/libatomic/configure.ac >> index 2a371870c2f..42d2016b7a2 100644 >> --- a/libatomic/configure.ac >> +++ b/libatomic/configure.ac >> @@ -161,9 +161,7 @@ libtool_VERSION=3:0:2 >> AC_SUBST(libtool_VERSION) >> >> # Check for used threading-model >> -AC_MSG_CHECKING([for thread model used by GCC]) >> -target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'` >> -AC_MSG_RESULT([$target_thread_file]) >> +GCC_AC_THREAD_MODEL >> >> case "$target" in >> *aarch64*) >> diff --git a/libgcc/configure.ac b/libgcc/configure.ac >> index 13a80b2551b..1209a0986e0 100644 >> --- a/libgcc/configure.ac >> +++ b/libgcc/configure.ac >> @@ -298,9 +298,7 @@ AC_SUBST([use_tm_clone_registry]) >> >> AC_LIB_PROG_LD_GNU >> >> -AC_MSG_CHECKING([for thread model used by GCC]) >> -target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'` >> -AC_MSG_RESULT([$target_thread_file]) >> +GCC_AC_THREAD_MODEL >> >> # Check for assembler CFI support. >> AC_CACHE_CHECK([whether assembler supports CFI directives], [libgcc_cv_cfi], >> diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4 >> index 351558dbcda..2b44fbca8fc 100644 >> --- a/libphobos/m4/druntime/os.m4 >> +++ b/libphobos/m4/druntime/os.m4 >> @@ -32,7 +32,7 @@ case $1 in >> # TODO: These targets need porting. >> dce|mipssde|rtems|tpf|vxworks) >> DCFG_THREAD_MODEL="Single" ;; >> - *) as_fn_error "Thread implementation '$1' not recognised" >> "$LINENO" 5 ;; >> + *) AC_MSG_ERROR([Thread implementation '$1' not recognised]) ;; >> esac >> AC_SUBST(DCFG_THREAD_MODEL) >> ]) >> diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 >> index 90ecc4a87a2..83204176c05 100644 >> --- a/libstdc++-v3/acinclude.m4 >> +++ b/libstdc++-v3/acinclude.m4 >> @@ -3910,9 +3910,7 @@ dnl Substs: >> dnl thread_header >> dnl >> AC_DEFUN([GLIBCXX_ENABLE_THREADS], [ >> - AC_MSG_CHECKING([for thread model used by GCC]) >> - target_thread_file=`$CXX -v 2>&1 | sed -n 's/^Thread model: //p'` >> - AC_MSG_RESULT([$target_thread_file]) >> + GCC_AC_THREAD_MODEL >> GCC_AC_THREAD_HEADER([$target_thread_file]) >> ]) >> >> @@ -3922,7 +3920,8 @@ dnl Check if gthread implementation defines the types >> and functions >> dnl required by the c++0x thread library. Conforming gthread >> dnl implementations can define __GTHREADS_CXX0X to enable use with c++0x. >> dnl >> -dnl GLIBCXX_ENABLE_SYMVERS must be done before this. >> +dnl GLIBCXX_ENABLE_SYMVERS and GLIBCXX_ENABLE_THREADS must be done >> +dnl before this. >> dnl >> AC_DEFUN([GLIBCXX_CHECK_GTHREADS], [ >> GLIBCXX_ENABLE(libstdcxx-threads,auto,,[enable C++11 threads support]) >> @@ -3937,7 +3936,6 @@ AC_DEFUN([GLIBCXX_CHECK_GTHREADS], [ >> CXXFLAGS="$CXXFLAGS -fno-exceptions \ >> -I${toplevel_srcdir}/libgcc -I${toplevel_builddir}/libgcc" >> >> - target_thread_file=`$CXX -v 2>&1 | sed -n 's/^Thread model: //p'` >> case $target_thread_file in >> posix) >> CXXFLAGS="$CXXFLAGS -DSUPPORTS_WEAK -DGTHREAD_USE_WEAK -D_PTHREADS" >> -- >> 2.31.1 >> >> >