#1014114 installation of crypt.h in the multiarch location breaks the GCC and LLVM multilib builds

Package:
libcrypt-dev
Source:
libxcrypt
Description:
libcrypt development files
Submitter:
Matthias Klose
Date:
2022-07-10 19:51:10 UTC
Severity:
serious
Tags:
#1014114#5
Date:
2022-06-30 12:10:17 UTC
From:
To:
installation of crypt.h in the multiarch location breaks the GCC and LLVM
multilib builds.

For libsanitizer, crypt.h is needed to determine the size of a struct, the
library itself is not needed.  Moving it to the MA location makes it unavailable
for the non-multilib builds.

Unfortunately the changelog doesn't mention anything why it was moved.

So either it should be moved back to /usr/include, or we need multilib builds
for libxcrypt.

#1014114#10
Date:
2022-06-30 12:21:22 UTC
From:
To:
It was discussed in #1004102 (and is documented in the git commit),
where Helmut was positive that this would not cause any issues. Helmut?

(Why can't we retire multilib for good?)

#1014114#15
Date:
2022-06-30 15:15:32 UTC
From:
To:
Hi Matthias and Marco,

This report seems needlessly imprecise to me. It is not exactly clear
whether you refer to building the gcc package here or whether you refer
to building something with gcc. I've tried building a small example
with -m32 on amd64. That happened to be successful. I also tried
building gcc-12 on amd64 in unstable (with the new version of libcrypt).
That happened to fail in the following way:

| /<<PKGBUILDDIR>>/build/./prev-gcc/xg++ -B/<<PKGBUILDDIR>>/build/./prev-gcc/ -B/usr/x86_64-linux-gnu/bin/ -nostdinc++ -B/<<PKGBUILDDIR>>/build/prev-x86_64-linux-gnu/libstdc++-v3/src/.libs -B/<<PKGBUILDDIR>>/build/prev-x86_64-linux-gnu/libstdc++-v3/libsupc++/.libs  -I/<<PKGBUILDDIR>>/build/prev-x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu  -I/<<PKGBUILDDIR>>/build/prev-x86_64-linux-gnu/libstdc++-v3/include  -I/<<PKGBUILDDIR>>/src/libstdc++-v3/libsupc++ -L/<<PKGBUILDDIR>>/build/prev-x86_64-linux-gnu/libstdc++-v3/src/.libs -L/<<PKGBUILDDIR>>/build/prev-x86_64-linux-gnu/libstdc++-v3/libsupc++/.libs  -fno-PIE -c -g   -g -O2 -fchecking=1 -DIN_GCC     -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual    -DHAVE_CONFIG_H -I. -Im2/gm2-gcc -I../../src/gcc -I../../src/gcc/m2/gm2-gcc -I../../src/gcc/../include -I../../src/gcc/../libcpp/include -I../../src/gcc/../libcody  -I../../src/gcc/../libdecnumber -I../../src/gcc/../libdecnumber/bid -I../libdecnumber -I../../src/gcc/../libbacktrace   -I. -Im2/gm2-gcc -I../../src/gcc -I../../src/gcc/m2/gm2-gcc -I../../src/gcc/../include -I../../src/gcc/../libcpp/include -I../../src/gcc/../libcody  -I../../src/gcc/../libdecnumber -I../../src/gcc/../libdecnumber/bid -I../libdecnumber -I../../src/gcc/../libbacktrace  ../../src/gcc/m2/gm2-gcc/m2convert.cc -o m2/gm2-gcc/m2convert.o
...
| In file included from ./tm.h:26,
|                  from ../../src/gcc/backend.h:28,
|                  from ../../src/gcc/m2/gm2-gcc/gcc-consolidation.h:26,
|                  from ../../src/gcc/m2/gm2-gcc/m2convert.cc:22:
| ../../src/gcc/config/i386/i386.h:2356:10: fatal error: insn-attr-common.h: No such file or directory
|  2356 | #include "insn-attr-common.h"
|       |          ^~~~~~~~~~~~~~~~~~~~
| compilation terminated.
| make[5]: *** [../../src/gcc/m2/Make-lang.in:600: m2/gm2-gcc/m2convert.o] Error 1
| make[5]: *** Waiting for unfinished jobs....

This looks unrelated to me given that no multilib flag is involved. On
the other hand, it talks about i386 in an amd64 build. I have no clue
how this failure could be attributed to crypt.h. It rather seems to be a
known issue and a classical FTBFS:
https://gcc.gnu.org/pipermail/gcc/2021-May/236101.html

I've attached the full build log to make report debuggable.

So I am unable to reproduce the reported issue with gcc.

Again, the lack of precision is not constructive. Linking to a failure
would help a lot here.

I assume that your statement about the MA location contains an
unintended negation. Is it correct that you meant to say that the MA
location is unavailable to multilib (without "non-") builds? That would
make more sense to me.

I am sorry for the lack of detail here. When moving headers the usual
reason is to avoid unpack errors. That's also the case here. crypt.h is
interpolated at build-time in an architecture-dependent way. Shipping it
on a non-multiarch path imposes a Multi-Arch: same violation.
unpack errors. In theory, we could move it back for multilib-enabled
architectures as long as none of them varies crypt.h (which actually
seems to be the case). I think this would be rather messy, but it seems
technically feasible and relatively simple.

That leaves the other option: adding multilib packages for libxcrypt.

I basically trust Matthias on the statement that something needs crypt.h
for some reason although I'd like to learn why precisely. In theory,
we'd like to make libcrypt-dev non-build-essential and if gcc requires
it, that's a no-brainer.

Assuming that, we basically have the two options above:
 * Move crypt.h back for all multilib architectures only.
 * Add multilib packages.

Marco, do you have any preference here?

Indeed, I did not see this coming and I still am unable to reproduce the
reported problem.

I would like to as well. A significant reason seems to be that doing so
would require cross-architecture dependencies to work with britney.

Helmut

#1014114#24
Date:
2022-07-03 00:37:27 UTC
From:
To:
I do not want to add any more complexity than what is strictly required
to support musl, which is not even a real port.
If moving crypt.h to the multiarch path only when building with musl is
a solution then let's do that.

#1014114#29
Date:
2022-07-03 09:12:14 UTC
From:
To:
Hi Marco,

I note that this complexity is not due to musl. It is due to libcrypt2
regardless of the architecture. It just happens that musl is the first
user of libcrypt2. If we later decide to transition existing
architectures to libcrypt2, they'll be fully hit by this in the very
same way. So keep in mind: If you move to libcrypt2 you have a choice of
breaking multilib or multiarch or adding multlib packages.

I'm attaching a patch for your convenience, but I'd prefer understanding
the actual problem before papering over it like this.

Helmut

#1014114#34
Date:
2022-07-04 18:51:05 UTC
From:
To:
Hi,

I now understand that the libsanitizer aspect is separate to the
multilib aspect. Therefore, my proposed solution is a non-solution and
adding multilib packages is a non-solution as well. It is way worse and
completely messed up.

A gcc build (cross compiler stage3 or native) requires a target
architecture crypt.h. Trying to do without breaks libsanitizer (no
multilib involved). Example from
https://jenkins.debian.net/job/rebootstrap_ppc64_gcc12_nobiarch/5/consoleText

| /bin/bash ../libtool  --tag=CXX   --mode=compile /tmp/buildd/gcc3/gcc-12-12.1.0/build/./gcc/xgcc -shared-libgcc -B/tmp/buildd/gcc3/gcc-12-12.1.0/build/./gcc -nostdinc++ -L/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libstdc++-v3/src -L/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libstdc++-v3/src/.libs -L/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libstdc++-v3/libsupc++/.libs -B/usr/powerpc64-linux-gnu/bin/ -B/usr/powerpc64-linux-gnu/lib/ -isystem /usr/powerpc64-linux-gnu/include -isystem /usr/powerpc64-linux-gnu/sys-include -isystem /tmp/buildd/gcc3/gcc-12-12.1.0/build/sys-include    -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS  -DHAVE_RPC_XDR_H=0 -DHAVE_TIRPC_RPC_XDR_H=0 -I. -I../../../../src/libsanitizer/sanitizer_common -I..  -I ../../../../src/libsanitizer/include -I ../../../../src/libsanitizer -isystem ../../../../src/libsanitizer/include/system  -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fno-rtti -fomit-frame-pointer -funwind-tables -fvisibility=hidden -Wno-variadic-macros -I../../libstdc++-v3/include     -I../../libstdc++-v3/include/powerpc64-linux-gnu     -I../../../../src/libsanitizer/../libstdc++-v3/libsupc++ -std=gnu++14  -DSANITIZER_LIBBACKTRACE -DSANITIZER_CP_DEMANGLE -I ../../../../src/libsanitizer/../libbacktrace -I ../libbacktrace -I ../../../../src/libsanitizer/../include -include ../../../../src/libsanitizer/libbacktrace/backtrace-rename.h -g -O2 -D_GNU_SOURCE -MT sanitizer_platform_limits_posix.lo -MD -MP -MF .deps/sanitizer_platform_limits_posix.Tpo -c -o sanitizer_platform_limits_posix.lo ../../../../src/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
| libtool: compile:  /tmp/buildd/gcc3/gcc-12-12.1.0/build/./gcc/xgcc -shared-libgcc -B/tmp/buildd/gcc3/gcc-12-12.1.0/build/./gcc -nostdinc++ -L/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libstdc++-v3/src -L/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libstdc++-v3/src/.libs -L/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libstdc++-v3/libsupc++/.libs -B/usr/powerpc64-linux-gnu/bin/ -B/usr/powerpc64-linux-gnu/lib/ -isystem /usr/powerpc64-linux-gnu/include -isystem /usr/powerpc64-linux-gnu/sys-include -isystem /tmp/buildd/gcc3/gcc-12-12.1.0/build/sys-include -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DHAVE_RPC_XDR_H=0 -DHAVE_TIRPC_RPC_XDR_H=0 -I. -I../../../../src/libsanitizer/sanitizer_common -I.. -I ../../../../src/libsanitizer/include -I ../../../../src/libsanitizer -isystem ../../../../src/libsanitizer/include/system -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fno-rtti -fomit-frame-pointer -funwind-tables -fvisibility=hidden -Wno-variadic-macros -I../../libstdc++-v3/include -I../../libstdc++-v3/include/powerpc64-linux-gnu -I../../../../src/libsanitizer/../libstdc++-v3/libsupc++ -std=gnu++14 -DSANITIZER_LIBBACKTRACE -DSANITIZER_CP_DEMANGLE -I ../../../../src/libsanitizer/../libbacktrace -I ../libbacktrace -I ../../../../src/libsanitizer/../include -include ../../../../src/libsanitizer/libbacktrace/backtrace-rename.h -g -O2 -D_GNU_SOURCE -MT sanitizer_platform_limits_posix.lo -MD -MP -MF .deps/sanitizer_platform_limits_posix.Tpo -c ../../../../src/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp  -fPIC -DPIC -o .libs/sanitizer_platform_limits_posix.o
| ../../../../src/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:155:10: fatal error: crypt.h: No such file or directory
|   155 | #include <crypt.h>
|       |          ^~~~~~~~~
| compilation terminated.
| make[6]: *** [Makefile:616: sanitizer_platform_limits_posix.lo] Error 1
| make[6]: Leaving directory '/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libsanitizer/sanitizer_common'
| make[5]: *** [Makefile:533: all-recursive] Error 1
| make[5]: Leaving directory '/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libsanitizer'
| make[4]: *** [Makefile:420: all] Error 2
| make[4]: Leaving directory '/tmp/buildd/gcc3/gcc-12-12.1.0/build/powerpc64-linux-gnu/libsanitizer'
| make[3]: *** [Makefile:12936: all-target-libsanitizer] Error 2
| make[3]: Leaving directory '/tmp/buildd/gcc3/gcc-12-12.1.0/build'
| make[2]: *** [Makefile:1049: all] Error 2
| make[2]: Leaving directory '/tmp/buildd/gcc3/gcc-12-12.1.0/build'
| === TIME stamps/05-build-stamp ===

Given that crypt.h is architecture dependent, we'll have to build
crypt.h with a stage1 compiler or no C compiler at all. This is going to
be painful.

I've checked that this is the only place in gcc-12 that uses crypt.h and
that the only thing it uses is sizeof(struct crypt_data), which
theoretically is architecture-dependent, but practically is not. This is
why it has worked in the past. Note that this assumption was broken when
we used musl's crypt.h instead of libxcrypt's.

So in principle, we can stick to the workaround (multiarch only for
libcrypt2), but it comes at a cost:
 * It encodes the assumption that sizeof(struct crypt_data) is
   architecture-independent into libcrypt-dev.
 * We will be unable to use any architecture that uses libcrypt2 as
   build architecture for cross bootstraps. In other words, we cannot
   bootstrap from musl.
 * We can only have architectures that get crypt.h from libxcrypt.

In essence this is a cycle. gcc-12's libsanitizer requires crypt.h,
which is built from libxcrypt, which requires a C compiler, which is
built from gcc-12. It needs to be broken somehow - not least for native
bootstraps. It's been like that all the time and we used to break is
using the assumption that sizeof(struct crypt_data) is
architecture-independent.

The commit adding the crypt.h dependency is fairly recent:

| commit 3ca75cd55030a53a858bdbe9aba6d87f6b1e90b8
| Author: Martin Liska <mliska@suse.cz>
| Date:   Tue Nov 5 14:54:57 2019 +0100
|
|     Libsanitizer: merge from trunk with merge.sh.
|
|     2019-11-05  Martin Liska  <mliska@suse.cz>
|
|             * all source files: Merge from upstream r375507.
|
|     From-SVN: r277834

I failed to figure out the commit messages of those subversion
revisions.

Any idea how to fix this? The TL;DR seems to be that either gcc-12 needs
to stop using crypt.h or we need a libxcrypt stage1 for building
crypt.h or crypt.h needs to become architecture-independent.

Short term, my workaround papers over the practical issues, but that's a
no-brainer long-term.

Helmut

#1014114#39
Date:
2022-07-05 07:16:03 UTC
From:
To:
Hi,

Regardless of how we fix libxcrypt (moving crypt.h back for some
architectures or adding multilib pacages), the libsanitizer issue will
persist. The only option on the libxcrypt side here is adding the
proposed stage1 build profile (but I really don't like that route).

A possible route here is encoding this assumption into gcc. I'm
attaching patch that does so. I'm not convinced that this is the right
way forward, but it practically fixes the cross toolchain bootstrap.

So does anyone see any better options?

Helmut

#1014114#46
Date:
2022-07-08 09:28:15 UTC
From:
To:
because it's still needed, and we don't have the cross compilers as a
replacement ready. As Helmut suggested, we need support for foreign dependencies
and build dependencies.

Please can we revert this?

Matthias

#1014114#51
Date:
2022-07-10 19:49:19 UTC
From:
To:
We believe that the bug you reported is fixed in the latest version of
libxcrypt, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 1014114@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Marco d'Itri <md@linux.it> (supplier of updated libxcrypt package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)
Format: 1.8
Date: Sun, 10 Jul 2022 21:30:07 +0200
Source: libxcrypt
Architecture: source
Version: 1:4.4.28-2
Distribution: unstable
Urgency: medium
Maintainer: Marco d'Itri <md@linux.it>
Changed-By: Marco d'Itri <md@linux.it>
Closes: 1014114
Changes:
 libxcrypt (1:4.4.28-2) unstable; urgency=medium
 .
   [ Helmut Grohne ]
   * Move back crypt.h of libcrypt1 to the non-multiarch directory because
     it broke the GCC and LLVM multilib builds. (Closes: #1014114)
Checksums-Sha1:
 58a4d729727a90113125a120147846d3fbeb166f 1613 libxcrypt_4.4.28-2.dsc
 28627e78c2c865e1b42cae336fb093e3ce9928f6 8088 libxcrypt_4.4.28-2.debian.tar.xz
 c2f86a05adfe5c88259d5ed14d2ec389024fea1c 6542 libxcrypt_4.4.28-2_amd64.buildinfo
Checksums-Sha256:
 b668e66960c61b6980fbb6f2ea2cd7602e390f363e843798eca85f6cc6200a87 1613 libxcrypt_4.4.28-2.dsc
 d5f8c1c1e2cb9ef9e99da9f3c7f28fc4142781337a72c22a67d841a8a8fee4d5 8088 libxcrypt_4.4.28-2.debian.tar.xz
 d716772b8d6eb6c5e3c51a9984ac1cff5f4943f4e2acfbf497913c0e664cdc5e 6542 libxcrypt_4.4.28-2_amd64.buildinfo
Files:
 2354316573bce0b9c6747ca80a9e0915 1613 admin optional libxcrypt_4.4.28-2.dsc
 eafe679af04d0f698c4f74861c104f9d 8088 admin optional libxcrypt_4.4.28-2.debian.tar.xz
 e1faff89fbd0369a673020f3e99b9783 6542 admin optional libxcrypt_4.4.28-2_amd64.buildinfo
-----BEGIN PGP SIGNATURE-----

iHUEARYIAB0WIQQnKUXNg20437dCfobLPsM64d7XgQUCYssrBgAKCRDLPsM64d7X
gQ1eAP0SB390X5iCVYfkUngNmILP7ni5PguagYpPOBS2bFqxjgD+PAdALpQEcjtX
H8NDlRUD8lccZmCGZd4izJgjoKUnAwc=
=E1+K
-----END PGP SIGNATURE-----