Add target to use LLVM wasm backend

The new target is wasm32-experimental-emscripten. Adds a new
configuration option to opt in to building experimental LLVM backends
such as the WebAssembly backend. The target name was chosen to be
similar to the existing wasm32-unknown-emscripten target so that the
build and tests would work with minimal other code changes. When/if the
new target replaces the old target, simply renaming it should just work.
This commit is contained in:
Thomas Lively 2017-06-16 15:43:43 -07:00
parent fe7227f6c8
commit a1981a64a2
7 changed files with 77 additions and 1 deletions

View File

@ -60,6 +60,7 @@ pub struct Config {
pub llvm_static_stdcpp: bool, pub llvm_static_stdcpp: bool,
pub llvm_link_shared: bool, pub llvm_link_shared: bool,
pub llvm_targets: Option<String>, pub llvm_targets: Option<String>,
pub llvm_experimental_targets: Option<String>,
pub llvm_link_jobs: Option<u32>, pub llvm_link_jobs: Option<u32>,
pub llvm_clean_rebuild: bool, pub llvm_clean_rebuild: bool,
@ -189,6 +190,7 @@ struct Llvm {
version_check: Option<bool>, version_check: Option<bool>,
static_libstdcpp: Option<bool>, static_libstdcpp: Option<bool>,
targets: Option<String>, targets: Option<String>,
experimental_targets: Option<String>,
link_jobs: Option<u32>, link_jobs: Option<u32>,
clean_rebuild: Option<bool>, clean_rebuild: Option<bool>,
} }
@ -350,6 +352,7 @@ impl Config {
set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild); set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild);
config.llvm_targets = llvm.targets.clone(); config.llvm_targets = llvm.targets.clone();
config.llvm_experimental_targets = llvm.experimental_targets.clone();
config.llvm_link_jobs = llvm.link_jobs; config.llvm_link_jobs = llvm.link_jobs;
} }

View File

@ -53,6 +53,14 @@
# Rust team and file an issue if you need assistance in porting! # Rust team and file an issue if you need assistance in porting!
#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon" #targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon"
# LLVM experimental targets to build support for. These targets are specified in
# the same format as above, but since these targets are experimental, they are
# not built by default and the experimental Rust compilation targets that depend
# on them will not work unless the user opts in to building them. Possible
# experimental LLVM targets include WebAssembly for the
# wasm32-experimental-emscripten Rust target.
#experimental-targets = ""
# Cap the number of parallel linker invocations when compiling LLVM. # Cap the number of parallel linker invocations when compiling LLVM.
# This can be useful when building LLVM with debug info, which significantly # This can be useful when building LLVM with debug info, which significantly
# increases the size of binaries and consequently the memory required by # increases the size of binaries and consequently the memory required by

View File

@ -86,6 +86,11 @@ pub fn llvm(build: &Build, target: &str) {
None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon", None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon",
}; };
let llvm_exp_targets = match build.config.llvm_experimental_targets {
Some(ref s) => s,
None => "",
};
let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"}; let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
cfg.target(target) cfg.target(target)
@ -94,6 +99,7 @@ pub fn llvm(build: &Build, target: &str) {
.profile(profile) .profile(profile)
.define("LLVM_ENABLE_ASSERTIONS", assertions) .define("LLVM_ENABLE_ASSERTIONS", assertions)
.define("LLVM_TARGETS_TO_BUILD", llvm_targets) .define("LLVM_TARGETS_TO_BUILD", llvm_targets)
.define("LLVM_EXPERIMENTAL_TARGETS_TO_BUILD", llvm_exp_targets)
.define("LLVM_INCLUDE_EXAMPLES", "OFF") .define("LLVM_INCLUDE_EXAMPLES", "OFF")
.define("LLVM_INCLUDE_TESTS", "OFF") .define("LLVM_INCLUDE_TESTS", "OFF")
.define("LLVM_INCLUDE_DOCS", "OFF") .define("LLVM_INCLUDE_DOCS", "OFF")

View File

@ -214,6 +214,7 @@ supported_targets! {
("le32-unknown-nacl", le32_unknown_nacl), ("le32-unknown-nacl", le32_unknown_nacl),
("asmjs-unknown-emscripten", asmjs_unknown_emscripten), ("asmjs-unknown-emscripten", asmjs_unknown_emscripten),
("wasm32-unknown-emscripten", wasm32_unknown_emscripten), ("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
("wasm32-experimental-emscripten", wasm32_experimental_emscripten),
("thumbv6m-none-eabi", thumbv6m_none_eabi), ("thumbv6m-none-eabi", thumbv6m_none_eabi),
("thumbv7m-none-eabi", thumbv7m_none_eabi), ("thumbv7m-none-eabi", thumbv7m_none_eabi),

View File

@ -0,0 +1,53 @@
// Copyright 2015 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.
use LinkerFlavor;
use super::{LinkArgs, Target, TargetOptions};
use super::emscripten_base::{cmd};
pub fn target() -> Result<Target, String> {
let mut post_link_args = LinkArgs::new();
post_link_args.insert(LinkerFlavor::Em,
vec!["-s".to_string(),
"WASM=1".to_string(),
"-s".to_string(),
"ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]);
let opts = TargetOptions {
linker: cmd("emcc"),
ar: cmd("emar"),
dynamic_linking: false,
executables: true,
// Today emcc emits two files - a .js file to bootstrap and
// possibly interpret the wasm, and a .wasm file
exe_suffix: ".js".to_string(),
linker_is_gnu: true,
allow_asm: false,
obj_is_bitcode: true,
is_like_emscripten: true,
max_atomic_width: Some(32),
post_link_args: post_link_args,
target_family: Some("unix".to_string()),
.. Default::default()
};
Ok(Target {
llvm_target: "wasm32-unknown-unknown".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "32".to_string(),
target_os: "emscripten".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
arch: "wasm32".to_string(),
linker_flavor: LinkerFlavor::Em,
options: opts,
})
}

View File

@ -93,7 +93,7 @@ fn main() {
let mut optional_components = let mut optional_components =
vec!["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", vec!["x86", "arm", "aarch64", "mips", "powerpc", "pnacl",
"systemz", "jsbackend", "msp430", "sparc", "nvptx"]; "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"];
let mut version_cmd = Command::new(&llvm_config); let mut version_cmd = Command::new(&llvm_config);
version_cmd.arg("--version"); version_cmd.arg("--version");

View File

@ -389,6 +389,11 @@ pub fn initialize_available_targets() {
LLVMInitializeHexagonTargetMC, LLVMInitializeHexagonTargetMC,
LLVMInitializeHexagonAsmPrinter, LLVMInitializeHexagonAsmPrinter,
LLVMInitializeHexagonAsmParser); LLVMInitializeHexagonAsmParser);
init_target!(llvm_component = "webassembly",
LLVMInitializeWebAssemblyTargetInfo,
LLVMInitializeWebAssemblyTarget,
LLVMInitializeWebAssemblyTargetMC,
LLVMInitializeWebAssemblyAsmPrinter);
} }
pub fn last_error() -> Option<String> { pub fn last_error() -> Option<String> {