cross/crossdirect: support rust (!845)

Use the native rustc cross compiler where possible, and fall back to the
qemu rustc if necessary. This should improve speed and reliability.
Without this patch, building squeekbox 1.4.0 for aarch64 with the
pmbootstrap stack just hangs forever.

Related: pmbootstrap#1861
This commit is contained in:
Oliver Smith 2020-01-02 16:16:20 +01:00 committed by Daniele Debernardi
parent fc8b9c39fa
commit f329c8f5ac
No known key found for this signature in database
GPG key ID: 5782FCF5DAE9AF60
3 changed files with 80 additions and 8 deletions

View file

@ -5,22 +5,25 @@
# #
# /native/usr/lib/crossdirect/armhf/gcc # /native/usr/lib/crossdirect/armhf/gcc
# -> /native/usr/bin/armv6-alpine-linux-muslgnueabihf-gcc # -> /native/usr/bin/armv6-alpine-linux-muslgnueabihf-gcc
# /native/usr/lib/crossdirect/armhf/rustc
# -> /native/usr/bin/rustc --target=armv6-alpine-linux-musleabihf ...
# #
# When building packages in the armhf chroot, PATH will get prepended with # When building packages in the armhf chroot, PATH will get prepended with
# "/native/usr/lib/crossdirect/armhf". The end game is of course invoking the # "/native/usr/lib/crossdirect/armhf". The end game is of course invoking the
# cross compiler from the native chroot, running at native speed, whenever # cross compiler from the native chroot, running at native speed, whenever
# calling the compiler from the foreign arch chroot. See crossdirect.c for # calling the compiler from the foreign arch chroot. See crossdirect.c for
# implementation details (llvm, fakeroot, rpath). # implementation details of the C version (llvm, fakeroot, rpath). The rust
# version is implemented as simple shell wrappers.
pkgname=crossdirect pkgname=crossdirect
pkgver=3 pkgver=4
pkgrel=1 pkgrel=0
pkgdesc="Wrappers to launch native cross compilers in foreign chroots" pkgdesc="Wrappers to launch native cross compilers in foreign chroots"
url="https://postmarketOS.org" url="https://postmarketOS.org"
arch="all" arch="all"
license="MIT" license="MIT"
options="" options="!check"
source="crossdirect.c" source="crossdirect.c rustc.sh rust-qemu-linker.sh"
build() { build() {
cd "$srcdir" cd "$srcdir"
@ -37,6 +40,9 @@ build() {
-Werror \ -Werror \
-DHOSTSPEC="\"$_hostspec\"" \ -DHOSTSPEC="\"$_hostspec\"" \
crossdirect.c crossdirect.c
# rustc
sed "s/@ARCH@/$_arch/g" rustc.sh >rustc-"$_arch"
done done
} }
@ -45,22 +51,32 @@ package() {
_archs="x86_64 armhf armv7 aarch64" _archs="x86_64 armhf armv7 aarch64"
_bins="c++ cc cpp g++ gcc clang clang++" _bins="c++ cc cpp g++ gcc clang clang++"
# Rust: qemu-linker
install -Dm755 "$srcdir/rust-qemu-linker.sh" \
"$pkgdir/usr/lib/crossdirect/rust-qemu-linker"
# Iterate over architectures # Iterate over architectures
for _arch in $_archs; do for _arch in $_archs; do
[ "$_arch" == "$CARCH" ] && continue [ "$_arch" == "$CARCH" ] && continue
# Put arch-specific crossdirect wrapper in arch-specific bin folder # GCC: put arch-specific crossdirect wrapper in arch-specific
# bin folder
_bindir="$pkgdir/usr/lib/crossdirect/$_arch" _bindir="$pkgdir/usr/lib/crossdirect/$_arch"
_hostspec="$(arch_to_hostspec $_arch)" _hostspec="$(arch_to_hostspec $_arch)"
mkdir -p "$_bindir" mkdir -p "$_bindir"
cd "$_bindir" cd "$_bindir"
cp "$srcdir/crossdirect-$_arch" "./" cp "$srcdir/crossdirect-$_arch" "./"
# Create compiler symlinks # GCC: create compiler symlinks
for _bin in $_bins; do for _bin in $_bins; do
ln -s "crossdirect-$_arch" "$_bin" ln -s "crossdirect-$_arch" "$_bin"
ln -s "crossdirect-$_arch" "$_hostspec-$_bin" ln -s "crossdirect-$_arch" "$_hostspec-$_bin"
done done
# Rust: arch-specific rustc wrapper
install -Dm755 "$srcdir/rustc-$_arch" "$_bindir/rustc"
done done
} }
sha512sums="20b963322820de038257304c1eefa85767b78e242eda7459f06d70a1cfae5540a445aa7d5587024bf4d88a4bee28120ef9f5c2d24a648e71b542b9618318deb2 crossdirect.c" sha512sums="20b963322820de038257304c1eefa85767b78e242eda7459f06d70a1cfae5540a445aa7d5587024bf4d88a4bee28120ef9f5c2d24a648e71b542b9618318deb2 crossdirect.c
c3492cf2bbf282d22585fb485a8a8950ddbd6e47faff472931072defa9c33ea757b72d455b2d608304c7e40f9c736fac2b9101b65accd48ad896bc7055ef0436 rustc.sh
ea9bf8db3810d03d0a7395057f3d6e57f7127d87c55deaedc171c255288f5f3cc6fbcc680a5a1b92786cf573875d5dc22521173799fe2639acc97d0715ff905b rust-qemu-linker.sh"

View file

@ -0,0 +1,8 @@
#!/bin/sh -e
# This wrapper gets called from the native rustc, and runs the qemu gcc for
# linking, with LD_LIBRARY_PATH reset so it does not point to /native anymore.
# It isn't possible to use the native cross compiler's linker with crossdirect
# currently (pmaports#233).
LD_LIBRARY_PATH=/lib:/usr/lib \
gcc "$@"

View file

@ -0,0 +1,48 @@
#!/bin/sh -e
rust_triplet() {
# Find the triplets in Alpine's rust APKBUILD or with:
# pmbootstrap chroot -barmhf --add=rust -- ls /usr/lib/rustlib
case "$1" in
x86_64)
echo "x86_64-alpine-linux-musl"
;;
armhf)
echo "arm-unknown-linux-musleabihf"
;;
armv7)
echo "armv7-unknown-linux-musleabihf"
;;
aarch64)
echo "aarch64-unknown-linux-musl"
;;
*)
echo "ERROR: don't know the rust triple for $1!" >&2
exit 1
;;
esac
}
arch="@ARCH@" # filled in by APKBUILD
if ! LD_LIBRARY_PATH=/native/lib:/native/usr/lib \
/native/usr/bin/rustc \
-Clinker=/native/usr/lib/crossdirect/rust-qemu-linker \
--target=$(rust_triplet "$arch") \
--sysroot=/usr \
"$@"; then
echo "---" >&2
echo "WARNING: crossdirect: cross compiling with rustc failed, trying"\
"again with rustc + qemu" >&2
echo "---" >&2
# Usually the crossdirect approach works; however, when passing
# --extern to rustc with a dynamic library (.so), it fails with an
# error like 'can't find crate for `serde_derive`' (although the crate
# does exist). I think it fails to parse the metadata of the so file
# for some reason. We probably need to adjust rustc's
# librustc_metadata/locator.rs or something (and upstream that
# change!), but I've spent enough time on this already. Let's simply
# fall back to compiling in qemu in the very few cases where this is
# necessary.
/usr/bin/rustc "$@"
fi