1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // The wasm32-unknown-unknown target is currently a highly experimental version
12 // of a wasm-based target which does *not* use the Emscripten toolchain. Instead
13 // this is a pretty flavorful (aka hacked up) target right now. The definition
14 // and semantics of this target are likely to change and so this shouldn't be
15 // relied on just yet.
17 // In general everyone is currently waiting on a linker for wasm code. In the
18 // meantime we have no means of actually making use of the traditional separate
19 // compilation model. At a high level this means that assembling Rust programs
20 // into a WebAssembly program looks like:
22 // 1. All intermediate artifacts are LLVM bytecode. We'll be using LLVM as
24 // 2. For the final artifact we emit one giant assembly file (WebAssembly
25 // doesn't have an object file format). To do this we force LTO to be turned
26 // on (`requires_lto` below) to ensure all Rust code is in one module. Any
27 // "linked" C library is basically just ignored.
28 // 3. Using LLVM we emit a `foo.s` file (assembly) with some... what I can only
29 // describe as arcane syntax. From there we need to actually change this
30 // into a wasm module. For this step we use the `binaryen` project. This
31 // project is mostly intended as a WebAssembly code generator, but for now
32 // we're just using its LLVM-assembly-to-wasm-module conversion utilities.
34 // And voila, out comes a web assembly module! There's some various tweaks here
35 // and there, but that's the high level at least. Note that this will be
36 // rethought from the ground up once a linker (lld) is available, so this is all
37 // temporary and should improve in the future.
40 use super::{Target, TargetOptions, PanicStrategy};
42 pub fn target() -> Result<Target, String> {
43 let opts = TargetOptions {
44 linker: "not-used".to_string(),
46 // we allow dynamic linking, but only cdylibs. Basically we allow a
47 // final library artifact that exports some symbols (a wasm module) but
48 // we don't allow intermediate `dylib` crate types
49 dynamic_linking: true,
52 // This means we'll just embed a `start` function in the wasm module
55 // relatively self-explanatory!
56 exe_suffix: ".wasm".to_string(),
57 dll_prefix: "".to_string(),
58 dll_suffix: ".wasm".to_string(),
61 // We're storing bitcode for now in all the rlibs
64 // A bit of a lie, but "eh"
65 max_atomic_width: Some(32),
67 // Unwinding doesn't work right now, so the whole target unconditionally
68 // defaults to panic=abort. Note that this is guaranteed to change in
69 // the future once unwinding is implemented. Don't rely on this.
70 panic_strategy: PanicStrategy::Abort,
72 // There's no linker yet so we're forced to use LLVM as a linker. This
73 // means that we must always enable LTO for final artifacts.
76 // Wasm doesn't have atomics yet, so tell LLVM that we're in a single
77 // threaded model which will legalize atomics to normal operations.
80 // Because we're always enabling LTO we can't enable builtin lowering as
81 // otherwise we'll lower the definition of the `memcpy` function to
82 // memcpy itself. Note that this is specifically because we're
83 // performing LTO with compiler-builtins.
86 // no dynamic linking, no need for default visibility!
87 default_hidden_visibility: true,
92 llvm_target: "wasm32-unknown-unknown".to_string(),
93 target_endian: "little".to_string(),
94 target_pointer_width: "32".to_string(),
95 target_c_int_width: "32".to_string(),
96 // This is basically guaranteed to change in the future, don't rely on
97 // this. Use `not(target_os = "emscripten")` for now.
98 target_os: "unknown".to_string(),
99 target_env: "".to_string(),
100 target_vendor: "unknown".to_string(),
101 data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
102 arch: "wasm32".to_string(),
103 // A bit of a lie, but it gets the job done
104 linker_flavor: LinkerFlavor::Binaryen,