From 480d743985d6acf1576be5f4b73b925495f0ac99 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 15 Sep 2016 18:27:57 -0500 Subject: [PATCH 1/2] compiler_builtins: base conditional compilation on the specification of the target rather than on its triple (i.e. its name). As explained in #35474, the current conditional compilation logic, which is based on the target triple (e.g. x86_64-unknown-linux-gnu), is not robust in the presence of custom targets as those can have arbitrary triples (e.g. cortex-m3). To fix that, this commit changes the conditional compilation logic to use the specification of the target (e.g. target_arch, target_os, etc.). For that, compiler_builtins build script now depends on the rustc-cfg crate, whose role is to shell out to `rustc --print cfg` and return its output parsed as a `struct`. With the goal of completely removing any direct dependency of the conditional compilation logic on the target triple, this commit also exposes the llvm-target field of the target specification via `rustc --print cfg`. closes #35474 --- src/libcompiler_builtins/Cargo.toml | 1 + src/libcompiler_builtins/build.rs | 43 ++++++++++++++++++++--------- src/librustc/session/config.rs | 2 ++ src/rustc/std_shim/Cargo.lock | 7 +++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/libcompiler_builtins/Cargo.toml b/src/libcompiler_builtins/Cargo.toml index a52873fc326b8..d9a8eb23ad573 100644 --- a/src/libcompiler_builtins/Cargo.toml +++ b/src/libcompiler_builtins/Cargo.toml @@ -13,3 +13,4 @@ core = { path = "../libcore" } [build-dependencies] gcc = "0.3.27" +rustc-cfg = { git = "https://github.com/japaric/rustc-cfg", branch = "llvm-target" } diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs index 09c400b52bc83..eb0719f98a29c 100644 --- a/src/libcompiler_builtins/build.rs +++ b/src/libcompiler_builtins/build.rs @@ -34,11 +34,14 @@ //! far far less than working with compiler-rt's build system over time. extern crate gcc; +extern crate rustc_cfg; use std::collections::BTreeMap; use std::env; use std::path::Path; +use rustc_cfg::Cfg; + struct Sources { // SYMBOL -> PATH TO SOURCE map: BTreeMap<&'static str, &'static str>, @@ -73,9 +76,23 @@ impl Sources { fn main() { let target = env::var("TARGET").unwrap(); + let Cfg { + ref llvm_target, + ref target_arch, + ref target_os, + ref target_env, + ref target_vendor, + .. + } = Cfg::new(&target).unwrap(); + // TODO(stage0) use `unwrap` instead of `unwrap_or` + // NOTE in the latest stable/beta release, `rustc --print cfg` doesn't include `llvm_target` in + // its output. In those cases simply fallback to the target triple, which is usually similar to + // llvm-target, as a workaround. + let llvm_target = llvm_target.as_ref().unwrap_or(&target).split('-').collect::>(); + let target_vendor = target_vendor.as_ref().unwrap(); let cfg = &mut gcc::Config::new(); - if target.contains("msvc") { + if target_env == "msvc" { // Don't pull in extra libraries on MSVC cfg.flag("/Zl"); @@ -183,7 +200,7 @@ fn main() { "umoddi3.c", "umodsi3.c"]); - if !target.contains("ios") { + if target_os != "ios" { sources.extend(&["absvti2.c", "addtf3.c", "addvti3.c", @@ -226,7 +243,7 @@ fn main() { "umodti3.c"]); } - if target.contains("apple") { + if target_vendor == "apple" { sources.extend(&["atomic_flag_clear.c", "atomic_flag_clear_explicit.c", "atomic_flag_test_and_set.c", @@ -235,20 +252,20 @@ fn main() { "atomic_thread_fence.c"]); } - if !target.contains("windows") { + if target_os != "windows" { sources.extend(&["emutls.c"]); } - if target.contains("msvc") { - if target.contains("x86_64") { + if target_env == "msvc" { + if llvm_target[0] == "x86_64" { sources.extend(&["x86_64/floatdidf.c", "x86_64/floatdisf.c", "x86_64/floatdixf.c"]); } } else { - if !target.contains("freebsd") { + if target_os != "freebsd" { sources.extend(&["gcc_personality_v0.c"]); } - if target.contains("x86_64") { + if target_arch == "x86_64" { sources.extend(&["x86_64/chkstk.S", "x86_64/chkstk2.S", "x86_64/floatdidf.c", @@ -259,7 +276,7 @@ fn main() { "x86_64/floatundixf.S"]); } - if target.contains("i386") || target.contains("i586") || target.contains("i686") { + if llvm_target[0] == "i386" || llvm_target[0] == "i586" || llvm_target[0] == "i686" { sources.extend(&["i386/ashldi3.S", "i386/ashrdi3.S", "i386/chkstk.S", @@ -279,7 +296,7 @@ fn main() { } } - if target.contains("arm") && !target.contains("ios") { + if target_arch == "arm" && target_os != "ios" { sources.extend(&["arm/aeabi_cdcmp.S", "arm/aeabi_cdcmpeq_check_nan.c", "arm/aeabi_cfcmp.S", @@ -315,7 +332,7 @@ fn main() { "arm/umodsi3.S"]); } - if target.contains("armv7") { + if llvm_target[0] == "armv7" { sources.extend(&["arm/sync_fetch_and_add_4.S", "arm/sync_fetch_and_add_8.S", "arm/sync_fetch_and_and_4.S", @@ -338,7 +355,7 @@ fn main() { "arm/sync_fetch_and_xor_8.S"]); } - if target.contains("eabihf") { + if llvm_target.last().unwrap().ends_with("eabihf") { sources.extend(&["arm/adddf3vfp.S", "arm/addsf3vfp.S", "arm/divdf3vfp.S", @@ -377,7 +394,7 @@ fn main() { "arm/unordsf2vfp.S"]); } - if target.contains("aarch64") { + if target_arch == "aarch64" { sources.extend(&["comparetf2.c", "extenddftf2.c", "extendsftf2.c", diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2009e18f6ee20..9d32c8425bbdf 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -930,6 +930,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { let os = &sess.target.target.target_os; let env = &sess.target.target.target_env; let vendor = &sess.target.target.target_vendor; + let llvm_target = &sess.target.target.llvm_target; let max_atomic_width = sess.target.target.options.max_atomic_width; let fam = if let Some(ref fam) = sess.target.target.options.target_family { @@ -949,6 +950,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { mk(InternedString::new("target_pointer_width"), intern(wordsz)), mk(InternedString::new("target_env"), intern(env)), mk(InternedString::new("target_vendor"), intern(vendor)), + mk(InternedString::new("llvm_target"), intern(llvm_target)), ]; match &fam[..] { "windows" | "unix" => ret.push(attr::mk_word_item(fam)), diff --git a/src/rustc/std_shim/Cargo.lock b/src/rustc/std_shim/Cargo.lock index 747322b32f320..644670f96844e 100644 --- a/src/rustc/std_shim/Cargo.lock +++ b/src/rustc/std_shim/Cargo.lock @@ -49,6 +49,7 @@ version = "0.0.0" dependencies = [ "core 0.0.0", "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-cfg 0.1.2 (git+https://github.com/japaric/rustc-cfg?branch=llvm-target)", ] [[package]] @@ -92,6 +93,11 @@ dependencies = [ "core 0.0.0", ] +[[package]] +name = "rustc-cfg" +version = "0.1.2" +source = "git+https://github.com/japaric/rustc-cfg?branch=llvm-target#7eb668fcf13e2730e9cf8b33389aadbcdfbb0abc" + [[package]] name = "rustc_unicode" version = "0.0.0" @@ -129,3 +135,4 @@ dependencies = [ [metadata] "checksum gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "806e63121fbf30760b060a5fc2d1e9f47e1bd356d183e8870367c6c12cc9d5ed" +"checksum rustc-cfg 0.1.2 (git+https://github.com/japaric/rustc-cfg?branch=llvm-target)" = "" From 10ff03de40ba91fc2a83254884fe95419e36c7f8 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 15 Sep 2016 20:47:42 -0500 Subject: [PATCH 2/2] fix make tidy --- src/libcompiler_builtins/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs index eb0719f98a29c..756ac51d2ba69 100644 --- a/src/libcompiler_builtins/build.rs +++ b/src/libcompiler_builtins/build.rs @@ -84,7 +84,7 @@ fn main() { ref target_vendor, .. } = Cfg::new(&target).unwrap(); - // TODO(stage0) use `unwrap` instead of `unwrap_or` + // FIXME(stage0) use `unwrap` instead of `unwrap_or` // NOTE in the latest stable/beta release, `rustc --print cfg` doesn't include `llvm_target` in // its output. In those cases simply fallback to the target triple, which is usually similar to // llvm-target, as a workaround.