While experimenting with a new warning, I'm running into a libtool/configure inconsistency. Initially, the new warning was supposed for the s390 target but it is also reproducible on x86_64. For easier reproducibility I'm including a patch for x86_64 without intending to push it, of course ;-). Applying diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 84494502345..2c6c9ae9283 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -655,3 +655,3 @@ Optimize noreturn functions by not saving callee-saved registers used in the fun m32 -Target RejectNegative Negative(m64) InverseMask(ISA_64BIT) Var(ix86_isa_flags) Save +Target RejectNegative Negative(m64) InverseMask(ISA_64BIT) Var(ix86_isa_flags) Save Warn(foobar) Generate 32bit i386 code. we run into the following error when language D is enabled: $ ./configure --enable-languages=c,d --enable-multilib ... $ make -j`nproc` ... libtool: compile: mv -f "atomic.o" "core/.libs/atomic.o" ... mv: cannot stat 'atomic.o': No such file or directory ... make[8]: Leaving directory '/gcc/build/x86_64-pc-linux-gnu/32/libphobos/libdruntime' make[7]: *** [Makefile:488: all-recursive] Error 1 make[7]: Leaving directory '/gcc/build/x86_64-pc-linux-gnu/32/libphobos' make[6]: *** [Makefile:415: all] Error 2 make[6]: Leaving directory '/gcc/build/x86_64-pc-linux-gnu/32/libphobos' make[5]: *** [Makefile:747: multi-do] Error 1 make[5]: Leaving directory '/gcc/build/x86_64-pc-linux-gnu/libphobos' make[4]: *** [Makefile:717: all-multi] Error 2 make[4]: Leaving directory '/gcc/build/x86_64-pc-linux-gnu/libphobos' make[3]: *** [Makefile:488: all-recursive] Error 1 make[3]: Leaving directory '/gcc/build/x86_64-pc-linux-gnu/libphobos' make[2]: *** [Makefile:415: all] Error 2 make[2]: Leaving directory '/gcc/build/x86_64-pc-linux-gnu/libphobos' make[1]: *** [Makefile:14902: all-target-libphobos] Error 2 make[1]: Leaving directory '/gcc/build' make: *** [Makefile:1047: all] Error 2 The error vanishes if I compile with a few processes only, or even without parallelism at all. Note, also it is so far always reproducible, the actual object may change, i.e., sometimes it is lifetime.o, atomic.o and so forth. Looking at strace output we have 3116200 execve("/bin/sh", ["/bin/sh", "../libtool", "--tag=D", "--mode=compile", "/gcc/build/./gcc/gdc", "-B/gcc/build/./gcc/", "-B/gcc/dst/x86_64-pc-linux-gnu/bin/", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/../lib", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/include", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/sys-include", "-m32", "-prefer-pic", "-fversion=Shared", "-Wall", "-frelease", "-ffunction-sections", "-fdata-sections", "-fcf-protection", "-mshstk", "-g", "-O2", "-fpreview=dip1000", "-fpreview=fieldwise", "-fpreview=dtorfields", "-nostdinc", "-I", "/gcc/src/libphobos/libdruntime", "-I", ".", "-c", "-o", "core/atomic.lo", "/gcc/src/libphobos/libdruntime/core/atomic.d"], ... 3116315 execve("/bin/sh", ["/bin/sh", "../libtool", "--tag=D", "--mode=compile", "/gcc/build/./gcc/gdc", "-B/gcc/build/./gcc/", "-B/gcc/dst/x86_64-pc-linux-gnu/bin/", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/../lib", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/include", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/sys-include", "-m32", "-prefer-pic", "-fversion=Shared", "-Wall", "-frelease", "-ffunction-sections", "-fdata-sections", "-fcf-protection", "-mshstk", "-g", "-O2", "-fpreview=dip1000", "-fpreview=fieldwise", "-fpreview=dtorfields", "-nostdinc", "-I", "/gcc/src/libphobos/libdruntime", "-I", ".", "-c", "-o", "core/internal/atomic.lo", "/gcc/src/libphobos/libdruntime/core/internal/atomic.d"], ... 3116463 execve("/gcc/build/./gcc/gdc", ["/gcc/build/./gcc/gdc", "-B/gcc/build/./gcc/", "-B/gcc/dst/x86_64-pc-linux-gnu/bin/", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/../lib", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/include", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/sys-include", "-m32", "-fversion=Shared", "-Wall", "-frelease", "-ffunction-sections", "-fdata-sections", "-fcf-protection", "-mshstk", "-g", "-O2", "-fpreview=dip1000", "-fpreview=fieldwise", "-fpreview=dtorfields", "-nostdinc", "-I", "/gcc/src/libphobos/libdruntime", "-I", ".", "-c", "/gcc/src/libphobos/libdruntime/core/atomic.d", "-fversion=Shared"], ... 3116722 execve("/gcc/build/./gcc/gdc", ["/gcc/build/./gcc/gdc", "-B/gcc/build/./gcc/", "-B/gcc/dst/x86_64-pc-linux-gnu/bin/", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/../lib", "-B/gcc/dst/x86_64-pc-linux-gnu/lib/", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/include", "-isystem", "/gcc/dst/x86_64-pc-linux-gnu/sys-include", "-m32", "-fversion=Shared", "-Wall", "-frelease", "-ffunction-sections", "-fdata-sections", "-fcf-protection", "-mshstk", "-g", "-O2", "-fpreview=dip1000", "-fpreview=fieldwise", "-fpreview=dtorfields", "-nostdinc", "-I", "/gcc/src/libphobos/libdruntime", "-I", ".", "-c", "/gcc/src/libphobos/libdruntime/core/internal/atomic.d", "-fversion=Shared"], ... 3116802 execve("/usr/bin/mv", ["mv", "-f", "atomic.o", "core/.libs/atomic.o"], ... 3116984 execve("/usr/bin/mv", ["mv", "-f", "atomic.o", "core/internal/.libs/atomic.o"], ... 3116999 execve("/usr/bin/mv", ["mv", "-f", "atomic.o", "core/atomic.o"], ... The culprit is that libtool is passed options "-c -o" but only option "-c" is passed to gdc. This in turn means that multiple processes may use the same output file atomic.o which explains the race. Manually changing libtool to use need_locks="warn" we then get *** ERROR, atomic.o.lock exists and contains: /gcc/src/libphobos/libdruntime/core/atomic.d This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support `-c' and `-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler. The "-o" option is missing because in libtool we have # ### BEGIN LIBTOOL TAG CONFIG: D ... # Does compiler simultaneously support -c and -o options? compiler_c_o="no" which is why "-o" is stripped off. Note, this is only the case for the 32-bit build but not for the 64-bit one. We end up with compiler_c_o="no" due to the test in _LT_COMPILER_C_O having if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi There we test for warnings where the compiler was invoked including option -m32 and compare this output against some expected output. The expected output was generated from a compile run without -m32. Thus, the outputs differ and we do not set compiler_c_o to yes meaning we keep the default no. The expected output is derived during configure time via _LT_COMPILER_BOILERPLATE where no -m32 is specified. Long story short: this is not a D bug but rather some inconsistency between libtool and configure which manifests while building libphobos.
This looks a lot like the Go thing which has been driving me crazy.
The warning triggers this: # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output.
https://inbox.sourceware.org/gcc-patches/20251203140356.402284-1-stefansf@linux.ibm.com/ Pending approval on Go part.