diff --git a/cross/crossdirect/APKBUILD b/cross/crossdirect/APKBUILD index 48491777b..734f95ed1 100644 --- a/cross/crossdirect/APKBUILD +++ b/cross/crossdirect/APKBUILD @@ -5,22 +5,25 @@ # # /native/usr/lib/crossdirect/armhf/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 # "/native/usr/lib/crossdirect/armhf". The end game is of course invoking the # cross compiler from the native chroot, running at native speed, whenever # 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 -pkgver=3 -pkgrel=1 +pkgver=4 +pkgrel=0 pkgdesc="Wrappers to launch native cross compilers in foreign chroots" url="https://postmarketOS.org" arch="all" license="MIT" -options="" -source="crossdirect.c" +options="!check" +source="crossdirect.c rustc.sh rust-qemu-linker.sh" build() { cd "$srcdir" @@ -37,6 +40,9 @@ build() { -Werror \ -DHOSTSPEC="\"$_hostspec\"" \ crossdirect.c + + # rustc + sed "s/@ARCH@/$_arch/g" rustc.sh >rustc-"$_arch" done } @@ -45,22 +51,32 @@ package() { _archs="x86_64 armhf armv7 aarch64" _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 for _arch in $_archs; do [ "$_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" _hostspec="$(arch_to_hostspec $_arch)" mkdir -p "$_bindir" cd "$_bindir" cp "$srcdir/crossdirect-$_arch" "./" - # Create compiler symlinks + # GCC: create compiler symlinks for _bin in $_bins; do ln -s "crossdirect-$_arch" "$_bin" ln -s "crossdirect-$_arch" "$_hostspec-$_bin" done + + # Rust: arch-specific rustc wrapper + install -Dm755 "$srcdir/rustc-$_arch" "$_bindir/rustc" done } -sha512sums="20b963322820de038257304c1eefa85767b78e242eda7459f06d70a1cfae5540a445aa7d5587024bf4d88a4bee28120ef9f5c2d24a648e71b542b9618318deb2 crossdirect.c" +sha512sums="20b963322820de038257304c1eefa85767b78e242eda7459f06d70a1cfae5540a445aa7d5587024bf4d88a4bee28120ef9f5c2d24a648e71b542b9618318deb2 crossdirect.c +c3492cf2bbf282d22585fb485a8a8950ddbd6e47faff472931072defa9c33ea757b72d455b2d608304c7e40f9c736fac2b9101b65accd48ad896bc7055ef0436 rustc.sh +ea9bf8db3810d03d0a7395057f3d6e57f7127d87c55deaedc171c255288f5f3cc6fbcc680a5a1b92786cf573875d5dc22521173799fe2639acc97d0715ff905b rust-qemu-linker.sh" diff --git a/cross/crossdirect/rust-qemu-linker.sh b/cross/crossdirect/rust-qemu-linker.sh new file mode 100644 index 000000000..7f0136101 --- /dev/null +++ b/cross/crossdirect/rust-qemu-linker.sh @@ -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 "$@" diff --git a/cross/crossdirect/rustc.sh b/cross/crossdirect/rustc.sh new file mode 100644 index 000000000..f3249077f --- /dev/null +++ b/cross/crossdirect/rustc.sh @@ -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