https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122794

            Bug ID: 122794
           Summary: Multilib warnings are treated differently by
                    libtool/configure
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: build
          Severity: normal
          Priority: P3
         Component: d
          Assignee: ibuclaw at gdcproject dot org
          Reporter: stefansf at gcc dot gnu.org
  Target Milestone: ---

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.

Reply via email to