diff --git a/src/bootstrap/build/config.rs b/src/bootstrap/build/config.rs index 1e67c4a9a3e8d..083914788b284 100644 --- a/src/bootstrap/build/config.rs +++ b/src/bootstrap/build/config.rs @@ -15,6 +15,7 @@ use std::io::prelude::*; use std::path::PathBuf; use std::process; +use build::util::build_path; use num_cpus; use rustc_serialize::Decodable; use toml::{Parser, Decoder, Value}; @@ -305,7 +306,7 @@ impl Config { .collect(); } "CFG_MUSL_ROOT" if value.len() > 0 => { - self.musl_root = Some(PathBuf::from(value)); + self.musl_root = Some(build_path(value)); } "CFG_DEFAULT_AR" if value.len() > 0 => { self.rustc_default_ar = Some(value.to_string()); @@ -322,31 +323,31 @@ impl Config { "CFG_LLVM_ROOT" if value.len() > 0 => { let target = self.target_config.entry(self.build.clone()) .or_insert(Target::default()); - let root = PathBuf::from(value); + let root = build_path(value); target.llvm_config = Some(root.join("bin/llvm-config")); } "CFG_JEMALLOC_ROOT" if value.len() > 0 => { let target = self.target_config.entry(self.build.clone()) .or_insert(Target::default()); - target.jemalloc = Some(PathBuf::from(value)); + target.jemalloc = Some(build_path(value)); } "CFG_ARM_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => { let target = "arm-linux-androideabi".to_string(); let target = self.target_config.entry(target) .or_insert(Target::default()); - target.ndk = Some(PathBuf::from(value)); + target.ndk = Some(build_path(value)); } "CFG_I686_LINUX_ANDROID_NDK" if value.len() > 0 => { let target = "i686-linux-androideabi".to_string(); let target = self.target_config.entry(target) .or_insert(Target::default()); - target.ndk = Some(PathBuf::from(value)); + target.ndk = Some(build_path(value)); } "CFG_AARCH64_LINUX_ANDROID_NDK" if value.len() > 0 => { let target = "aarch64-linux-androideabi".to_string(); let target = self.target_config.entry(target) .or_insert(Target::default()); - target.ndk = Some(PathBuf::from(value)); + target.ndk = Some(build_path(value)); } _ => {} } diff --git a/src/bootstrap/build/native.rs b/src/bootstrap/build/native.rs index b3bd6b9229965..e2c048d051857 100644 --- a/src/bootstrap/build/native.rs +++ b/src/bootstrap/build/native.rs @@ -146,15 +146,20 @@ pub fn compiler_rt(build: &Build, target: &str) { } let _ = fs::remove_dir_all(&dst); t!(fs::create_dir_all(&dst)); - let build_llvm_config = build.llvm_out(&build.config.build) - .join("bin") - .join(exe("llvm-config", &build.config.build)); + + let internal_config = build.llvm_out(&build.config.build) + .join("bin") + .join("llvm-config"); + let external_config = build.config.target_config.get(target).and_then(|config| { + config.llvm_config.clone() + }); + let llvm_config = external_config.unwrap_or(internal_config); let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt")); cfg.target(target) .host(&build.config.build) .out_dir(&dst) .profile(mode) - .define("LLVM_CONFIG_PATH", build_llvm_config) + .define("LLVM_CONFIG_PATH", llvm_config) .define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target) .define("COMPILER_RT_BUILD_SANITIZERS", "OFF") .define("COMPILER_RT_BUILD_EMUTLS", "OFF") diff --git a/src/bootstrap/build/sanity.rs b/src/bootstrap/build/sanity.rs index be4416c697c56..f92319658d1cc 100644 --- a/src/bootstrap/build/sanity.rs +++ b/src/bootstrap/build/sanity.rs @@ -12,6 +12,7 @@ use std::collections::HashSet; use std::env; use std::ffi::{OsStr, OsString}; use std::fs; +use std::path::PathBuf; use std::process::Command; use build_helper::output; @@ -78,6 +79,24 @@ pub fn check(build: &mut Build) { panic!("the iOS target is only supported on OSX"); } + if cfg!(windows) { + if let Some(config) = build.config.target_config.get(target) { + if let Some(ref llvm_config) = config.llvm_config { + let llvm_mode = output(Command::new(&llvm_config).arg("--shared-mode")); + if llvm_mode == "shared" { + let bin = output(Command::new(&llvm_config).arg("--bindir")); + let bin_canonical = PathBuf::from(bin.trim()).canonicalize().unwrap(); + let bin_in_path = env::split_paths(&path).find(|p| { + p.canonicalize().ok().map_or(false, |c| c.eq(&bin_canonical)) + }); + if bin_in_path.is_none() { + panic!("Unable to find LLVM's binary folder {:?} in PATH", bin); + } + } + } + } + } + // Make sure musl-root is valid if specified if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) { match build.config.musl_root { diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index 107b0688b6889..21c92f0a2c68a 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -144,7 +144,9 @@ fn top_level(build: &Build) -> Vec { src: Source::Llvm { _dummy: () }, target: &build.config.build, }; - targets.push(t.doc(stage)); + if build.config.docs { + targets.push(t.doc(stage)); + } for host in build.config.host.iter() { if !build.flags.host.contains(host) { continue @@ -320,7 +322,9 @@ impl<'a> Step<'a> { Source::Dist { stage } => { let mut base = Vec::new(); - base.push(self.dist_docs(stage)); + if build.config.docs { + base.push(self.dist_docs(stage)); + } for host in build.config.host.iter() { let host = self.target(host); diff --git a/src/bootstrap/build/util.rs b/src/bootstrap/build/util.rs index 35d22ee5d2658..4ee63dc3aef4a 100644 --- a/src/bootstrap/build/util.rs +++ b/src/bootstrap/build/util.rs @@ -16,6 +16,29 @@ use std::process::Command; use bootstrap::{dylib_path, dylib_path_var}; use filetime::FileTime; +#[cfg(not(windows))] +pub fn build_path(path: &str) -> PathBuf { + PathBuf::from(path) +} + +#[cfg(windows)] +pub fn build_path(path: &str) -> PathBuf { + use std::io::{stderr, Write}; + use build_helper::output; + + if path.chars().next() == Some('/') { + let output = output(&mut Command::new("cygpath").arg("-w").arg(path)); + let win_path = output.trim_right(); + writeln!(&mut stderr(), + "note: Converted Unix path '{}' to Windows path '{}'", + path, + win_path).ok(); + PathBuf::from(win_path) + } else { + PathBuf::from(path) + } +} + pub fn staticlib(name: &str, target: &str) -> String { if target.contains("windows-msvc") { format!("{}.lib", name) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index dcfb518ba7938..1af577e143a0b 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -21,8 +21,8 @@ fn main() { println!("cargo:rustc-cfg=cargobuild"); let target = env::var("TARGET").unwrap(); - let llvm_config = env::var_os("LLVM_CONFIG").map(PathBuf::from) - .unwrap_or_else(|| { + let mut llvm_config = env::var_os("LLVM_CONFIG").map(PathBuf::from) + .unwrap_or_else(|| { match env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) { Some(dir) => { let to_test = dir.parent().unwrap().parent().unwrap() @@ -35,7 +35,7 @@ fn main() { } PathBuf::from("llvm-config") }); - + llvm_config.set_extension(env::consts::EXE_EXTENSION); println!("cargo:rerun-if-changed={}", llvm_config.display()); // Test whether we're cross-compiling LLVM. This is a pretty rare case @@ -111,6 +111,7 @@ fn main() { // Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then // we don't pick up system libs because unfortunately they're for the host // of llvm-config, not the target that we're attempting to link. + let llvm_static = output(Command::new(&llvm_config).arg("--shared-mode")) == "static"; let mut cmd = Command::new(&llvm_config); cmd.arg("--libs"); if !is_crossed { @@ -136,7 +137,7 @@ fn main() { continue } - let kind = if name.starts_with("LLVM") {"static"} else {"dylib"}; + let kind = if name.starts_with("LLVM") && llvm_static {"static"} else {"dylib"}; println!("cargo:rustc-link-lib={}={}", kind, name); } @@ -161,6 +162,13 @@ fn main() { } } + if !llvm_static && cfg!(windows) { + // Use --bindir as the search path. DLLs will be placed here. + // llvm-config is bugged and doesn't doesn't indicate this on Windows + let bin = output(Command::new(&llvm_config).arg("--bindir")); + println!("cargo:rustc-link-search=native={}", bin.trim()); + } + // C++ runtime library if !target.contains("msvc") { if let Some(s) = env::var_os("LLVM_STATIC_STDCPP") {