diff --git a/cross/crossdirect/APKBUILD b/cross/crossdirect/APKBUILD index 4a04ee5da..181673366 100644 --- a/cross/crossdirect/APKBUILD +++ b/cross/crossdirect/APKBUILD @@ -16,14 +16,14 @@ # version is implemented as simple shell wrappers. pkgname=crossdirect -pkgver=4 -pkgrel=3 +pkgver=5 +pkgrel=0 pkgdesc="Wrappers to launch native cross compilers in foreign chroots" url="https://postmarketOS.org" arch="all" license="MIT" options="!check" -source="crossdirect.c rustc.sh rust-qemu-linker.sh" +source="cargo.sh crossdirect.c rustc.sh rust-qemu-linker.sh" build() { cd "$srcdir" @@ -40,9 +40,6 @@ build() { -Werror \ -DHOSTSPEC="\"$_hostspec\"" \ crossdirect.c - - # rustc - sed "s/@ARCH@/$_arch/g" rustc.sh >rustc-"$_arch" done } @@ -51,9 +48,11 @@ package() { _archs="x86_64 armhf armv7 aarch64" _bins="c++ cc cpp g++ gcc clang clang++" - # Rust: qemu-linker + # Rust wrappers install -Dm755 "$srcdir/rust-qemu-linker.sh" \ "$pkgdir/usr/lib/crossdirect/rust-qemu-linker" + install -Dm755 "$srcdir/cargo.sh" "$pkgdir/usr/lib/crossdirect/cargo.sh" + install -Dm755 "$srcdir/rustc.sh" "$pkgdir/usr/lib/crossdirect/rustc.sh" # Iterate over architectures for _arch in $_archs; do @@ -73,10 +72,13 @@ package() { ln -s "crossdirect-$_arch" "$_hostspec-$_bin" done - # Rust: arch-specific rustc wrapper - install -Dm755 "$srcdir/rustc-$_arch" "$_bindir/rustc" + ln -s ../cargo.sh cargo + ln -s ../rustc.sh rustc done } -sha512sums="500107e5aff8b34e74b54982ebcd447fc41bc8283956d506561b031a055cb30ec12698047c2604918b4b6d8560fe03db427a63dff2b83c907e8494b7f5233f29 crossdirect.c -6be16ba88720e628a3ecc8fa53f8e7a21d2af268b0509745d989139874d6b94b640bfcff09575eaa19073810be6ef91169c1f83e94f5cf8e6819f2670d9408de rustc.sh -ea9bf8db3810d03d0a7395057f3d6e57f7127d87c55deaedc171c255288f5f3cc6fbcc680a5a1b92786cf573875d5dc22521173799fe2639acc97d0715ff905b rust-qemu-linker.sh" +sha512sums=" +0f4b48f250425dc57f63955fc8b38477d23db793bee367c3fbe03c3d2a559ba576434d07518310db4cae9d90d501af4051b80038b10fae94b980e537fc9374ad cargo.sh +500107e5aff8b34e74b54982ebcd447fc41bc8283956d506561b031a055cb30ec12698047c2604918b4b6d8560fe03db427a63dff2b83c907e8494b7f5233f29 crossdirect.c +2c41410a9ef2dab31403545e55e2464f2ee4e7056ffbcd3bc5810d582311801496b88d55307f17ce6acf766e9c867d30d05f2b0d8d46bf77a5e8f0495d6bc24e rustc.sh +ea9bf8db3810d03d0a7395057f3d6e57f7127d87c55deaedc171c255288f5f3cc6fbcc680a5a1b92786cf573875d5dc22521173799fe2639acc97d0715ff905b rust-qemu-linker.sh +" diff --git a/cross/crossdirect/cargo.sh b/cross/crossdirect/cargo.sh new file mode 100644 index 000000000..d29b40fc1 --- /dev/null +++ b/cross/crossdirect/cargo.sh @@ -0,0 +1,66 @@ +#!/bin/sh -e + +if [ -n "$CROSSDIRECT_DEBUG" ]; then + set -x +fi + +native_version=$(LD_LIBRARY_PATH=/native/lib:/native/usr/lib /native/usr/bin/rustc -V) +target_version=$(/usr/bin/rustc -V) + +if [ "$target_version" != "$native_version" ]; then + echo "ERROR: crossdirect: rustc version mismatch between native and build chroot. Please update your chroots and try again." >&2 + exit 1 +fi + +triplet=$(/usr/bin/rustc -vV | sed -n 's/host: //p') +cmd=$1 +shift + +case "$cmd" in + build|test|run) + ;; + *) + echo "WARNING: crossdirect: 'cargo $cmd $*' command not supported, running in QEMU (slow!)" >&2 + export PATH="$(echo "$PATH" | sed 's,/native/usr/lib/crossdirect/[^:]*:,,')" + exec /usr/bin/cargo "$cmd" "$@" + ;; +esac + +target_dir=${CARGO_TARGET_DIR:-target} +target_already_specified=${CARGO_BUILD_TARGET:+1} + +if [ -z "$target_specified" ]; then + for arg in "$@"; do + if [ "$arg_target_dir" = 1 ]; then + target_dir=$arg + arg_target_dir=0 + fi + case "$arg" in + --target|--target=*) + target_already_specified=1 + break + ;; + --target-dir) + arg_target_dir=1 + ;; + --target-dir=*) + target_dir=${arg##--target-dir=} + ;; + esac + done +fi + +if [ -n "$target_already_specified" ]; then + exec /usr/bin/cargo "$cmd" "$@" +fi + +/usr/bin/cargo "$cmd" --target=$triplet "$@" + +# copy target/$triplet/{release,debug,...} to target/{release,debug,...} +if [ -d "$target_dir/$triplet" ]; then + for dir in "$target_dir/$triplet"/*/; do + build=$(basename "$dir") + rm -rf "$target_dir/$build" + cp -r "$target_dir/$triplet/$build" "$target_dir/$build" + done +fi diff --git a/cross/crossdirect/rustc.sh b/cross/crossdirect/rustc.sh index 9402c727e..64835838e 100644 --- a/cross/crossdirect/rustc.sh +++ b/cross/crossdirect/rustc.sh @@ -1,48 +1,26 @@ #!/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 "armv6-alpine-linux-musleabihf" - ;; - armv7) - echo "armv7-alpine-linux-musleabihf" - ;; - aarch64) - echo "aarch64-alpine-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 "$@" +if [ -n "$CROSSDIRECT_DEBUG" ]; then + set -x +fi + +# return the correct host architecture when cargo requests it +if [ "$*" = "-vV" ]; then + exec /usr/bin/rustc -vV +fi + +# We expect the right target to be set in the arguments if compiling for the +# target architecture. Our cargo wrapper passes the right "--target" argument +# automatically. If no target is provided, this is probably a macro or a +# build script, so it should be compiled for the native architecture. +if echo "$*" | grep -qFe "--target"; then + LD_LIBRARY_PATH=/native/lib:/native/usr/lib /native/usr/bin/rustc \ + -Clinker=/native/usr/lib/crossdirect/rust-qemu-linker \ + --sysroot=/usr \ + "$@" +else + PATH=/native/usr/bin:/native/bin LD_LIBRARY_PATH=/native/lib:/native/usr/lib \ + /native/usr/bin/rustc \ + -Clink-arg=-Wl,-rpath,/native/lib:/native/usr/lib \ + "$@" fi