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

Add support for emscripten targets #106

Merged
merged 6 commits into from
Jun 10, 2017
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ matrix:
- env: TARGET=x86_64-pc-windows-gnu CPP=1 STD=1 RUN=1
- env: TARGET=i686-pc-windows-gnu CPP=1 STD=1 RUN=1

# Emscripten
- env: TARGET=asmjs-unknown-emscripten CPP=1 STD=1 RUN=1
- env: TARGET=wasm32-unknown-emscripten CPP=1 STD=1 RUN=1

# Bare metal
- env: TARGET=thumbv6m-none-eabi RUN=1
- env: TARGET=thumbv7em-none-eabi RUN=1
Expand Down
74 changes: 39 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,41 +154,43 @@ because QEMU gets upset when you spawn several threads. This also means that, if
one of your unit tests spawns several threads then it's more likely to fail or,
worst, "hang" (never terminate).

| Target | libc | GCC | OpenSSL | C++ | QEMU | `test` |
|--------------------------------------|--------|-------|---------|:---:|-------|:------:|
| `aarch64-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `aarch64-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `arm-linux-androideabi` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `arm-unknown-linux-gnueabi` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `arm-unknown-linux-musleabi` | 1.1.15 | 5.3.1 | N/A | | 2.8.0 | ✓ |
| `armv7-linux-androideabi` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `armv7-unknown-linux-gnueabihf` | 2.15 | 4.6.2 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `armv7-unknown-linux-musleabihf` | 1.1.15 | 5.3.1 | N/A | | 2.8.0 | ✓ |
| `i686-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `i686-pc-windows-gnu` | N/A | 6.2.0 | N/A | ✓ | N/A | ✓ |
| `i686-unknown-freebsd` [1] | 10.2 | 5.3.0 | 1.0.2k | | N/A | |
| `i686-unknown-linux-gnu` | 2.15 | 4.6.2 | 1.0.2k | ✓ | N/A | ✓ |
| `i686-unknown-linux-musl` | 1.1.15 | 5.3.1 | N/A | | N/A | ✓ |
| `mips-unknown-linux-gnu` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `mips64-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `mips64el-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `mipsel-unknown-linux-gnu` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `powerpc-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.7.1 | ✓ |
| `powerpc64-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.7.1 | ✓ |
| `powerpc64le-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.7.1 | ✓ |
| `s390x-unknown-linux-gnu` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | |
| `sparc64-unknown-linux-gnu` [2] | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `thumbv6m-none-eabi` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `thumbv7em-none-eabi` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `thumbv7em-none-eabihf` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `thumbv7m-none-eabi` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `x86_64-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `x86_64-pc-windows-gnu` | N/A | 6.2.0 | N/A | ✓ | N/A | ✓ |
| `x86_64-unknown-dragonfly` [1] [2] | 4.6.0 | 5.3.0 | 1.0.2k | | N/A | ✓ |
| `x86_64-unknown-freebsd` [1] | 10.2 | 5.3.0 | 1.0.2k | | N/A | |
| `x86_64-unknown-linux-gnu` | 2.15 | 4.6.2 | 1.0.2k | ✓ | N/A | ✓ |
| `x86_64-unknown-linux-musl` | 1.1.15 | 5.3.1 | 1.0.2k | | N/A | ✓ |
| `x86_64-unknown-netbsd`[1] | 7.0 | 5.3.0 | 1.0.2k | | N/A | |
| Target | libc | GCC | OpenSSL | C++ | QEMU | `test` |
|--------------------------------------|--------|---------|---------|:---:|-------|:------:|
| `aarch64-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `aarch64-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `arm-linux-androideabi` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `arm-unknown-linux-gnueabi` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `arm-unknown-linux-musleabi` | 1.1.15 | 5.3.1 | N/A | | 2.8.0 | ✓ |
| `armv7-linux-androideabi` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `armv7-unknown-linux-gnueabihf` | 2.15 | 4.6.2 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `armv7-unknown-linux-musleabihf` | 1.1.15 | 5.3.1 | N/A | | 2.8.0 | ✓ |
| `asmjs-unknown-emscripten` [4] | 1.1.15 | 1.37.13 | N/A | ✓ | N/A | ✓ |
| `i686-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `i686-pc-windows-gnu` | N/A | 6.2.0 | N/A | ✓ | N/A | ✓ |
| `i686-unknown-freebsd` [1] | 10.2 | 5.3.0 | 1.0.2k | | N/A | |
| `i686-unknown-linux-gnu` | 2.15 | 4.6.2 | 1.0.2k | ✓ | N/A | ✓ |
| `i686-unknown-linux-musl` | 1.1.15 | 5.3.1 | N/A | | N/A | ✓ |
| `mips-unknown-linux-gnu` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `mips64-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `mips64el-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `mipsel-unknown-linux-gnu` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `powerpc-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.7.1 | ✓ |
| `powerpc64-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.7.1 | ✓ |
| `powerpc64le-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.7.1 | ✓ |
| `s390x-unknown-linux-gnu` | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | |
| `sparc64-unknown-linux-gnu` [2] | 2.23 | 5.3.1 | 1.0.2k | ✓ | 2.8.0 | ✓ |
| `thumbv6m-none-eabi` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `thumbv7em-none-eabi` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `thumbv7em-none-eabihf` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `thumbv7m-none-eabi` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | |
| `wasm32-unknown-emscripten` [4] | 1.1.15 | 1.37.13 | N/A | ✓ | N/A | ✓ |
| `x86_64-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | |
| `x86_64-pc-windows-gnu` | N/A | 6.2.0 | N/A | ✓ | N/A | ✓ |
| `x86_64-unknown-dragonfly` [1] [2] | 4.6.0 | 5.3.0 | 1.0.2k | | N/A | ✓ |
| `x86_64-unknown-freebsd` [1] | 10.2 | 5.3.0 | 1.0.2k | | N/A | |
| `x86_64-unknown-linux-gnu` | 2.15 | 4.6.2 | 1.0.2k | ✓ | N/A | ✓ |
| `x86_64-unknown-linux-musl` | 1.1.15 | 5.3.1 | 1.0.2k | | N/A | ✓ |
| `x86_64-unknown-netbsd`[1] | 7.0 | 5.3.0 | 1.0.2k | | N/A | |

