cross/crossdirect: improve rust handling (MR 4234)
Add a cargo wrapper which appends a --target argument to the command line. This makes cargo pass the --target argument to rustc for crates being built for the target architecture, even if the target is the same as the host. It will omit the --target argument for build scripts and crates used in macros. Check for this --target argument in the rustc wrapper and adjust the library paths depending on its presence. The fallback that runs rustc under qemu is no longer needed because macros are now built for the native architecture and can be loaded into the native compiler without any problems. Also check if the arguments passed to rustc are "-vV". If this is the case, we still need to fall back to the target rustc because the native rustc will return the wrong architecture. If the wrong host architecture is passed to a build script, it might try to look for a cross-compiler or do something else that doesn't work. [ci:skip-build]: already built successfully in CI
This commit is contained in:
parent
042d577de4
commit
f0286576e7
3 changed files with 103 additions and 57 deletions
|
@ -16,14 +16,14 @@
|
||||||
# version is implemented as simple shell wrappers.
|
# version is implemented as simple shell wrappers.
|
||||||
|
|
||||||
pkgname=crossdirect
|
pkgname=crossdirect
|
||||||
pkgver=4
|
pkgver=5
|
||||||
pkgrel=3
|
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="!check"
|
options="!check"
|
||||||
source="crossdirect.c rustc.sh rust-qemu-linker.sh"
|
source="cargo.sh crossdirect.c rustc.sh rust-qemu-linker.sh"
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
cd "$srcdir"
|
cd "$srcdir"
|
||||||
|
@ -40,9 +40,6 @@ build() {
|
||||||
-Werror \
|
-Werror \
|
||||||
-DHOSTSPEC="\"$_hostspec\"" \
|
-DHOSTSPEC="\"$_hostspec\"" \
|
||||||
crossdirect.c
|
crossdirect.c
|
||||||
|
|
||||||
# rustc
|
|
||||||
sed "s/@ARCH@/$_arch/g" rustc.sh >rustc-"$_arch"
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,9 +48,11 @@ 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
|
# Rust wrappers
|
||||||
install -Dm755 "$srcdir/rust-qemu-linker.sh" \
|
install -Dm755 "$srcdir/rust-qemu-linker.sh" \
|
||||||
"$pkgdir/usr/lib/crossdirect/rust-qemu-linker"
|
"$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
|
# Iterate over architectures
|
||||||
for _arch in $_archs; do
|
for _arch in $_archs; do
|
||||||
|
@ -73,10 +72,13 @@ package() {
|
||||||
ln -s "crossdirect-$_arch" "$_hostspec-$_bin"
|
ln -s "crossdirect-$_arch" "$_hostspec-$_bin"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Rust: arch-specific rustc wrapper
|
ln -s ../cargo.sh cargo
|
||||||
install -Dm755 "$srcdir/rustc-$_arch" "$_bindir/rustc"
|
ln -s ../rustc.sh rustc
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
sha512sums="500107e5aff8b34e74b54982ebcd447fc41bc8283956d506561b031a055cb30ec12698047c2604918b4b6d8560fe03db427a63dff2b83c907e8494b7f5233f29 crossdirect.c
|
sha512sums="
|
||||||
6be16ba88720e628a3ecc8fa53f8e7a21d2af268b0509745d989139874d6b94b640bfcff09575eaa19073810be6ef91169c1f83e94f5cf8e6819f2670d9408de rustc.sh
|
0f4b48f250425dc57f63955fc8b38477d23db793bee367c3fbe03c3d2a559ba576434d07518310db4cae9d90d501af4051b80038b10fae94b980e537fc9374ad cargo.sh
|
||||||
ea9bf8db3810d03d0a7395057f3d6e57f7127d87c55deaedc171c255288f5f3cc6fbcc680a5a1b92786cf573875d5dc22521173799fe2639acc97d0715ff905b rust-qemu-linker.sh"
|
500107e5aff8b34e74b54982ebcd447fc41bc8283956d506561b031a055cb30ec12698047c2604918b4b6d8560fe03db427a63dff2b83c907e8494b7f5233f29 crossdirect.c
|
||||||
|
2c41410a9ef2dab31403545e55e2464f2ee4e7056ffbcd3bc5810d582311801496b88d55307f17ce6acf766e9c867d30d05f2b0d8d46bf77a5e8f0495d6bc24e rustc.sh
|
||||||
|
ea9bf8db3810d03d0a7395057f3d6e57f7127d87c55deaedc171c255288f5f3cc6fbcc680a5a1b92786cf573875d5dc22521173799fe2639acc97d0715ff905b rust-qemu-linker.sh
|
||||||
|
"
|
||||||
|
|
66
cross/crossdirect/cargo.sh
Normal file
66
cross/crossdirect/cargo.sh
Normal file
|
@ -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
|
|
@ -1,48 +1,26 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
rust_triplet() {
|
if [ -n "$CROSSDIRECT_DEBUG" ]; then
|
||||||
# Find the triplets in Alpine's rust APKBUILD or with:
|
set -x
|
||||||
# pmbootstrap chroot -barmhf --add=rust -- ls /usr/lib/rustlib
|
fi
|
||||||
case "$1" in
|
|
||||||
x86_64)
|
# return the correct host architecture when cargo requests it
|
||||||
echo "x86_64-alpine-linux-musl"
|
if [ "$*" = "-vV" ]; then
|
||||||
;;
|
exec /usr/bin/rustc -vV
|
||||||
armhf)
|
fi
|
||||||
echo "armv6-alpine-linux-musleabihf"
|
|
||||||
;;
|
# We expect the right target to be set in the arguments if compiling for the
|
||||||
armv7)
|
# target architecture. Our cargo wrapper passes the right "--target" argument
|
||||||
echo "armv7-alpine-linux-musleabihf"
|
# automatically. If no target is provided, this is probably a macro or a
|
||||||
;;
|
# build script, so it should be compiled for the native architecture.
|
||||||
aarch64)
|
if echo "$*" | grep -qFe "--target"; then
|
||||||
echo "aarch64-alpine-linux-musl"
|
LD_LIBRARY_PATH=/native/lib:/native/usr/lib /native/usr/bin/rustc \
|
||||||
;;
|
-Clinker=/native/usr/lib/crossdirect/rust-qemu-linker \
|
||||||
*)
|
--sysroot=/usr \
|
||||||
echo "ERROR: don't know the rust triple for $1!" >&2
|
"$@"
|
||||||
exit 1
|
else
|
||||||
;;
|
PATH=/native/usr/bin:/native/bin LD_LIBRARY_PATH=/native/lib:/native/usr/lib \
|
||||||
esac
|
/native/usr/bin/rustc \
|
||||||
}
|
-Clink-arg=-Wl,-rpath,/native/lib:/native/usr/lib \
|
||||||
|
"$@"
|
||||||
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
|
fi
|
||||||
|
|
Loading…
Reference in a new issue