toolchain/external: remove libcrypt from glibc

Note: this commit only deals with glibc and its internal libcrypt (or
lack thereof); other C libraries, musl and uClibc-NG, are not considered.

libcrypt from glibc has been deprecated for a long time, and it has now
been entirely dropped with glibc 2.39. Now, packages that need crypt(3)
features need to explicitly depend on the libxcrypt pacakge.

However, the set of files installed both by glibc and libxcrypt is not
empty:

    glibc                           libxcrypt
    /usr/include/crypt.h            /usr/include/crypt.h
    /usr/lib/libcrypt.a             /usr/lib/libcrypt.a
    /usr/lib/libcrypt.so            /usr/lib/libcrypt.so
    /lib/libcrypt.so.1
    /lib/libcrypt-2.23.so
                                    /usr/lib/libcrypt.so.2

The two libraries have different SO_NAME, so they do not conflict on the
library filename. However, the .so synlink is present in both, and thus
conflicts. The header and the static library also conflict.

So, the situation is that, with a glibc 2.39 or later, packages have to
use libxcrypt, which is a drop-in replacement. With glibc 2.38 or
earlier, they can use either.

Since we already bumped to glibc 2.39 for the internal toolchain, we
have already converted quite a few packages to use libxcrypt. That works
well with an internl toolchain, because glibc does not install the
conflicting files.

However, for external toolchains, we may very well end up in three
situations:

  - a glibc 2.39 or later, without libcrypt
  - a glibc 2.39 or later, without libcrypt, but with libxcrypt [0]
  - a glibc 2.38 or earlier with libcrypt

In the first case, all is OK and we are in a situation similar to the
internal toolchain, but in the latter two cases, we end up with a
conflict.

We could introduce BR2_TOOLCHAIN_EXTERNAL_HAS_LIBCRYPT os something
along those lines, but this is going to be a bit complex on packages,
which would have to select LIBXCRYPT if GLIBC && !_HAS_LIBCRYPT.

So, to simplify things, we want to get the external toolchains into a
situation similar to the internal one, where libcrypt is not provided by
the toolchain; packages have to select libxcrypt for glibc toolchains,
without having to care whether this is an internal or external toolchain
or some more complex conditions.

So, we remove from staging whatever could be used to compile and link
with libcrypt. We however keep the SO_NAME file, if it exists, and we
also install it in target/, for those pre-built binaries that may be
linked with it [1]. The glibc SO_NAME has always been libcrypt.so.1, so
this is what we copy exactly, to avoid copying the libxcrypt one, which
is libcrypt.so.2.

[0] that could happen if a toolchain provider tried to be helpful and
suplies a toolchain with libxcrypt to be trasnparent to users, in which
case that would conflict with ours...

[1] if such a prebuilt binary (executable or library) is used with a
glibc 2.39 or later toolchain, it will obviously not work at all.
libxcrypt is supposed to be a drop-in replacement for glibc's libcrypt,
so we could look into symlinking libcrypt.so.1 to libcrypt.so.2. In a
later patch, maybe...

Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Cc: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
1 file changed