[1] For *BSD targets, the libc column indicates the OS release version from
where libc was extracted.
Expand All @@ -197,6 +199,8 @@ where libc was extracted.

[3] libc = newlib

[4] libc = musl, gcc = emcc

## Debugging

### QEMU_STRACE (v0.1.9+)
Expand Down
11 changes: 11 additions & 0 deletions ci/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ EOF
cross build --target $TARGET
popd

rm -rf $td
elif [ "$TARGET" = "asmjs-unknown-emscripten" -o \
"$TARGET" = "wasm32-unknown-emscripten" ]; then
td=$(mktemp -d)

git clone --depth 1 https://github.com/bluss/rust-itertools $td

pushd $td
cross build --target $TARGET
popd

rm -rf $td
else
td=$(mktemp -d)
Expand Down
20 changes: 20 additions & 0 deletions docker/asmjs-unknown-emscripten/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM ubuntu:16.04

RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
cmake \
gcc \
libc6-dev \
make \
pkg-config

RUN apt-get install -y --no-install-recommends python

COPY emscripten.sh /
RUN bash /emscripten.sh

COPY emscripten-entry.sh /
ENTRYPOINT ["/emscripten-entry.sh"]

ENV CARGO_TARGET_ASMJS_UNKNOWN_EMSCRIPTEN_RUNNER=node
11 changes: 11 additions & 0 deletions docker/emscripten-entry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

set -e

export HOME=/tmp/

cp /emsdk-portable/.emscripten $HOME/

source /emsdk-portable/emsdk_env.sh &> /dev/null

exec "$@"
54 changes: 54 additions & 0 deletions docker/emscripten.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
set -ex

main() {
local dependencies=(
ca-certificates
cmake
curl
git
python
)

apt-get update
local purge_list=()
for dep in ${dependencies[@]}; do
if ! dpkg -L $dep; then
apt-get install --no-install-recommends -y $dep
purge_list+=( $dep )
fi
done

cd /
curl -L https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz | \
tar -xz
cd /emsdk-portable

./emsdk update
./emsdk install latest
./emsdk activate latest

# Make emsdk usable by any user
cp /root/.emscripten /emsdk-portable
chmod a+r -R /emsdk-portable/
chmod a+x /emsdk-portable/emsdk
chmod a+xw /emsdk-portable/

# Compile and cache libc
source ./emsdk_env.sh
echo "main(){}" > a.c
emcc a.c
emcc -s BINARYEN=1 a.c
echo -e "#include <iostream>\n void hello(){ std::cout << std::endl; }" > a.cpp
emcc a.cpp
emcc -s BINARYEN=1 a.cpp
rm -f a.*
chmod a+rw -R /emsdk-portable/.emscripten_cache/
rm /emsdk-portable/.emscripten_cache.lock

# Clean up
apt-get purge --auto-remove -y ${purge_list[@]}

rm $0
}

main "${@}"
19 changes: 19 additions & 0 deletions docker/node-wasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

path="$(dirname $1)"
file="$(basename $1)"

# Workaround for
# https://github.com/kripken/emscripten/issues/4542

