Skip to content

Commit 4de2d6e

Browse files
author
Jorge Aparicio
committed
support asmjs-unknown-emscripten and wasm32-unknown-emscripten
1 parent e89dae4 commit 4de2d6e

File tree

10 files changed

+236
-32
lines changed

10 files changed

+236
-32
lines changed

.travis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ sudo: required
66

77
matrix:
88
include:
9+
- env: TARGET=asmjs-unknown-emscripten
10+
- env: TARGET=wasm32-unknown-emscripten
911
- env: TARGET=aarch64-unknown-linux-gnu
1012
- env: TARGET=arm-unknown-linux-gnueabi
1113
- env: TARGET=armv7-unknown-linux-gnueabihf

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased]
77

8+
- Support for the `asmjs-unknown-emscripten` and `wasm32-unknown-emscripten`
9+
targets
10+
811
### Added
912

1013
- Support for the `arm-unknown-linux-gnueabi` target

README.md

+23-21
Original file line numberDiff line numberDiff line change
@@ -89,27 +89,29 @@ because QEMU gets upset when you spawn several threads. This also means that, if
8989
one of your unit tests spawns several threads then it's more likely to fail or,
9090
worst, "hang" (never terminate).
9191

92-
| Target | libc | GCC | QEMU | OpenSSL | `test` |
93-
|--------------------------------------|--------|-------|-------|---------|:------:|
94-
| `aarch64-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.8.0 | 1.0.2j ||
95-
| `arm-unknown-linux-gnueabi` | 2.19 | 4.8.2 | 2.8.0 | 1.0.2j ||
96-
| `armv7-unknown-linux-gnueabihf` | 2.15 | 4.6.2 | 2.8.0 | 1.0.2j ||
97-
| `i686-unknown-linux-gnu` | 2.15 | 4.6.2 | N/A | 1.0.2j ||
98-
| `i686-unknown-linux-musl` | 1.1.15 | 5.3.1 | N/A | N/A ||
99-
| `mips-unknown-linux-gnu` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
100-
| `mips64-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
101-
| `mips64el-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
102-
| `mipsel-unknown-linux-gnu` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
103-
| `powerpc-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.7.1 | 1.0.2j ||
104-
| `powerpc64-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.7.1 | 1.0.2j ||
105-
| `powerpc64le-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.7.1 | 1.0.2j ||
106-
| `s390x-unknown-linux-gnu` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j | |
107-
| `thumbv6m-none-eabi` | N/A | 5.3.1 | N/A | N/A | |
108-
| `thumbv7em-none-eabi` | N/A | 5.3.1 | N/A | N/A | |
109-
| `thumbv7em-none-eabihf` | N/A | 5.3.1 | N/A | N/A | |
110-
| `thumbv7m-none-eabi` | N/A | 5.3.1 | N/A | N/A | |
111-
| `x86_64-unknown-linux-gnu` | 2.15 | 4.6.2 | N/A | 1.0.2j ||
112-
| `x86_64-unknown-linux-musl` | 1.1.15 | 5.3.1 | N/A | 1.0.2j ||
92+
| Target | libc | cc | QEMU | OpenSSL | `test` |
93+
|--------------------------------------|--------|--------|-------|---------|:------:|
94+
| `aarch64-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.8.0 | 1.0.2j ||
95+
| `arm-unknown-linux-gnueabi` | 2.19 | 4.8.2 | 2.8.0 | 1.0.2j ||
96+
| `armv7-unknown-linux-gnueabihf` | 2.15 | 4.6.3 | 2.8.0 | 1.0.2j ||
97+
| `asm-unknown-emscripten` | N/A | 1.37.1 | N/A | N/A | |
98+
| `i686-unknown-linux-gnu` | 2.15 | 4.6.3 | N/A | 1.0.2j ||
99+
| `i686-unknown-linux-musl` | 1.1.15 | 5.3.1 | N/A | N/A ||
100+
| `mips-unknown-linux-gnu` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
101+
| `mips64-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
102+
| `mips64el-unknown-linux-gnuabi64` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
103+
| `mipsel-unknown-linux-gnu` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j ||
104+
| `powerpc-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.7.1 | 1.0.2j ||
105+
| `powerpc64-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.7.1 | 1.0.2j ||
106+
| `powerpc64le-unknown-linux-gnu` | 2.19 | 4.8.2 | 2.7.1 | 1.0.2j ||
107+
| `s390x-unknown-linux-gnu` | 2.23 | 5.3.1 | 2.8.0 | 1.0.2j | |
108+
| `thumbv6m-none-eabi` | N/A | 5.3.1 | N/A | N/A | |
109+
| `thumbv7em-none-eabi` | N/A | 5.3.1 | N/A | N/A | |
110+
| `thumbv7em-none-eabihf` | N/A | 5.3.1 | N/A | N/A | |
111+
| `thumbv7m-none-eabi` | N/A | 5.3.1 | N/A | N/A | |
112+
| `wasm32-unknown-emscripten` | N/A | 1.37.1 | N/A | N/A | |
113+
| `x86_64-unknown-linux-gnu` | 2.15 | 4.6.3 | N/A | 1.0.2j ||
114+
| `x86_64-unknown-linux-musl` | 1.1.15 | 5.3.1 | N/A | 1.0.2j ||
113115

