Files
rpi-buildroot/toolchain
Yann E. MORIN 28694dcec7 toolchain/external: support merged-bin
When an external toolchain does not have a merged-bin, we can end up
with a situation where the toolchain installs an staging/usr/sbin/
directory, overriding the sbin symlink with an actual directory. When
not using PPD, this does not cause any harm.

However, with PPD, the build fails when preparing the staging (the
host/) for packages when the skeleton is eventually rsynced, e.g.:

    $ cat defconfig
    BR2_aarch64=y
    BR2_TOOLCHAIN_EXTERNAL=y
    BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y
    BR2_PER_PACKAGE_DIRECTORIES=y
    BR2_INIT_NONE=y
    BR2_ROOTFS_MERGED_USR=y
    BR2_ROOTFS_MERGED_SBIN=y
    # BR2_PACKAGE_BUSYBOX is not set
    BR2_PACKAGE_ZLIB=y
    # BR2_TARGET_ROOTFS_TAR is not set

    $ make zlib
    [...]
    >>> zlib  Configuring
    mkdir -p [...]/per-package/zlib/host
    rsync -a --hard-links --link-dest=[...]/per-package/host-skeleton/host/ [...]/per-package/host-skeleton/host/ [...]/per-package/zlib/host
    rsync -a --hard-links --link-dest=[...]/per-package/libzlib/host/ [...]/per-package/libzlib/host/ [...]/per-package/zlib/host
    rsync -a --hard-links --link-dest=[...]/per-package/skeleton/host/ [...]/per-package/skeleton/host/ [...]/per-package/zlib/host
    could not make way for new symlink: aarch64-buildroot-linux-gnu/sysroot/usr/sbin
    cannot delete non-empty directory: aarch64-buildroot-linux-gnu/sysroot/usr/sbin
    rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.3.0]
    make[1]: *** [package/pkg-generic.mk:256: [...]/build/zlib/.stamp_configured] Error 23
    make: *** [Makefile:23: _all] Error 2

The root cause is that, in the skeleton, we end up with
[staging]/usr/sbin as a synlink to bin, but when the external toolchain
gets installed, the symlinbk is replaced by a directory. Later, when we
aggregate the PPD before configuring a package, it often happens that a
dependant package be rsynced before the toolchain and the skeleton, as
seen above, in which case the sbin directory from the toolchain, by way
of the dependency to a package, is already present when rsync wants to
create a symlink as rsynced from the skeleton.

In the example above, this plays in this order:

 1. skeleton gets installed, provides a symlink
 2. toolchain-external-bootlin rsyncs from skeleton, gets a symlink
 3. toolchain-external-bootlin gets installed, replaces symlink with a
    directory
 4. libzlib rsyncs from skeleton, gets a symlink, then rsyncs from
    toolchain-e-b, gets a directory
 5. zlib rsyncs from libzlib first (because alphabetical ordering), gets
    a directory, then rsyncs from skeleton, which rsyncs from a symlink,
    but the destination is a non-empty directory, so rsync fails.

It is perfectly legit that an external toolchain does not use a
merged-bin setup, so we must accept that as input. We do so by treating
the /usr/sbin entry specially, like we already do for a few others, of
which /sbin itself for example.

Note that the merged-usr setup has no issue, because we already handle
the lib*/ directories specially too.

Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Giulio Benetti <giulio.benetti@benettiengineering.com>
Cc: Romain Naour <romain.naour@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
2025-11-05 23:10:29 +01:00
..