if [ "$(basename $path)" != "deps" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a comment here indicating what kind of paths we expect to see here and why we have to branch here and in the if below?

path="$path/deps"
fi

cd "$path"

if [ -f "$file" ]; then
/node-*/bin/node "$file"
else
/node-*/bin/node "../$file"
fi
28 changes: 28 additions & 0 deletions docker/node.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
set -ex

main() {
local dependencies=(
ca-certificates
curl
)

apt-get update
local purge_list=()
for dep in ${dependencies[@]}; do
if ! dpkg -L $dep; then
apt-get install --no-install-recommends -y $dep
purge_list+=( $dep )
fi
done

cd /
curl -L https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
tar -xJ

# Clean up
apt-get purge --auto-remove -y ${purge_list[@]}

rm $0
}

main "${@}"
24 changes: 24 additions & 0 deletions docker/wasm32-unknown-emscripten/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM ubuntu:16.04

RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
cmake \
gcc \
libc6-dev \
make \
pkg-config

RUN apt-get install -y --no-install-recommends python

COPY emscripten.sh /
RUN bash /emscripten.sh

COPY node.sh /
RUN bash /node.sh

COPY emscripten-entry.sh /
ENTRYPOINT ["/emscripten-entry.sh"]

COPY node-wasm /usr/local/bin/
ENV CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER=node-wasm
18 changes: 17 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ pub enum Target {
X86_64PcWindowsGnu,
I686PcWindowsGnu,

// Emscripten
AsmjsUnknownEmscripten,
Wasm32UnknownEmscripten,

// Bare metal
Thumbv6mNoneEabi,
Thumbv7emNoneEabi,
Expand Down Expand Up @@ -168,6 +172,14 @@ impl Target {
}
}

fn is_emscripten(&self) -> bool {
match *self {
Target::AsmjsUnknownEmscripten |
Target::Wasm32UnknownEmscripten => true,
_ => false,
}
}

fn is_linux(&self) -> bool {
match *self {
Target::Aarch64UnknownLinuxGnu |
Expand Down Expand Up @@ -202,7 +214,7 @@ impl Target {

fn needs_docker(&self) -> bool {
self.is_linux() || self.is_android() || self.is_bare_metal() || self.is_bsd() ||
!self.is_builtin() || self.is_windows()
!self.is_builtin() || self.is_windows() || self.is_emscripten()
}

fn needs_interpreter(&self) -> bool {
Expand Down Expand Up @@ -237,6 +249,7 @@ impl Target {
Armv7LinuxAndroideabi => "armv7-linux-androideabi",
Armv7UnknownLinuxGnueabihf => "armv7-unknown-linux-gnueabihf",
Armv7UnknownLinuxMusleabihf => "armv7-unknown-linux-musleabihf",
AsmjsUnknownEmscripten => "asmjs-unknown-emscripten",
I686AppleDarwin => "i686-apple-darwin",
I686LinuxAndroid => "i686-linux-android",
I686PcWindowsGnu => "i686-pc-windows-gnu",
Expand All @@ -256,6 +269,7 @@ impl Target {
Thumbv7emNoneEabi => "thumbv7em-none-eabi",
Thumbv7emNoneEabihf => "thumbv7em-none-eabihf",
Thumbv7mNoneEabi => "thumbv7m-none-eabi",
Wasm32UnknownEmscripten => "wasm32-unknown-emscripten",
X86_64AppleDarwin => "x86_64-apple-darwin",
X86_64PcWindowsGnu => "x86_64-pc-windows-gnu",
X86_64LinuxAndroid => "x86_64-linux-android",
Expand Down Expand Up @@ -285,6 +299,7 @@ impl Target {
"armv7-linux-androideabi" => Armv7LinuxAndroideabi,
"armv7-unknown-linux-gnueabihf" => Armv7UnknownLinuxGnueabihf,
"armv7-unknown-linux-musleabihf" => Armv7UnknownLinuxMusleabihf,
"asmjs-unknown-emscripten" => AsmjsUnknownEmscripten,
"i686-apple-darwin" => I686AppleDarwin,
"i686-linux-android" => I686LinuxAndroid,
"i686-pc-windows-gnu" => I686PcWindowsGnu,
Expand All @@ -304,6 +319,7 @@ impl Target {
"thumbv7em-none-eabi" => Thumbv7emNoneEabi,
"thumbv7em-none-eabihf" => Thumbv7emNoneEabihf,
"thumbv7m-none-eabi" => Thumbv7mNoneEabi,
"wasm32-unknown-emscripten" => Wasm32UnknownEmscripten,
"x86_64-apple-darwin" => X86_64AppleDarwin,
"x86_64-linux-android" => X86_64LinuxAndroid,
"x86_64-pc-windows-gnu" => X86_64PcWindowsGnu,
Expand Down