diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 574c927bd75d2..069c48e3958bf 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -164,6 +164,7 @@ pub enum PrintRequest { CrateName, Cfg, TargetList, + TargetSpec, } pub enum Input { @@ -905,7 +906,7 @@ pub fn rustc_short_optgroups() -> Vec { "[asm|llvm-bc|llvm-ir|obj|link|dep-info]"), opt::multi_s("", "print", "Comma separated list of compiler information to \ print on stdout", - "[crate-name|file-names|sysroot|cfg|target-list]"), + "[crate-name|file-names|sysroot|cfg|target-list|target-spec]"), opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"), opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"), opt::opt_s("o", "", "Write output to ", "FILENAME"), @@ -1189,6 +1190,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { "sysroot" => PrintRequest::Sysroot, "cfg" => PrintRequest::Cfg, "target-list" => PrintRequest::TargetList, + "target-spec" => PrintRequest::TargetSpec, req => { early_error(error_format, &format!("unknown print request `{}`", req)) } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index a8eac524971ba..6e454426643a1 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -45,7 +45,8 @@ //! settings, though `target-feature` and `link-args` will *add* to the list //! specified by the target, rather than replace. -use serialize::json::Json; +use serialize::json::{Json, ToJson}; +use std::collections::BTreeMap; use std::default::Default; use std::io::prelude::*; use syntax::abi::Abi; @@ -504,6 +505,80 @@ impl Target { } } +impl ToJson for Target { + fn to_json(&self) -> Json { + let mut d = BTreeMap::new(); + let default: TargetOptions = Default::default(); + + macro_rules! target_val { + ($attr:ident) => ( { + let name = (stringify!($attr)).replace("_", "-"); + d.insert(name.to_string(), self.$attr.to_json()); + } ); + ($attr:ident, $key_name:expr) => ( { + let name = $key_name; + d.insert(name.to_string(), self.$attr.to_json()); + } ); + } + + macro_rules! target_option_val { + ($attr:ident) => ( { + let name = (stringify!($attr)).replace("_", "-"); + if default.$attr != self.options.$attr { + d.insert(name.to_string(), self.options.$attr.to_json()); + } + } ); + ($attr:ident, $key_name:expr) => ( { + let name = $key_name; + if default.$attr != self.options.$attr { + d.insert(name.to_string(), self.options.$attr.to_json()); + } + } ); + } + + target_val!(llvm_target); + target_val!(target_endian); + target_val!(target_pointer_width); + target_val!(arch); + target_val!(target_os, "os"); + target_val!(target_env, "env"); + target_val!(target_vendor, "vendor"); + + target_option_val!(cpu); + target_option_val!(ar); + target_option_val!(linker); + target_option_val!(relocation_model); + target_option_val!(code_model); + target_option_val!(dll_prefix); + target_option_val!(dll_suffix); + target_option_val!(exe_suffix); + target_option_val!(staticlib_prefix); + target_option_val!(staticlib_suffix); + target_option_val!(features); + target_option_val!(data_layout); + target_option_val!(dynamic_linking); + target_option_val!(executables); + target_option_val!(disable_redzone); + target_option_val!(eliminate_frame_pointer); + target_option_val!(function_sections); + target_option_val!(target_family); + target_option_val!(is_like_osx); + target_option_val!(is_like_windows); + target_option_val!(is_like_msvc); + target_option_val!(linker_is_gnu); + target_option_val!(has_rpath); + target_option_val!(no_compiler_rt); + target_option_val!(no_default_libraries); + target_option_val!(pre_link_args); + target_option_val!(post_link_args); + target_option_val!(archive_format); + target_option_val!(allow_asm); + target_option_val!(custom_unwind_resume); + + Json::Object(d) + } +} + fn maybe_jemalloc() -> String { if cfg!(feature = "jemalloc") { "alloc_jemalloc".to_string() diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 769449b96d2b1..9290e5dab112c 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -76,6 +76,8 @@ use rustc_metadata::loader; use rustc_metadata::cstore::CStore; use rustc::util::common::time; +use serialize::json::ToJson; + use std::cmp::max; use std::cmp::Ordering::Equal; use std::default::Default; @@ -560,6 +562,7 @@ impl RustcDefaultCalls { println!("{}", targets.join("\n")); }, PrintRequest::Sysroot => println!("{}", sess.sysroot().display()), + PrintRequest::TargetSpec => println!("{}", sess.target.target.to_json().pretty()), PrintRequest::FileNames | PrintRequest::CrateName => { let input = match input { diff --git a/src/test/run-make/target-specs/Makefile b/src/test/run-make/target-specs/Makefile index 0c9a0169c1abb..90082839026d0 100644 --- a/src/test/run-make/target-specs/Makefile +++ b/src/test/run-make/target-specs/Makefile @@ -6,3 +6,4 @@ all: $(RUSTC) foo.rs --target=my-incomplete-platform.json 2>&1 | grep 'Field llvm-target' RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-awesome-platform --crate-type=lib --emit=asm RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=x86_64-unknown-linux-gnu --crate-type=lib --emit=asm + $(RUSTC) --target=my-awesome-platform.json --print target-spec > $(TMPDIR)/test-platform.json && $(RUSTC) --target=$(TMPDIR)/test-platform.json --print target-spec | diff -q $(TMPDIR)/test-platform.json -