diff --git a/configure b/configure index 2b493ee91b50a..e08bcc028272e 100755 --- a/configure +++ b/configure @@ -490,6 +490,7 @@ valopt musl-root-armhf "" "arm-unknown-linux-musleabihf install directory" valopt musl-root-armv7 "" "armv7-unknown-linux-musleabihf install directory" valopt extra-filename "" "Additional data that is hashed and passed to the -C extra-filename flag" valopt qemu-armhf-rootfs "" "rootfs in qemu testing, you probably don't want to use this" +valopt experimental-targets "" "experimental LLVM targets to build" if [ -e ${CFG_SRC_DIR}.git ] then diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 902cd0997a8ed..3ada846e38236 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -497,6 +497,9 @@ impl Config { "CFG_TARGET" if value.len() > 0 => { self.target.extend(value.split(" ").map(|s| s.to_string())); } + "CFG_EXPERIMENTAL_TARGETS" if value.len() > 0 => { + self.llvm_experimental_targets = Some(value.to_string()); + } "CFG_MUSL_ROOT" if value.len() > 0 => { self.musl_root = Some(parse_configure_path(value)); } diff --git a/src/ci/docker/disabled/wasm32/Dockerfile b/src/ci/docker/disabled/wasm32/Dockerfile index daf398ac0962f..c75b5d455c522 100644 --- a/src/ci/docker/disabled/wasm32/Dockerfile +++ b/src/ci/docker/disabled/wasm32/Dockerfile @@ -11,16 +11,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ sudo \ gdb \ - xz-utils + xz-utils \ + jq \ + bzip2 # dumb-init COPY scripts/dumb-init.sh /scripts/ RUN sh /scripts/dumb-init.sh # emscripten -COPY scripts/emscripten.sh /scripts/ -RUN bash /scripts/emscripten.sh -COPY wasm32/node.sh /usr/local/bin/node +COPY scripts/emscripten-wasm.sh /scripts/ +RUN bash /scripts/emscripten-wasm.sh +COPY disabled/wasm32/node.sh /usr/local/bin/node + +# cache +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh # env ENV PATH=$PATH:/emsdk-portable @@ -30,15 +36,11 @@ ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/ ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/ ENV EM_CONFIG=/emsdk-portable/.emscripten -ENV TARGETS=wasm32-unknown-emscripten +ENV TARGETS=wasm32-unknown-emscripten,wasm32-experimental-emscripten -ENV RUST_CONFIGURE_ARGS --target=$TARGETS +ENV RUST_CONFIGURE_ARGS --target=$TARGETS --experimental-targets=WebAssembly ENV SCRIPT python2.7 ../x.py test --target $TARGETS -# cache -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - # init ENTRYPOINT ["/usr/bin/dumb-init", "--"] diff --git a/src/ci/docker/scripts/emscripten-wasm.sh b/src/ci/docker/scripts/emscripten-wasm.sh new file mode 100644 index 0000000000000..e693f975f69bc --- /dev/null +++ b/src/ci/docker/scripts/emscripten-wasm.sh @@ -0,0 +1,64 @@ +# Copyright 2017 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + rm -f /tmp/build.log + set -x +} + +# Download emsdk +cd / +curl -L https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz | \ + tar -xz + +# Download last known good emscripten from WebAssembly waterfall +BUILD=$(curl -L https://storage.googleapis.com/wasm-llvm/builds/linux/lkgr.json | \ + jq '.build | tonumber') +curl -L https://storage.googleapis.com/wasm-llvm/builds/linux/$BUILD/wasm-binaries.tbz2 | \ + hide_output tar xvkj + +# node 8 is required to run wasm +cd / +curl -L https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \ + tar -xJ + +cd /emsdk-portable +./emsdk update +hide_output ./emsdk install sdk-1.37.13-64bit +./emsdk activate sdk-1.37.13-64bit + +# Make emscripten use wasm-ready node and LLVM tools +echo "NODE_JS='/node-v8.0.0-linux-x64/bin/node'" >> /root/.emscripten +echo "LLVM_ROOT='/wasm-install/bin'" >> /root/.emscripten + +# Make emsdk usable by any user +cp /root/.emscripten /emsdk-portable +chmod a+rxw -R /emsdk-portable + +# Compile and cache libc +source ./emsdk_env.sh +echo "main(){}" > a.c +HOME=/emsdk-portable/ emcc a.c +HOME=/emsdk-portable/ emcc -s WASM=1 a.c +rm -f a.* diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh index 8aa5a98d7fc52..cf5eecbdb6c8c 100644 --- a/src/ci/docker/scripts/emscripten.sh +++ b/src/ci/docker/scripts/emscripten.sh @@ -50,4 +50,4 @@ chmod a+rxw -R /emsdk-portable # node 8 is required to run wasm cd / curl -L https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \ - tar -xJ + tar -xJ diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 37d6a6b95d937..5df227e39acbd 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -282,6 +282,9 @@ pub struct TargetOptions { /// user-defined libraries. pub post_link_args: LinkArgs, + /// Environment variables to be set before invoking the linker. + pub link_env: Vec<(String, String)>, + /// Extra arguments to pass to the external assembler (when used) pub asm_args: Vec<String>, @@ -451,6 +454,7 @@ impl Default for TargetOptions { pre_link_objects_dll: Vec::new(), post_link_objects: Vec::new(), late_link_args: LinkArgs::new(), + link_env: Vec::new(), archive_format: "gnu".to_string(), custom_unwind_resume: false, lib_allocation_crate: "alloc_system".to_string(), @@ -620,6 +624,21 @@ impl Target { base.options.$key_name = args; } } ); + ($key_name:ident, env) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(a) = obj.find(&name[..]).and_then(|o| o.as_array()) { + for o in a { + if let Some(s) = o.as_string() { + let p = s.split('=').collect::<Vec<_>>(); + if p.len() == 2 { + let k = p[0].to_string(); + let v = p[1].to_string(); + base.options.$key_name.push((k, v)); + } + } + } + } + } ); } key!(is_builtin, bool); @@ -631,6 +650,7 @@ impl Target { key!(late_link_args, link_args); key!(post_link_objects, list); key!(post_link_args, link_args); + key!(link_env, env); key!(asm_args, list); key!(cpu); key!(features); @@ -785,6 +805,17 @@ impl ToJson for Target { d.insert(name.to_string(), obj.to_json()); } } ); + (env - $attr:ident) => ( { + let name = (stringify!($attr)).replace("_", "-"); + if default.$attr != self.options.$attr { + let obj = self.options.$attr + .iter() + .map(|&(ref k, ref v)| k.clone() + "=" + &v) + .collect::<Vec<_>>(); + d.insert(name.to_string(), obj.to_json()); + } + } ); + } target_val!(llvm_target); @@ -806,6 +837,7 @@ impl ToJson for Target { target_option_val!(link_args - late_link_args); target_option_val!(post_link_objects); target_option_val!(link_args - post_link_args); + target_option_val!(env - link_env); target_option_val!(asm_args); target_option_val!(cpu); target_option_val!(features); diff --git a/src/librustc_back/target/wasm32_experimental_emscripten.rs b/src/librustc_back/target/wasm32_experimental_emscripten.rs index 1a95c93363adb..053fab5425019 100644 --- a/src/librustc_back/target/wasm32_experimental_emscripten.rs +++ b/src/librustc_back/target/wasm32_experimental_emscripten.rs @@ -30,6 +30,7 @@ pub fn target() -> Result<Target, String> { // possibly interpret the wasm, and a .wasm file exe_suffix: ".js".to_string(), linker_is_gnu: true, + link_env: vec![("EMCC_WASM_BACKEND".to_string(), "1".to_string())], allow_asm: false, obj_is_bitcode: true, is_like_emscripten: true, diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 1f88f90dbbb28..a9af8b11f93ad 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -785,6 +785,9 @@ fn link_natively(sess: &Session, if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) { cmd.args(args); } + for &(ref k, ref v) in &sess.target.target.options.link_env { + cmd.env(k, v); + } if sess.opts.debugging_opts.print_link_args { println!("{:?}", &cmd); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 01419c4257074..0692e07253fbe 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1338,7 +1338,6 @@ actual:\n\ input) } - fn compose_and_run(&self, ProcArgs{ args, prog }: ProcArgs, procenv: Vec<(String, String)> ,