Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasm rust support #90

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,15 @@ RUN xx-cargo build --release --target-dir ./build && \
xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo
```

### WebAssembly

`xx-cargo` can also be used to build WebAssembly targets. Use platform `wasi/wasm` on your builds for `xx` to pick up the correct configuration. If your code is compatible you can use identical Dockerfile to build Linux and WebAssembly containers.

When using multi-stage builds to copy build results to other stages, note that Rust adds ".wasm" suffix to the binaries built with
WebAssembly.

Only Rust builds are supported at the moment. To build C/C++ code for WebAssembly using `xx-clang` your Dockerfile needs to set up Wasi Sysroot and `libclang-rt` itself.

## External SDK support

In addition to Linux targets, `xx` can also build binaries for MacOS and Windows. When building MacOS binaries from C, external MacOS SDK is needed in `/xx-sdk` directory. Such SDK can be built, for example, with [gen_sdk_package script in osxcross project](https://github.com/tpoechtrager/osxcross/blob/master/tools/gen_sdk_package.sh). Please consult XCode license terms when making such an image. `RUN --mount` syntax can be used in Dockerfile in order to avoid copying SDK files. No special tooling such as `ld64` linker is required in the image itself.
Expand Down
16 changes: 14 additions & 2 deletions base/test-cargo.bats
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ testHelloCargo() {
assert_success
run xx-cargo build --verbose --color=never --manifest-path=./fixtures/hello_cargo/Cargo.toml --release --target-dir /tmp/cargobuild
assert_success
xx-verify /tmp/cargobuild/$(xx-cargo --print-target-triple)/release/hello_cargo

if [ "$TARGETARCH" = "wasm" ]; then
sfx=".wasm"
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't like this hack but I can't see a way how to configure this in cargo. Maybe xx-cargo should scan for the target dir and create hardlink/symlink to the correct path?

fi
xx-verify /tmp/cargobuild/$(xx-cargo --print-target-triple)/release/hello_cargo$sfx
if ! xx-info is-cross; then
run /tmp/cargobuild/$(xx-cargo --print-target-triple)/release/hello_cargo
run /tmp/cargobuild/$(xx-cargo --print-target-triple)/release/hello_cargo$sfx
assert_success
assert_output "hello cargo"
fi
Expand Down Expand Up @@ -87,6 +91,14 @@ testHelloCargoRustup() {
testHelloCargoRustup
}

@test "wasm-hellocargo-rustup" {
export TARGETARCH=wasm
export TARGETOS=wasi
testHelloCargoRustup
unset TARGETOS
unset TARGETARCH
}

@test "uninstall-rustup" {
export PATH="$HOME/.cargo/bin:$PATH"
rustup self uninstall -y
Expand Down
7 changes: 7 additions & 0 deletions base/test-info-alpine.bats
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ load 'assert'
assert_equal "mips64le" "$(TARGETPLATFORM=linux/mips64le xx-info pkg-arch)"
}

@test "wasm" {
assert_equal "wasm32-alpine-wasi" "$(TARGETPLATFORM=wasi/wasm xx-info triple)"
assert_equal "wasm64-alpine-wasi" "$(TARGETPLATFORM=wasi/wasm64 xx-info triple)"
assert_equal "wasm32-alpine-wasi" "$(TARGETPLATFORM=wasi/wasm32 xx-info triple)"
assert_equal "wasm32" "$(TARGETPLATFORM=linux/wasm xx-info pkg-arch)"
}

@test "darwin" {
assert_equal "x86_64-apple-macos10.6" "$(TARGETPLATFORM=darwin/amd64 xx-info triple)"
assert_equal "darwin" "$(TARGETPLATFORM=darwin/amd64 xx-info os)"
Expand Down
7 changes: 7 additions & 0 deletions base/test-info-debian.bats
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ fi
assert_equal "mips64el" "$(TARGETPLATFORM=linux/mips64le xx-info pkg-arch)"
}

@test "wasm" {
assert_equal "wasm32-wasi" "$(TARGETPLATFORM=wasi/wasm xx-info triple)"
assert_equal "wasm64-wasi" "$(TARGETPLATFORM=wasi/wasm64 xx-info triple)"
assert_equal "wasm32-wasi" "$(TARGETPLATFORM=wasi/wasm32 xx-info triple)"
assert_equal "wasm32" "$(TARGETPLATFORM=linux/wasm xx-info pkg-arch)"
}

@test "sysroot" {
assert_equal "/" "$(xx-info sysroot)"
assert_equal "/" "$(TARGETPLATFORM=linux/amd64 xx-info sysroot)"
Expand Down
16 changes: 12 additions & 4 deletions base/xx-cargo
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ fi
vendor=$XX_VENDOR
if [ -n "$rustup" ] || [ ! -f /etc/alpine-release ]; then
export XX_VENDOR="unknown"
export XX_RUSTUP=1 # this sets the correct target triple for rust libraries for subsequent calls
fi

if [ ! -f "$done_file" ]; then
xx-clang --setup-target-triple
XX_RUSTUP="" xx-clang --setup-target-triple
if [ ! -d "$(rustc --print sysroot)/lib/rustlib/$(xx-info)" ]; then
if [ -n "$rustup" ]; then
execSilent rustup target add "$(xx-info)"
Expand All @@ -73,13 +74,20 @@ if [ ! -f "$done_file" ]; then
touch "$done_file"
fi

export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_LINKER=$(xx-info)-clang"
export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_LINKER=$(XX_RUSTUP='' XX_VENDOR='' xx-info)-clang"
if [ -n "$XX_RUSTFLAGS" ]; then
export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_RUSTFLAGS=$XX_RUSTFLAGS"
fi
export "CC_$(xx-info | tr - _)=$(xx-info)-clang"
export "CC_$(xx-info | tr - _)=$(XX_RUSTUP='' XX_VENDOR='' xx-info)-clang"

if which "qemu-$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info march)" >/dev/null 2>&1; then
if xx-info is-cross; then
nativeRustTriple="$(TARGETPLATFORM='' TARGETPAIR='' TARGETOS='' TARGETARCH='' TARGETVARIANT='' xx-info)"
nativeClangTriple="$(TARGETPLATFORM='' TARGETPAIR='' TARGETOS='' TARGETARCH='' TARGETVARIANT='' XX_RUSTUP='' XX_VENDOR='' xx-clang --print-target-triple)"
export "CARGO_TARGET_$(echo "$nativeRustTriple" | tr '[:lower:]' '[:upper:]' | tr - _)_LINKER=$nativeClangTriple-clang"
export "CC_$(echo "$nativeRustTriple" | tr - _)=$nativeClangTriple-clang"
fi

if which "qemu-$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info march)" >/dev/null 2>&1 && [ "$XX_OS" = "linux" ]; then
export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_RUNNER=qemu-$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info march)"
if [ -f /etc/alpine-release ]; then
export "QEMU_LD_PREFIX=/$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info)/"
Expand Down
38 changes: 36 additions & 2 deletions base/xx-info
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ distro=""
# shellcheck disable=SC1091
if . /etc/os-release 2>/dev/null; then
distro=$ID
XX_OS_VERSION=$VERSION_ID
if [ "$TARGETOS" = "linux" ] || [ "$TARGETOS" = "" ]; then
XX_OS_VERSION=$VERSION_ID
fi
fi

vendor=""
Expand All @@ -130,6 +132,10 @@ case "$XX_VENDOR" in
*) vendor="-${XX_VENDOR}" ;;
esac

if [ -n "$XX_RUSTUP" ] && [ "$TARGETOS" = "wasi" ]; then
vendor=""
fi

if [ -z "$XX_LIBC" ]; then
if [ "$distro" = "alpine" ]; then
XX_LIBC="musl"
Expand All @@ -139,6 +145,9 @@ if [ -z "$XX_LIBC" ]; then
if [ "$TARGETOS" = "windows" ]; then
XX_LIBC="mingw32"
fi
if [ "$TARGETOS" = "wasi" ]; then
XX_LIBC=""
fi
fi

# reverse lookup if no parameters given
Expand Down Expand Up @@ -208,6 +217,11 @@ if [ "$TARGETOS" = "darwin" ] && [ -z "$MACOSX_VERSION_MIN" ]; then
fi
fi

# normalize wasm because early implementation didn't have strict convention
if [ "$TARGETARCH" = "wasm32" ]; then
TARGETARCH="wasm"
fi

case "$TARGETARCH" in
"amd64")
XX_MARCH="x86_64"
Expand Down Expand Up @@ -337,6 +351,26 @@ case "$TARGETARCH" in
XX_RHEL_ARCH="mips64el"
XX_TRIPLE="mips64el${vendor}-linux-${XX_LIBC}abi64"
;;
"wasm")
XX_MARCH="wasm32"
XX_DEBIAN_ARCH="wasm32"
XX_ALPINE_ARCH="wasm32"
XX_RHEL_ARCH="wasm32"
XX_TRIPLE="wasm32${vendor}-unknown"
if [ "$TARGETOS" = "wasi" ]; then
XX_TRIPLE="wasm32${vendor}-wasi"
fi
;;
"wasm64")
XX_MARCH="wasm64"
XX_DEBIAN_ARCH="wasm64"
XX_ALPINE_ARCH="wasm64"
XX_RHEL_ARCH="wasm64"
XX_TRIPLE="wasm64${vendor}-unknown"
if [ "$TARGETOS" = "wasi" ]; then
XX_TRIPLE="wasm64${vendor}-wasi"
fi
;;
esac

XX_PKG_ARCH=$TARGETARCH
Expand Down Expand Up @@ -395,7 +429,7 @@ case "$1" in
echo "$XX_VENDOR"
;;
"libc") # this is not abi, just the prefix
echo $XX_LIBC
echo "$XX_LIBC"
;;
"env")
echo "XX_OS=${TARGETOS}"
Expand Down
6 changes: 6 additions & 0 deletions base/xx-verify
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ for f in "$@"; do
"windows")
expOS="MS Windows"
;;
"wasi")
expOS="WebAssembly"
;;
esac

if [ -z "$expOS" ]; then
Expand Down Expand Up @@ -226,6 +229,9 @@ for f in "$@"; do
expArch2="32-bit LSB"
fi
;;
"wasm" | "wasm64")
expArch="WebAssembly"
;;
esac

if [ -z "$expArch" ]; then
Expand Down