114116
## Caveats / gotchas
115117

ci/script.sh

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ main() {
1313

1414
cargo install --path .
1515

16+
# Minimal testing
1617
case $TARGET in
1718
thumbv*-none-eabi*)
1819
td=$(mktemp -d)
@@ -33,7 +34,9 @@ main() {
3334
;;
3435
esac
3536

37+
# Test `cross build`
3638
if [ $TARGET = i686-apple-darwin ] || [ $TARGET = i686-unknown-linux-musl ]; then
39+
# No OpenSSL
3740
td=$(mktemp -d)
3841

3942
git clone --depth 1 https://github.com/japaric/xargo $td
@@ -44,6 +47,7 @@ main() {
4447

4548
rm -rf $td
4649
else
50+
# With OpenSSL
4751
td=$(mktemp -d)
4852

4953
git clone --depth 1 https://github.com/rust-lang/cargo $td
@@ -55,6 +59,7 @@ main() {
5559
rm -rf $td
5660
fi
5761

62+
# Test `cross test` & `cross run`. Usually involves QEMU
5863
# NOTE(s390x) japaric/cross#3
5964
# NOTE(*-musl) can't test compiler-builtins because that crate needs
6065
# cdylibs and musl targets don't support cdylibs
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM ubuntu:16.04
2+
3+
COPY emscripten.sh /
4+
RUN bash /emscripten.sh 1.37.1
5+
6+
RUN apt-get install --no-install-recommends -y \
7+
ca-certificates \
8+
gcc \
9+
libc6-dev \
10+
nodejs \
11+
python
12+
13+
ENV NODE=/usr/bin/nodejs

docker/binaryen.sh

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
set -ex
2+
3+
main() {
4+
local version=$1
5+
6+
local dependencies=(
7+
ca-certificates
8+
cmake
9+
curl
10+
g++
11+
ninja-build
12+
)
13+
14+
apt-get update
15+
apt-get install --no-install-recommends -y ${dependencies[@]}
16+
17+
local td=$(mktemp -d)
18+
19+
curl -L https://github.com/WebAssembly/binaryen/archive/$version.tar.gz | \
20+
tar -C $td --strip-components=1 -xz
21+
22+
pushd $td
23+
cmake -G Ninja
24+
nice ninja
25+
26+
mkdir /binaryen
27+
cp -r bin lib src /binaryen
28+
cp -r src/js /binaryen/src
29+
30+
# Cleanup
31+
apt-get purge --auto-remove -y ${dependencies[@]}
32+
33+
popd
34+
35+
rm -rf $td
36+
rm $0
37+
}
38+
39+
main "${@}"

docker/emscripten.sh

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
set -ex
2+
3+
main() {
4+
local version=$1
5+
6+
local dependencies=(
7+
ca-certificates
8+
cmake
9+
curl
10+
g++
11+
ninja-build
12+
python
13+
)
14+
15+
apt-get update
16+
apt-get install --no-install-recommends -y ${dependencies[@]}
17+
18+
local td=$(mktemp -d)
19+
20+
mkdir $td/{build,fastcomp}
21+
22+
curl -L https://github.com/kripken/emscripten-fastcomp/archive/$version.tar.gz |
23+
tar --strip-components=1 -C $td/fastcomp -xz
24+
25+
mkdir $td/fastcomp/tools/clang
26+
curl -L https://github.com/kripken/emscripten-fastcomp-clang/archive/$version.tar.gz |
27+
tar --strip-components=1 -C $td/fastcomp/tools/clang -xz
28+
29+
pushd $td
30+
cmake \
31+
-G Ninja \
32+
-DCLANG_INCLUDE_TESTS=OFF \
33+
-DCMAKE_BUILD_TYPE=Release \
34+
-DLLVM_INCLUDE_EXAMPLES=OFF \
35+
-DLLVM_INCLUDE_TESTS=OFF \
36+
-DLLVM_TARGETS_TO_BUILD="X86;JSBackend" \
37+
$td/fastcomp
38+
39+
nice ninja
40+
ninja install
41+
42+
mkdir /emscripten
43+
curl -L https://github.com/kripken/emscripten/archive/$version.tar.gz |
44+
tar --strip-components=1 -C /emscripten -xz
45+
46+
# TODO build tools/optimizer. I have no idea if `rustc` calls `emcc` in
47+
# a way that makes uses of that optimizer though.
48+
49+
# Put `emcc` in `$PATH`
50+
ln -s /emscripten/emcc /usr/local/bin
51+
52+
# Cleanup
53+
apt-get purge --auto-remove -y ${dependencies[@]}
54+
55+
popd
56+
57+
rm -rf $td
58+
rm $0
59+
}
60+
61+
main "${@}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM ubuntu:16.04
2+
3+
COPY emscripten.sh /
4+
RUN bash /emscripten.sh 1.37.1
5+
6+
COPY binaryen.sh /
7+
RUN bash /binaryen.sh version_22
8+
9+
RUN apt-get install --no-install-recommends -y \
10+
ca-certificates \
11+
gcc \
12+
libc6-dev \
13+
nodejs \
14+
python
15+
16+
ENV BINARYEN=/binaryen \
17+
NODE=/usr/bin/nodejs

src/docker.rs

+47-9
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ pub fn run(target: Target,
4545
fs::create_dir(&cargo_dir).ok();
4646
fs::create_dir(&xargo_dir).ok();
4747

48-
let mut cmd = if target.uses_xargo() {
48+
let mut cargo = if target.uses_xargo() {
4949
Command::new("xargo")
5050
} else {
5151
Command::new("cargo")
5252
};
53-
cmd.args(args);
53+
cargo.args(args);
5454

5555
let version = env!("CARGO_PKG_VERSION");
5656
let tag = if version.ends_with("-dev") {
@@ -59,22 +59,60 @@ pub fn run(target: Target,
5959
Cow::from(format!("v{}", version))
6060
};
6161

62-
Command::new("docker")
63-
.arg("run")
62+
let mut docker = Command::new("docker");
63+
64+
docker.arg("run")
6465
.arg("--rm")
6566
.args(&["--user", &format!("{}:{}", id::user(), id::group())])
6667
.args(&["-e", "CARGO_HOME=/cargo"])
6768
.args(&["-e", "CARGO_TARGET_DIR=/target"])
69+
.args(&["-e", "HOME=/tmp"])
6870
.args(&["-e", &format!("USER={}", id::username())])
6971
.args(&["-e", "XARGO_HOME=/xargo"])
7072
.args(&["-v", &format!("{}:/xargo", xargo_dir.display())])
7173
.args(&["-v", &format!("{}:/cargo", cargo_dir.display())])
7274
.args(&["-v", &format!("{}:/project:ro", cargo_root.display())])
7375
.args(&["-v",
7476
&format!("{}:/rust:ro", rustc::sysroot(verbose)?.display())])
75-
.args(&["-v", &format!("{}:/target", target_dir.display())])
76-
.args(&["-w", "/project"])
77-
.args(&["-it", &format!("japaric/{}:{}", target.triple(), tag)])
78-
.args(&["sh", "-c", &format!("PATH=$PATH:/rust/bin {:?}", cmd)])
79-
.run_and_get_status(verbose)
77+
.args(&["-v", &format!("{}:/target", target_dir.display())]);
78+
79+
// `emcc` caches stuff in `$HOME`. We must preserve that information across
80+
// runs so we use an OS-level temporary directory for that.
81+
let must_run_emcc_first = if target.uses_emcc() {
82+
let temp_dir = env::temp_dir();
83+
let cache_dir = temp_dir.join(format!("cross-{}", target.triple()));
84+
85+
if !cache_dir.exists() {
86+
fs::create_dir(&cache_dir).chain_err(|| {
87+
format!("couldn't create a directory in {}",
88+
temp_dir.display())
89+
})?;
90+
}
91+
92+
docker.args(&["-v", &format!("{}:{}", cache_dir.display(), "/tmp")]);
93+
94+
!cache_dir.join(".emscripten").exists()
95+
} else {
96+
false
97+
};
98+
99+
docker.args(&["-w", "/project"])
100+
.args(&["-it", &format!("japaric/{}:{}", target.triple(), tag)]);
101+
102+
// `emcc` only creates the `~/.emscripten` file the very first time is
103+
// called. Make sure that first time is from "outside" `rustc` so that
104+
// `cross build` doesn't result in a no-op.
105+
if must_run_emcc_first {
106+
docker.args(&["sh",
107+
"-c",
108+
&format!("emcc 2>/dev/null; \
109+
PATH=$PATH:/rust/bin {:?}",
110+
cargo)]);
111+
} else {
112+
docker.args(&["sh",
113+
"-c",
114+
&format!("PATH=$PATH:/rust/bin {:?}", cargo)]);
115+
}
116+
117+
docker.run_and_get_status(verbose)
80118
}

0 commit comments

Comments
 (0)