rustbuild: Support specifying archiver and linker explicitly
This commit is contained in:
@@ -300,7 +300,7 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
[target.x86_64-unknown-linux-gnu]
|
[target.x86_64-unknown-linux-gnu]
|
||||||
|
|
||||||
# C compiler to be used to compiler C code and link Rust code. Note that the
|
# C compiler to be used to compiler C code. Note that the
|
||||||
# default value is platform specific, and if not specified it may also depend on
|
# default value is platform specific, and if not specified it may also depend on
|
||||||
# what platform is crossing to what platform.
|
# what platform is crossing to what platform.
|
||||||
#cc = "cc"
|
#cc = "cc"
|
||||||
@@ -309,6 +309,15 @@
|
|||||||
# This is only used for host targets.
|
# This is only used for host targets.
|
||||||
#cxx = "c++"
|
#cxx = "c++"
|
||||||
|
|
||||||
|
# Archiver to be used to assemble static libraries compiled from C/C++ code.
|
||||||
|
# Note: an absolute path should be used, otherwise LLVM build will break.
|
||||||
|
#ar = "ar"
|
||||||
|
|
||||||
|
# Linker to be used to link Rust code. Note that the
|
||||||
|
# default value is platform specific, and if not specified it may also depend on
|
||||||
|
# what platform is crossing to what platform.
|
||||||
|
#linker = "cc"
|
||||||
|
|
||||||
# Path to the `llvm-config` binary of the installation of a custom LLVM to link
|
# Path to the `llvm-config` binary of the installation of a custom LLVM to link
|
||||||
# against. Note that if this is specifed we don't compile LLVM at all for this
|
# against. Note that if this is specifed we don't compile LLVM at all for this
|
||||||
# target.
|
# target.
|
||||||
|
|||||||
1
src/Cargo.lock
generated
1
src/Cargo.lock
generated
@@ -1994,7 +1994,6 @@ dependencies = [
|
|||||||
"alloc_jemalloc 0.0.0",
|
"alloc_jemalloc 0.0.0",
|
||||||
"alloc_system 0.0.0",
|
"alloc_system 0.0.0",
|
||||||
"build_helper 0.1.0",
|
"build_helper 0.1.0",
|
||||||
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"collections 0.0.0",
|
"collections 0.0.0",
|
||||||
"compiler_builtins 0.0.0",
|
"compiler_builtins 0.0.0",
|
||||||
"core 0.0.0",
|
"core 0.0.0",
|
||||||
|
|||||||
@@ -120,12 +120,6 @@ fn main() {
|
|||||||
cmd.arg("-L").arg(&root);
|
cmd.arg("-L").arg(&root);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass down extra flags, commonly used to configure `-Clinker` when
|
|
||||||
// cross compiling.
|
|
||||||
if let Ok(s) = env::var("RUSTC_FLAGS") {
|
|
||||||
cmd.args(&s.split(" ").filter(|s| !s.is_empty()).collect::<Vec<_>>());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass down incremental directory, if any.
|
// Pass down incremental directory, if any.
|
||||||
if let Ok(dir) = env::var("RUSTC_INCREMENTAL") {
|
if let Ok(dir) = env::var("RUSTC_INCREMENTAL") {
|
||||||
cmd.arg(format!("-Zincremental={}", dir));
|
cmd.arg(format!("-Zincremental={}", dir));
|
||||||
@@ -254,6 +248,13 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass down extra flags, commonly used to configure `-Clinker`.
|
||||||
|
// Linker options should be set for build scripts as well,
|
||||||
|
// can't link a build script executable without a linker!
|
||||||
|
if let Ok(s) = env::var("RUSTC_FLAGS") {
|
||||||
|
cmd.args(&s.split(" ").filter(|s| !s.is_empty()).collect::<Vec<_>>());
|
||||||
|
}
|
||||||
|
|
||||||
let color = match env::var("RUSTC_COLOR") {
|
let color = match env::var("RUSTC_COLOR") {
|
||||||
Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
|
Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
|
||||||
Err(_) => 0,
|
Err(_) => 0,
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ fn main() {
|
|||||||
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
|
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
|
||||||
cmd.arg("-Z").arg("force-unstable-if-unmarked");
|
cmd.arg("-Z").arg("force-unstable-if-unmarked");
|
||||||
}
|
}
|
||||||
|
if let Some(linker) = env::var_os("RUSTDOC_LINKER") {
|
||||||
|
cmd.arg("--linker").arg(linker).arg("-Z").arg("unstable-options");
|
||||||
|
}
|
||||||
|
|
||||||
// Bootstrap's Cargo-command builder sets this variable to the current Rust version; let's pick
|
// Bootstrap's Cargo-command builder sets this variable to the current Rust version; let's pick
|
||||||
// it up so we can make rustdoc print this into the docs
|
// it up so we can make rustdoc print this into the docs
|
||||||
|
|||||||
@@ -413,13 +413,15 @@ impl<'a> Builder<'a> {
|
|||||||
pub fn rustdoc_cmd(&self, host: Interned<String>) -> Command {
|
pub fn rustdoc_cmd(&self, host: Interned<String>) -> Command {
|
||||||
let mut cmd = Command::new(&self.out.join("bootstrap/debug/rustdoc"));
|
let mut cmd = Command::new(&self.out.join("bootstrap/debug/rustdoc"));
|
||||||
let compiler = self.compiler(self.top_stage, host);
|
let compiler = self.compiler(self.top_stage, host);
|
||||||
cmd
|
cmd.env("RUSTC_STAGE", compiler.stage.to_string())
|
||||||
.env("RUSTC_STAGE", compiler.stage.to_string())
|
|
||||||
.env("RUSTC_SYSROOT", self.sysroot(compiler))
|
.env("RUSTC_SYSROOT", self.sysroot(compiler))
|
||||||
.env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
|
.env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
|
||||||
.env("CFG_RELEASE_CHANNEL", &self.build.config.channel)
|
.env("CFG_RELEASE_CHANNEL", &self.build.config.channel)
|
||||||
.env("RUSTDOC_REAL", self.rustdoc(host))
|
.env("RUSTDOC_REAL", self.rustdoc(host))
|
||||||
.env("RUSTDOC_CRATE_VERSION", self.build.rust_version());
|
.env("RUSTDOC_CRATE_VERSION", self.build.rust_version());
|
||||||
|
if let Some(linker) = self.build.linker(host) {
|
||||||
|
cmd.env("RUSTDOC_LINKER", linker);
|
||||||
|
}
|
||||||
cmd
|
cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,6 +487,10 @@ impl<'a> Builder<'a> {
|
|||||||
.env("TEST_MIRI", self.config.test_miri.to_string())
|
.env("TEST_MIRI", self.config.test_miri.to_string())
|
||||||
.env("RUSTC_FLAGS", self.rustc_flags(target).join(" "));
|
.env("RUSTC_FLAGS", self.rustc_flags(target).join(" "));
|
||||||
|
|
||||||
|
if let Some(linker) = self.build.linker(target) {
|
||||||
|
cargo.env("RUSTDOC_LINKER", linker);
|
||||||
|
}
|
||||||
|
|
||||||
if mode != Mode::Tool {
|
if mode != Mode::Tool {
|
||||||
// Tools don't get debuginfo right now, e.g. cargo and rls don't
|
// Tools don't get debuginfo right now, e.g. cargo and rls don't
|
||||||
// get compiled with debuginfo.
|
// get compiled with debuginfo.
|
||||||
@@ -557,17 +563,35 @@ impl<'a> Builder<'a> {
|
|||||||
|
|
||||||
cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
|
cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
|
||||||
|
|
||||||
// Specify some various options for build scripts used throughout
|
// Throughout the build Cargo can execute a number of build scripts
|
||||||
// the build.
|
// compiling C/C++ code and we need to pass compilers, archivers, flags, etc
|
||||||
|
// obtained previously to those build scripts.
|
||||||
|
// Build scripts use either the `cc` crate or `configure/make` so we pass
|
||||||
|
// the options through environment variables that are fetched and understood by both.
|
||||||
//
|
//
|
||||||
// FIXME: the guard against msvc shouldn't need to be here
|
// FIXME: the guard against msvc shouldn't need to be here
|
||||||
if !target.contains("msvc") {
|
if !target.contains("msvc") {
|
||||||
cargo.env(format!("CC_{}", target), self.cc(target))
|
let cc = self.cc(target);
|
||||||
.env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
|
cargo.env(format!("CC_{}", target), cc)
|
||||||
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
|
.env("CC", cc);
|
||||||
|
|
||||||
|
let cflags = self.cflags(target).join(" ");
|
||||||
|
cargo.env(format!("CFLAGS_{}", target), cflags.clone())
|
||||||
|
.env("CFLAGS", cflags.clone());
|
||||||
|
|
||||||
|
if let Some(ar) = self.ar(target) {
|
||||||
|
let ranlib = format!("{} s", ar.display());
|
||||||
|
cargo.env(format!("AR_{}", target), ar)
|
||||||
|
.env("AR", ar)
|
||||||
|
.env(format!("RANLIB_{}", target), ranlib.clone())
|
||||||
|
.env("RANLIB", ranlib);
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(cxx) = self.cxx(target) {
|
if let Ok(cxx) = self.cxx(target) {
|
||||||
cargo.env(format!("CXX_{}", target), cxx);
|
cargo.env(format!("CXX_{}", target), cxx)
|
||||||
|
.env("CXX", cxx)
|
||||||
|
.env(format!("CXXFLAGS_{}", target), cflags.clone())
|
||||||
|
.env("CXXFLAGS", cflags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,20 +31,51 @@
|
|||||||
//! ever be probed for. Instead the compilers found here will be used for
|
//! ever be probed for. Instead the compilers found here will be used for
|
||||||
//! everything.
|
//! everything.
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::{env, iter};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::iter;
|
|
||||||
|
|
||||||
use build_helper::{cc2ar, output};
|
use build_helper::output;
|
||||||
use cc;
|
use cc;
|
||||||
|
|
||||||
use Build;
|
use Build;
|
||||||
use config::Target;
|
use config::Target;
|
||||||
use cache::Interned;
|
use cache::Interned;
|
||||||
|
|
||||||
|
// The `cc` crate doesn't provide a way to obtain a path to the detected archiver,
|
||||||
|
// so use some simplified logic here. First we respect the environment variable `AR`, then
|
||||||
|
// try to infer the archiver path from the C compiler path.
|
||||||
|
// In the future this logic should be replaced by calling into the `cc` crate.
|
||||||
|
fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
|
||||||
|
if let Some(ar) = env::var_os("AR") {
|
||||||
|
Some(PathBuf::from(ar))
|
||||||
|
} else if target.contains("msvc") {
|
||||||
|
None
|
||||||
|
} else if target.contains("musl") {
|
||||||
|
Some(PathBuf::from("ar"))
|
||||||
|
} else if target.contains("openbsd") {
|
||||||
|
Some(PathBuf::from("ar"))
|
||||||
|
} else {
|
||||||
|
let parent = cc.parent().unwrap();
|
||||||
|
let file = cc.file_name().unwrap().to_str().unwrap();
|
||||||
|
for suffix in &["gcc", "cc", "clang"] {
|
||||||
|
if let Some(idx) = file.rfind(suffix) {
|
||||||
|
let mut file = file[..idx].to_owned();
|
||||||
|
file.push_str("ar");
|
||||||
|
return Some(parent.join(&file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(parent.join(file))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find(build: &mut Build) {
|
pub fn find(build: &mut Build) {
|
||||||
// For all targets we're going to need a C compiler for building some shims
|
// For all targets we're going to need a C compiler for building some shims
|
||||||
// and such as well as for being a linker for Rust code.
|
// and such as well as for being a linker for Rust code.
|
||||||
for target in build.targets.iter().chain(&build.hosts).cloned().chain(iter::once(build.build)) {
|
let targets = build.targets.iter().chain(&build.hosts).cloned().chain(iter::once(build.build))
|
||||||
|
.collect::<HashSet<_>>();
|
||||||
|
for target in targets.into_iter() {
|
||||||
let mut cfg = cc::Build::new();
|
let mut cfg = cc::Build::new();
|
||||||
cfg.cargo_metadata(false).opt_level(0).warnings(false).debug(false)
|
cfg.cargo_metadata(false).opt_level(0).warnings(false).debug(false)
|
||||||
.target(&target).host(&build.build);
|
.target(&target).host(&build.build);
|
||||||
@@ -57,16 +88,23 @@ pub fn find(build: &mut Build) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let compiler = cfg.get_compiler();
|
let compiler = cfg.get_compiler();
|
||||||
let ar = cc2ar(compiler.path(), &target);
|
let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) {
|
||||||
|
ar
|
||||||
|
} else {
|
||||||
|
cc2ar(compiler.path(), &target)
|
||||||
|
};
|
||||||
|
|
||||||
build.verbose(&format!("CC_{} = {:?}", &target, compiler.path()));
|
build.verbose(&format!("CC_{} = {:?}", &target, compiler.path()));
|
||||||
if let Some(ref ar) = ar {
|
build.cc.insert(target, compiler);
|
||||||
|
if let Some(ar) = ar {
|
||||||
build.verbose(&format!("AR_{} = {:?}", &target, ar));
|
build.verbose(&format!("AR_{} = {:?}", &target, ar));
|
||||||
|
build.ar.insert(target, ar);
|
||||||
}
|
}
|
||||||
build.cc.insert(target, (compiler, ar));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For all host triples we need to find a C++ compiler as well
|
// For all host triples we need to find a C++ compiler as well
|
||||||
for host in build.hosts.iter().cloned().chain(iter::once(build.build)) {
|
let hosts = build.hosts.iter().cloned().chain(iter::once(build.build)).collect::<HashSet<_>>();
|
||||||
|
for host in hosts.into_iter() {
|
||||||
let mut cfg = cc::Build::new();
|
let mut cfg = cc::Build::new();
|
||||||
cfg.cargo_metadata(false).opt_level(0).warnings(false).debug(false).cpp(true)
|
cfg.cargo_metadata(false).opt_level(0).warnings(false).debug(false).cpp(true)
|
||||||
.target(&host).host(&build.build);
|
.target(&host).host(&build.build);
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ impl Step for Compiletest {
|
|||||||
// Avoid depending on rustdoc when we don't need it.
|
// Avoid depending on rustdoc when we don't need it.
|
||||||
if mode == "rustdoc" || mode == "run-make" {
|
if mode == "rustdoc" || mode == "run-make" {
|
||||||
cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host));
|
cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host));
|
||||||
|
if let Some(linker) = build.linker(target) {
|
||||||
|
cmd.arg("--linker").arg(linker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
|
cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
|
||||||
@@ -806,6 +809,9 @@ impl Step for Compiletest {
|
|||||||
.arg("--cflags").arg(build.cflags(target).join(" "))
|
.arg("--cflags").arg(build.cflags(target).join(" "))
|
||||||
.arg("--llvm-components").arg(llvm_components.trim())
|
.arg("--llvm-components").arg(llvm_components.trim())
|
||||||
.arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());
|
.arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());
|
||||||
|
if let Some(ar) = build.ar(target) {
|
||||||
|
cmd.arg("--ar").arg(ar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if suite == "run-make" && !build.config.llvm_enabled {
|
if suite == "run-make" && !build.config.llvm_enabled {
|
||||||
@@ -831,7 +837,7 @@ impl Step for Compiletest {
|
|||||||
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
|
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
|
||||||
// rather than stomp over it.
|
// rather than stomp over it.
|
||||||
if target.contains("msvc") {
|
if target.contains("msvc") {
|
||||||
for &(ref k, ref v) in build.cc[&target].0.env() {
|
for &(ref k, ref v) in build.cc[&target].env() {
|
||||||
if k != "PATH" {
|
if k != "PATH" {
|
||||||
cmd.env(k, v);
|
cmd.env(k, v);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,8 @@ pub struct Target {
|
|||||||
pub jemalloc: Option<PathBuf>,
|
pub jemalloc: Option<PathBuf>,
|
||||||
pub cc: Option<PathBuf>,
|
pub cc: Option<PathBuf>,
|
||||||
pub cxx: Option<PathBuf>,
|
pub cxx: Option<PathBuf>,
|
||||||
|
pub ar: Option<PathBuf>,
|
||||||
|
pub linker: Option<PathBuf>,
|
||||||
pub ndk: Option<PathBuf>,
|
pub ndk: Option<PathBuf>,
|
||||||
pub crt_static: Option<bool>,
|
pub crt_static: Option<bool>,
|
||||||
pub musl_root: Option<PathBuf>,
|
pub musl_root: Option<PathBuf>,
|
||||||
@@ -282,6 +284,8 @@ struct TomlTarget {
|
|||||||
jemalloc: Option<String>,
|
jemalloc: Option<String>,
|
||||||
cc: Option<String>,
|
cc: Option<String>,
|
||||||
cxx: Option<String>,
|
cxx: Option<String>,
|
||||||
|
ar: Option<String>,
|
||||||
|
linker: Option<String>,
|
||||||
android_ndk: Option<String>,
|
android_ndk: Option<String>,
|
||||||
crt_static: Option<bool>,
|
crt_static: Option<bool>,
|
||||||
musl_root: Option<String>,
|
musl_root: Option<String>,
|
||||||
@@ -484,8 +488,10 @@ impl Config {
|
|||||||
if let Some(ref s) = cfg.android_ndk {
|
if let Some(ref s) = cfg.android_ndk {
|
||||||
target.ndk = Some(env::current_dir().unwrap().join(s));
|
target.ndk = Some(env::current_dir().unwrap().join(s));
|
||||||
}
|
}
|
||||||
target.cxx = cfg.cxx.clone().map(PathBuf::from);
|
|
||||||
target.cc = cfg.cc.clone().map(PathBuf::from);
|
target.cc = cfg.cc.clone().map(PathBuf::from);
|
||||||
|
target.cxx = cfg.cxx.clone().map(PathBuf::from);
|
||||||
|
target.ar = cfg.ar.clone().map(PathBuf::from);
|
||||||
|
target.linker = cfg.linker.clone().map(PathBuf::from);
|
||||||
target.crt_static = cfg.crt_static.clone();
|
target.crt_static = cfg.crt_static.clone();
|
||||||
target.musl_root = cfg.musl_root.clone().map(PathBuf::from);
|
target.musl_root = cfg.musl_root.clone().map(PathBuf::from);
|
||||||
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);
|
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);
|
||||||
|
|||||||
@@ -240,10 +240,11 @@ pub struct Build {
|
|||||||
lldb_python_dir: Option<String>,
|
lldb_python_dir: Option<String>,
|
||||||
|
|
||||||
// Runtime state filled in later on
|
// Runtime state filled in later on
|
||||||
// target -> (cc, ar)
|
// C/C++ compilers and archiver for all targets
|
||||||
cc: HashMap<Interned<String>, (cc::Tool, Option<PathBuf>)>,
|
cc: HashMap<Interned<String>, cc::Tool>,
|
||||||
// host -> (cc, ar)
|
|
||||||
cxx: HashMap<Interned<String>, cc::Tool>,
|
cxx: HashMap<Interned<String>, cc::Tool>,
|
||||||
|
ar: HashMap<Interned<String>, PathBuf>,
|
||||||
|
// Misc
|
||||||
crates: HashMap<Interned<String>, Crate>,
|
crates: HashMap<Interned<String>, Crate>,
|
||||||
is_sudo: bool,
|
is_sudo: bool,
|
||||||
ci_env: CiEnv,
|
ci_env: CiEnv,
|
||||||
@@ -324,6 +325,7 @@ impl Build {
|
|||||||
rls_info,
|
rls_info,
|
||||||
cc: HashMap::new(),
|
cc: HashMap::new(),
|
||||||
cxx: HashMap::new(),
|
cxx: HashMap::new(),
|
||||||
|
ar: HashMap::new(),
|
||||||
crates: HashMap::new(),
|
crates: HashMap::new(),
|
||||||
lldb_version: None,
|
lldb_version: None,
|
||||||
lldb_python_dir: None,
|
lldb_python_dir: None,
|
||||||
@@ -612,7 +614,7 @@ impl Build {
|
|||||||
|
|
||||||
/// Returns the path to the C compiler for the target specified.
|
/// Returns the path to the C compiler for the target specified.
|
||||||
fn cc(&self, target: Interned<String>) -> &Path {
|
fn cc(&self, target: Interned<String>) -> &Path {
|
||||||
self.cc[&target].0.path()
|
self.cc[&target].path()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of flags to pass to the C compiler for the target
|
/// Returns a list of flags to pass to the C compiler for the target
|
||||||
@@ -620,7 +622,7 @@ impl Build {
|
|||||||
fn cflags(&self, target: Interned<String>) -> Vec<String> {
|
fn cflags(&self, target: Interned<String>) -> Vec<String> {
|
||||||
// Filter out -O and /O (the optimization flags) that we picked up from
|
// Filter out -O and /O (the optimization flags) that we picked up from
|
||||||
// cc-rs because the build scripts will determine that for themselves.
|
// cc-rs because the build scripts will determine that for themselves.
|
||||||
let mut base = self.cc[&target].0.args().iter()
|
let mut base = self.cc[&target].args().iter()
|
||||||
.map(|s| s.to_string_lossy().into_owned())
|
.map(|s| s.to_string_lossy().into_owned())
|
||||||
.filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
|
.filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@@ -644,7 +646,11 @@ impl Build {
|
|||||||
|
|
||||||
/// Returns the path to the `ar` archive utility for the target specified.
|
/// Returns the path to the `ar` archive utility for the target specified.
|
||||||
fn ar(&self, target: Interned<String>) -> Option<&Path> {
|
fn ar(&self, target: Interned<String>) -> Option<&Path> {
|
||||||
self.cc[&target].1.as_ref().map(|p| &**p)
|
self.ar.get(&target).map(|p| &**p)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn linker(&self, target: Interned<String>) -> Option<&Path> {
|
||||||
|
self.config.target_config.get(&target).and_then(|c| c.linker.as_ref().map(|p| &**p))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the C++ compiler for the target specified.
|
/// Returns the path to the C++ compiler for the target specified.
|
||||||
@@ -667,7 +673,10 @@ impl Build {
|
|||||||
// than an entry here.
|
// than an entry here.
|
||||||
|
|
||||||
let mut base = Vec::new();
|
let mut base = Vec::new();
|
||||||
if target != self.config.build && !target.contains("msvc") &&
|
if let Some(linker) = self.linker(target) {
|
||||||
|
// If linker was explictly provided, force it on all the compiled Rust code.
|
||||||
|
base.push(format!("-Clinker={}", linker.display()));
|
||||||
|
} else if target != self.config.build && !target.contains("msvc") &&
|
||||||
!target.contains("emscripten") {
|
!target.contains("emscripten") {
|
||||||
base.push(format!("-Clinker={}", self.cc(target).display()));
|
base.push(format!("-Clinker={}", self.cc(target).display()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,6 +227,13 @@ impl Step for Llvm {
|
|||||||
cfg.build_arg("-j").build_arg(build.jobs().to_string());
|
cfg.build_arg("-j").build_arg(build.jobs().to_string());
|
||||||
cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
|
cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
|
||||||
cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
|
cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
|
||||||
|
if let Some(ar) = build.ar(target) {
|
||||||
|
if ar.is_absolute() {
|
||||||
|
// LLVM build breaks if `CMAKE_AR` is a relative path, for some reason it
|
||||||
|
// tries to resolve this path in the LLVM build directory.
|
||||||
|
cfg.define("CMAKE_AR", sanitize_cc(ar));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
configure_compilers(&mut cfg);
|
configure_compilers(&mut cfg);
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ impl<'a> Builder<'a> {
|
|||||||
if compiler.host.contains("msvc") {
|
if compiler.host.contains("msvc") {
|
||||||
let curpaths = env::var_os("PATH").unwrap_or_default();
|
let curpaths = env::var_os("PATH").unwrap_or_default();
|
||||||
let curpaths = env::split_paths(&curpaths).collect::<Vec<_>>();
|
let curpaths = env::split_paths(&curpaths).collect::<Vec<_>>();
|
||||||
for &(ref k, ref v) in self.cc[&compiler.host].0.env() {
|
for &(ref k, ref v) in self.cc[&compiler.host].env() {
|
||||||
if k != "PATH" {
|
if k != "PATH" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,27 +138,6 @@ pub fn gnu_target(target: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
|
|
||||||
if target.contains("msvc") {
|
|
||||||
None
|
|
||||||
} else if target.contains("musl") {
|
|
||||||
Some(PathBuf::from("ar"))
|
|
||||||
} else if target.contains("openbsd") {
|
|
||||||
Some(PathBuf::from("ar"))
|
|
||||||
} else {
|
|
||||||
let parent = cc.parent().unwrap();
|
|
||||||
let file = cc.file_name().unwrap().to_str().unwrap();
|
|
||||||
for suffix in &["gcc", "cc", "clang"] {
|
|
||||||
if let Some(idx) = file.rfind(suffix) {
|
|
||||||
let mut file = file[..idx].to_owned();
|
|
||||||
file.push_str("ar");
|
|
||||||
return Some(parent.join(&file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(parent.join(file))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn make(host: &str) -> PathBuf {
|
pub fn make(host: &str) -> PathBuf {
|
||||||
if host.contains("bitrig") || host.contains("dragonfly") ||
|
if host.contains("bitrig") || host.contains("dragonfly") ||
|
||||||
host.contains("freebsd") || host.contains("netbsd") ||
|
host.contains("freebsd") || host.contains("netbsd") ||
|
||||||
|
|||||||
@@ -63,15 +63,6 @@ fn main() {
|
|||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let compiler = cc::Build::new().get_compiler();
|
|
||||||
// only msvc returns None for ar so unwrap is okay
|
|
||||||
let ar = build_helper::cc2ar(compiler.path(), &target).unwrap();
|
|
||||||
let cflags = compiler.args()
|
|
||||||
.iter()
|
|
||||||
.map(|s| s.to_str().unwrap())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(" ");
|
|
||||||
|
|
||||||
let mut cmd = Command::new("sh");
|
let mut cmd = Command::new("sh");
|
||||||
cmd.arg(native.src_dir.join("configure")
|
cmd.arg(native.src_dir.join("configure")
|
||||||
.to_str()
|
.to_str()
|
||||||
@@ -79,8 +70,6 @@ fn main() {
|
|||||||
.replace("C:\\", "/c/")
|
.replace("C:\\", "/c/")
|
||||||
.replace("\\", "/"))
|
.replace("\\", "/"))
|
||||||
.current_dir(&native.out_dir)
|
.current_dir(&native.out_dir)
|
||||||
.env("CC", compiler.path())
|
|
||||||
.env("EXTRA_CFLAGS", cflags.clone())
|
|
||||||
// jemalloc generates Makefile deps using GCC's "-MM" flag. This means
|
// jemalloc generates Makefile deps using GCC's "-MM" flag. This means
|
||||||
// that GCC will run the preprocessor, and only the preprocessor, over
|
// that GCC will run the preprocessor, and only the preprocessor, over
|
||||||
// jemalloc's source files. If we don't specify CPPFLAGS, then at least
|
// jemalloc's source files. If we don't specify CPPFLAGS, then at least
|
||||||
@@ -89,9 +78,7 @@ fn main() {
|
|||||||
// passed to GCC, and then GCC won't define the
|
// passed to GCC, and then GCC won't define the
|
||||||
// "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" macro that jemalloc needs to
|
// "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" macro that jemalloc needs to
|
||||||
// select an atomic operation implementation.
|
// select an atomic operation implementation.
|
||||||
.env("CPPFLAGS", cflags.clone())
|
.env("CPPFLAGS", env::var_os("CFLAGS").unwrap_or_default());
|
||||||
.env("AR", &ar)
|
|
||||||
.env("RANLIB", format!("{} s", ar.display()));
|
|
||||||
|
|
||||||
if target.contains("ios") {
|
if target.contains("ios") {
|
||||||
cmd.arg("--disable-tls");
|
cmd.arg("--disable-tls");
|
||||||
|
|||||||
@@ -246,6 +246,9 @@ pub fn opts() -> Vec<RustcOptGroup> {
|
|||||||
unstable("crate-version", |o| {
|
unstable("crate-version", |o| {
|
||||||
o.optopt("", "crate-version", "crate version to print into documentation", "VERSION")
|
o.optopt("", "crate-version", "crate version to print into documentation", "VERSION")
|
||||||
}),
|
}),
|
||||||
|
unstable("linker", |o| {
|
||||||
|
o.optopt("", "linker", "linker used for building executable test code", "PATH")
|
||||||
|
}),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,15 +360,16 @@ pub fn main_args(args: &[String]) -> isize {
|
|||||||
let playground_url = matches.opt_str("playground-url");
|
let playground_url = matches.opt_str("playground-url");
|
||||||
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
|
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
|
||||||
let display_warnings = matches.opt_present("display-warnings");
|
let display_warnings = matches.opt_present("display-warnings");
|
||||||
|
let linker = matches.opt_str("linker");
|
||||||
|
|
||||||
match (should_test, markdown_input) {
|
match (should_test, markdown_input) {
|
||||||
(true, true) => {
|
(true, true) => {
|
||||||
return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, render_type,
|
return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, render_type,
|
||||||
display_warnings)
|
display_warnings, linker)
|
||||||
}
|
}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
return test::run(input, cfgs, libs, externs, test_args, crate_name, maybe_sysroot,
|
return test::run(input, cfgs, libs, externs, test_args, crate_name, maybe_sysroot,
|
||||||
render_type, display_warnings)
|
render_type, display_warnings, linker)
|
||||||
}
|
}
|
||||||
(false, true) => return markdown::render(input,
|
(false, true) => return markdown::render(input,
|
||||||
output.unwrap_or(PathBuf::from("doc")),
|
output.unwrap_or(PathBuf::from("doc")),
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
|
|||||||
/// Run any tests/code examples in the markdown file `input`.
|
/// Run any tests/code examples in the markdown file `input`.
|
||||||
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||||
mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
|
mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
|
||||||
render_type: RenderType, display_warnings: bool) -> isize {
|
render_type: RenderType, display_warnings: bool, linker: Option<String>) -> isize {
|
||||||
let input_str = match load_string(input) {
|
let input_str = match load_string(input) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(LoadStringError::ReadFail) => return 1,
|
Err(LoadStringError::ReadFail) => return 1,
|
||||||
@@ -154,7 +154,7 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
|||||||
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
|
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
|
||||||
true, opts, maybe_sysroot, None,
|
true, opts, maybe_sysroot, None,
|
||||||
Some(input.to_owned()),
|
Some(input.to_owned()),
|
||||||
render_type);
|
render_type, linker);
|
||||||
if render_type == RenderType::Pulldown {
|
if render_type == RenderType::Pulldown {
|
||||||
old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
|
old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
|
||||||
find_testable_code(&input_str, &mut collector, DUMMY_SP);
|
find_testable_code(&input_str, &mut collector, DUMMY_SP);
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ pub fn run(input: &str,
|
|||||||
crate_name: Option<String>,
|
crate_name: Option<String>,
|
||||||
maybe_sysroot: Option<PathBuf>,
|
maybe_sysroot: Option<PathBuf>,
|
||||||
render_type: RenderType,
|
render_type: RenderType,
|
||||||
display_warnings: bool)
|
display_warnings: bool,
|
||||||
|
linker: Option<String>)
|
||||||
-> isize {
|
-> isize {
|
||||||
let input_path = PathBuf::from(input);
|
let input_path = PathBuf::from(input);
|
||||||
let input = config::Input::File(input_path.clone());
|
let input = config::Input::File(input_path.clone());
|
||||||
@@ -121,7 +122,8 @@ pub fn run(input: &str,
|
|||||||
maybe_sysroot,
|
maybe_sysroot,
|
||||||
Some(codemap),
|
Some(codemap),
|
||||||
None,
|
None,
|
||||||
render_type);
|
render_type,
|
||||||
|
linker);
|
||||||
|
|
||||||
{
|
{
|
||||||
let map = hir::map::map_crate(&sess, &*cstore, &mut hir_forest, &defs);
|
let map = hir::map::map_crate(&sess, &*cstore, &mut hir_forest, &defs);
|
||||||
@@ -180,7 +182,8 @@ fn run_test(test: &str, cratename: &str, filename: &str, cfgs: Vec<String>, libs
|
|||||||
externs: Externs,
|
externs: Externs,
|
||||||
should_panic: bool, no_run: bool, as_test_harness: bool,
|
should_panic: bool, no_run: bool, as_test_harness: bool,
|
||||||
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
|
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
|
||||||
maybe_sysroot: Option<PathBuf>) {
|
maybe_sysroot: Option<PathBuf>,
|
||||||
|
linker: Option<String>) {
|
||||||
// the test harness wants its own `main` & top level functions, so
|
// the test harness wants its own `main` & top level functions, so
|
||||||
// never wrap the test in `fn main() { ... }`
|
// never wrap the test in `fn main() { ... }`
|
||||||
let test = make_test(test, Some(cratename), as_test_harness, opts);
|
let test = make_test(test, Some(cratename), as_test_harness, opts);
|
||||||
@@ -201,6 +204,7 @@ fn run_test(test: &str, cratename: &str, filename: &str, cfgs: Vec<String>, libs
|
|||||||
externs,
|
externs,
|
||||||
cg: config::CodegenOptions {
|
cg: config::CodegenOptions {
|
||||||
prefer_dynamic: true,
|
prefer_dynamic: true,
|
||||||
|
linker,
|
||||||
.. config::basic_codegen_options()
|
.. config::basic_codegen_options()
|
||||||
},
|
},
|
||||||
test: as_test_harness,
|
test: as_test_harness,
|
||||||
@@ -442,13 +446,14 @@ pub struct Collector {
|
|||||||
filename: Option<String>,
|
filename: Option<String>,
|
||||||
// to be removed when hoedown will be removed as well
|
// to be removed when hoedown will be removed as well
|
||||||
pub render_type: RenderType,
|
pub render_type: RenderType,
|
||||||
|
linker: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collector {
|
impl Collector {
|
||||||
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||||
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
|
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
|
||||||
codemap: Option<Rc<CodeMap>>, filename: Option<String>,
|
codemap: Option<Rc<CodeMap>>, filename: Option<String>,
|
||||||
render_type: RenderType) -> Collector {
|
render_type: RenderType, linker: Option<String>) -> Collector {
|
||||||
Collector {
|
Collector {
|
||||||
tests: Vec::new(),
|
tests: Vec::new(),
|
||||||
old_tests: HashMap::new(),
|
old_tests: HashMap::new(),
|
||||||
@@ -464,6 +469,7 @@ impl Collector {
|
|||||||
codemap,
|
codemap,
|
||||||
filename,
|
filename,
|
||||||
render_type,
|
render_type,
|
||||||
|
linker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +516,7 @@ impl Collector {
|
|||||||
let cratename = self.cratename.to_string();
|
let cratename = self.cratename.to_string();
|
||||||
let opts = self.opts.clone();
|
let opts = self.opts.clone();
|
||||||
let maybe_sysroot = self.maybe_sysroot.clone();
|
let maybe_sysroot = self.maybe_sysroot.clone();
|
||||||
|
let linker = self.linker.clone();
|
||||||
debug!("Creating test {}: {}", name, test);
|
debug!("Creating test {}: {}", name, test);
|
||||||
self.tests.push(testing::TestDescAndFn {
|
self.tests.push(testing::TestDescAndFn {
|
||||||
desc: testing::TestDesc {
|
desc: testing::TestDesc {
|
||||||
@@ -538,7 +545,8 @@ impl Collector {
|
|||||||
compile_fail,
|
compile_fail,
|
||||||
error_codes,
|
error_codes,
|
||||||
&opts,
|
&opts,
|
||||||
maybe_sysroot)
|
maybe_sysroot,
|
||||||
|
linker)
|
||||||
})
|
})
|
||||||
} {
|
} {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ rustc_tsan = { path = "../librustc_tsan" }
|
|||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
build_helper = { path = "../build_helper" }
|
build_helper = { path = "../build_helper" }
|
||||||
cc = "1.0.1"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
backtrace = []
|
backtrace = []
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
extern crate build_helper;
|
extern crate build_helper;
|
||||||
extern crate cc;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
@@ -77,12 +76,6 @@ fn main() {
|
|||||||
fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> {
|
fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> {
|
||||||
let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace", ".libs")?;
|
let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace", ".libs")?;
|
||||||
|
|
||||||
let compiler = cc::Build::new().get_compiler();
|
|
||||||
// only msvc returns None for ar so unwrap is okay
|
|
||||||
let ar = build_helper::cc2ar(compiler.path(), target).unwrap();
|
|
||||||
let mut cflags = compiler.args().iter().map(|s| s.to_str().unwrap())
|
|
||||||
.collect::<Vec<_>>().join(" ");
|
|
||||||
cflags.push_str(" -fvisibility=hidden");
|
|
||||||
run(Command::new("sh")
|
run(Command::new("sh")
|
||||||
.current_dir(&native.out_dir)
|
.current_dir(&native.out_dir)
|
||||||
.arg(native.src_dir.join("configure").to_str().unwrap()
|
.arg(native.src_dir.join("configure").to_str().unwrap()
|
||||||
@@ -94,10 +87,7 @@ fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> {
|
|||||||
.arg("--disable-host-shared")
|
.arg("--disable-host-shared")
|
||||||
.arg(format!("--host={}", build_helper::gnu_target(target)))
|
.arg(format!("--host={}", build_helper::gnu_target(target)))
|
||||||
.arg(format!("--build={}", build_helper::gnu_target(host)))
|
.arg(format!("--build={}", build_helper::gnu_target(host)))
|
||||||
.env("CC", compiler.path())
|
.env("CFLAGS", env::var("CFLAGS").unwrap_or_default() + " -fvisibility=hidden"),
|
||||||
.env("AR", &ar)
|
|
||||||
.env("RANLIB", format!("{} s", ar.display()))
|
|
||||||
.env("CFLAGS", cflags),
|
|
||||||
BuildExpectation::None);
|
BuildExpectation::None);
|
||||||
|
|
||||||
run(Command::new(build_helper::make(host))
|
run(Command::new(build_helper::make(host))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ all:
|
|||||||
mkdir $(TMPDIR)/b
|
mkdir $(TMPDIR)/b
|
||||||
$(call COMPILE_OBJ,$(TMPDIR)/a/foo.o,foo.c)
|
$(call COMPILE_OBJ,$(TMPDIR)/a/foo.o,foo.c)
|
||||||
$(call COMPILE_OBJ,$(TMPDIR)/b/foo.o,bar.c)
|
$(call COMPILE_OBJ,$(TMPDIR)/b/foo.o,bar.c)
|
||||||
ar crus $(TMPDIR)/libfoo.a $(TMPDIR)/a/foo.o $(TMPDIR)/b/foo.o
|
$(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/a/foo.o $(TMPDIR)/b/foo.o
|
||||||
$(RUSTC) foo.rs
|
$(RUSTC) foo.rs
|
||||||
$(RUSTC) bar.rs
|
$(RUSTC) bar.rs
|
||||||
$(call RUN,bar)
|
$(call RUN,bar)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
ifneq (,$(findstring MINGW,$(UNAME)))
|
ifneq (,$(findstring MINGW,$(UNAME)))
|
||||||
ifndef IS_MSVC
|
ifndef IS_MSVC
|
||||||
all:
|
all:
|
||||||
g++ foo.cpp -c -o $(TMPDIR)/foo.o
|
$(CXX) foo.cpp -c -o $(TMPDIR)/foo.o
|
||||||
ar crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
|
$(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
|
||||||
$(RUSTC) foo.rs -lfoo -lstdc++
|
$(RUSTC) foo.rs -lfoo -lstdc++
|
||||||
$(call RUN,foo)
|
$(call RUN,foo)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
all:
|
all:
|
||||||
touch $(TMPDIR)/rust.metadata.bin
|
touch $(TMPDIR)/rust.metadata.bin
|
||||||
ar crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/rust.metadata.bin
|
$(AR) crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/rust.metadata.bin
|
||||||
$(RUSTC) foo.rs 2>&1 | grep "can't find crate for"
|
$(RUSTC) foo.rs 2>&1 | grep "can't find crate for"
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ extern crate rustc_errors;
|
|||||||
extern crate rustc_trans;
|
extern crate rustc_trans;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
|
||||||
use rustc::dep_graph::DepGraph;
|
|
||||||
use rustc::session::{build_session, Session};
|
use rustc::session::{build_session, Session};
|
||||||
use rustc::session::config::{basic_options, build_configuration, Input,
|
use rustc::session::config::{basic_options, build_configuration, Input,
|
||||||
OutputType, OutputTypes};
|
OutputType, OutputTypes};
|
||||||
@@ -56,6 +55,9 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
|
|||||||
let mut opts = basic_options();
|
let mut opts = basic_options();
|
||||||
opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
|
opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
|
||||||
opts.maybe_sysroot = Some(sysroot);
|
opts.maybe_sysroot = Some(sysroot);
|
||||||
|
if let Ok(linker) = std::env::var("RUSTC_LINKER") {
|
||||||
|
opts.cg.linker = Some(linker);
|
||||||
|
}
|
||||||
|
|
||||||
let descriptions = Registry::new(&rustc::DIAGNOSTICS);
|
let descriptions = Registry::new(&rustc::DIAGNOSTICS);
|
||||||
let cstore = Rc::new(CStore::new(Box::new(rustc_trans::LlvmMetadataLoader)));
|
let cstore = Rc::new(CStore::new(Box::new(rustc_trans::LlvmMetadataLoader)));
|
||||||
@@ -67,8 +69,7 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
|
|||||||
|
|
||||||
fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
|
fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
|
||||||
let (sess, cstore) = basic_sess(sysroot);
|
let (sess, cstore) = basic_sess(sysroot);
|
||||||
let cfg = build_configuration(&sess, HashSet::new());
|
|
||||||
let control = CompileController::basic();
|
let control = CompileController::basic();
|
||||||
let input = Input::Str { name: anon_src(), input: code };
|
let input = Input::Str { name: anon_src(), input: code };
|
||||||
compile_input(&sess, &cstore, &input, &None, &Some(output), None, &control);
|
let _ = compile_input(&sess, &cstore, &input, &None, &Some(output), None, &control);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
all: foo.rs
|
all: foo.rs
|
||||||
$(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs
|
$(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs
|
||||||
$(HOST_RPATH_ENV) '$(RUSTDOC)' --test --cfg 'feature="bar"' \
|
$(RUSTDOC) --test --cfg 'feature="bar"' \
|
||||||
-L $(TMPDIR) foo.rs |\
|
-L $(TMPDIR) foo.rs |\
|
||||||
grep -q 'foo.rs - foo (line 11) ... ok'
|
grep -q 'foo.rs - foo (line 11) ... ok'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
-include ../tools.mk
|
-include ../tools.mk
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(HOST_RPATH_ENV) '$(RUSTDOC)' -o "$(TMPDIR)/foo/bar/doc" foo.rs
|
$(RUSTDOC) -o "$(TMPDIR)/foo/bar/doc" foo.rs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
-include ../tools.mk
|
-include ../tools.mk
|
||||||
|
|
||||||
all:
|
all:
|
||||||
ar crus $(TMPDIR)/libfoo.a foo.rs
|
$(AR) crus $(TMPDIR)/libfoo.a foo.rs
|
||||||
ar d $(TMPDIR)/libfoo.a foo.rs
|
$(AR) d $(TMPDIR)/libfoo.a foo.rs
|
||||||
$(RUSTC) foo.rs
|
$(RUSTC) foo.rs
|
||||||
|
|||||||
@@ -7,7 +7,13 @@ TARGET_RPATH_ENV = \
|
|||||||
|
|
||||||
RUSTC_ORIGINAL := $(RUSTC)
|
RUSTC_ORIGINAL := $(RUSTC)
|
||||||
BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)'
|
BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)'
|
||||||
|
BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)'
|
||||||
RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS)
|
RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS)
|
||||||
|
RUSTDOC := $(BARE_RUSTDOC)
|
||||||
|
ifdef RUSTC_LINKER
|
||||||
|
RUSTC := $(RUSTC) -Clinker=$(RUSTC_LINKER)
|
||||||
|
RUSTDOC := $(RUSTDOC) --linker $(RUSTC_LINKER) -Z unstable-options
|
||||||
|
endif
|
||||||
#CC := $(CC) -L $(TMPDIR)
|
#CC := $(CC) -L $(TMPDIR)
|
||||||
HTMLDOCCK := $(PYTHON) $(S)/src/etc/htmldocck.py
|
HTMLDOCCK := $(PYTHON) $(S)/src/etc/htmldocck.py
|
||||||
|
|
||||||
@@ -102,13 +108,13 @@ REMOVE_DYLIBS = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1))
|
|||||||
REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1))
|
REMOVE_RLIBS = rm $(TMPDIR)/$(call RLIB_GLOB,$(1))
|
||||||
|
|
||||||
%.a: %.o
|
%.a: %.o
|
||||||
ar crus $@ $<
|
$(AR) crus $@ $<
|
||||||
ifdef IS_MSVC
|
ifdef IS_MSVC
|
||||||
%.lib: lib%.o
|
%.lib: lib%.o
|
||||||
$(MSVC_LIB) -out:`cygpath -w $@` $<
|
$(MSVC_LIB) -out:`cygpath -w $@` $<
|
||||||
else
|
else
|
||||||
%.lib: lib%.o
|
%.lib: lib%.o
|
||||||
ar crus $@ $<
|
$(AR) crus $@ $<
|
||||||
endif
|
endif
|
||||||
%.dylib: %.o
|
%.dylib: %.o
|
||||||
$(CC) -dynamiclib -Wl,-dylib -o $@ $<
|
$(CC) -dynamiclib -Wl,-dylib -o $@ $<
|
||||||
|
|||||||
@@ -201,6 +201,8 @@ pub struct Config {
|
|||||||
pub cc: String,
|
pub cc: String,
|
||||||
pub cxx: String,
|
pub cxx: String,
|
||||||
pub cflags: String,
|
pub cflags: String,
|
||||||
|
pub ar: String,
|
||||||
|
pub linker: Option<String>,
|
||||||
pub llvm_components: String,
|
pub llvm_components: String,
|
||||||
pub llvm_cxxflags: String,
|
pub llvm_cxxflags: String,
|
||||||
pub nodejs: Option<String>,
|
pub nodejs: Option<String>,
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
|||||||
.reqopt("", "cc", "path to a C compiler", "PATH")
|
.reqopt("", "cc", "path to a C compiler", "PATH")
|
||||||
.reqopt("", "cxx", "path to a C++ compiler", "PATH")
|
.reqopt("", "cxx", "path to a C++ compiler", "PATH")
|
||||||
.reqopt("", "cflags", "flags for the C compiler", "FLAGS")
|
.reqopt("", "cflags", "flags for the C compiler", "FLAGS")
|
||||||
|
.optopt("", "ar", "path to an archiver", "PATH")
|
||||||
|
.optopt("", "linker", "path to a linker", "PATH")
|
||||||
.reqopt("", "llvm-components", "list of LLVM components built in", "LIST")
|
.reqopt("", "llvm-components", "list of LLVM components built in", "LIST")
|
||||||
.reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS")
|
.reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS")
|
||||||
.optopt("", "nodejs", "the name of nodejs", "PATH")
|
.optopt("", "nodejs", "the name of nodejs", "PATH")
|
||||||
@@ -198,6 +200,8 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
|||||||
cc: matches.opt_str("cc").unwrap(),
|
cc: matches.opt_str("cc").unwrap(),
|
||||||
cxx: matches.opt_str("cxx").unwrap(),
|
cxx: matches.opt_str("cxx").unwrap(),
|
||||||
cflags: matches.opt_str("cflags").unwrap(),
|
cflags: matches.opt_str("cflags").unwrap(),
|
||||||
|
ar: matches.opt_str("ar").unwrap_or("ar".into()),
|
||||||
|
linker: matches.opt_str("linker"),
|
||||||
llvm_components: matches.opt_str("llvm-components").unwrap(),
|
llvm_components: matches.opt_str("llvm-components").unwrap(),
|
||||||
llvm_cxxflags: matches.opt_str("llvm-cxxflags").unwrap(),
|
llvm_cxxflags: matches.opt_str("llvm-cxxflags").unwrap(),
|
||||||
nodejs: matches.opt_str("nodejs"),
|
nodejs: matches.opt_str("nodejs"),
|
||||||
@@ -234,6 +238,8 @@ pub fn log_config(config: &Config) {
|
|||||||
logv(c, format!("adb_test_dir: {:?}", config.adb_test_dir));
|
logv(c, format!("adb_test_dir: {:?}", config.adb_test_dir));
|
||||||
logv(c, format!("adb_device_status: {}",
|
logv(c, format!("adb_device_status: {}",
|
||||||
config.adb_device_status));
|
config.adb_device_status));
|
||||||
|
logv(c, format!("ar: {}", config.ar));
|
||||||
|
logv(c, format!("linker: {:?}", config.linker));
|
||||||
logv(c, format!("verbose: {}", config.verbose));
|
logv(c, format!("verbose: {}", config.verbose));
|
||||||
logv(c, format!("quiet: {}", config.quiet));
|
logv(c, format!("quiet: {}", config.quiet));
|
||||||
logv(c, "\n".to_string());
|
logv(c, "\n".to_string());
|
||||||
|
|||||||
@@ -1155,6 +1155,9 @@ actual:\n\
|
|||||||
.arg("-o").arg(out_dir)
|
.arg("-o").arg(out_dir)
|
||||||
.arg(&self.testpaths.file)
|
.arg(&self.testpaths.file)
|
||||||
.args(&self.props.compile_flags);
|
.args(&self.props.compile_flags);
|
||||||
|
if let Some(ref linker) = self.config.linker {
|
||||||
|
rustdoc.arg("--linker").arg(linker).arg("-Z").arg("unstable-options");
|
||||||
|
}
|
||||||
|
|
||||||
self.compose_and_run_compiler(rustdoc, None)
|
self.compose_and_run_compiler(rustdoc, None)
|
||||||
}
|
}
|
||||||
@@ -2101,6 +2104,10 @@ actual:\n\
|
|||||||
.env("LLVM_COMPONENTS", &self.config.llvm_components)
|
.env("LLVM_COMPONENTS", &self.config.llvm_components)
|
||||||
.env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags);
|
.env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags);
|
||||||
|
|
||||||
|
if let Some(ref linker) = self.config.linker {
|
||||||
|
cmd.env("RUSTC_LINKER", linker);
|
||||||
|
}
|
||||||
|
|
||||||
// We don't want RUSTFLAGS set from the outside to interfere with
|
// We don't want RUSTFLAGS set from the outside to interfere with
|
||||||
// compiler flags set in the test cases:
|
// compiler flags set in the test cases:
|
||||||
cmd.env_remove("RUSTFLAGS");
|
cmd.env_remove("RUSTFLAGS");
|
||||||
@@ -2123,7 +2130,8 @@ actual:\n\
|
|||||||
.env("CXX", &self.config.cxx);
|
.env("CXX", &self.config.cxx);
|
||||||
} else {
|
} else {
|
||||||
cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
|
cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
|
||||||
.env("CXX", format!("{} {}", self.config.cxx, self.config.cflags));
|
.env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))
|
||||||
|
.env("AR", &self.config.ar);
|
||||||
|
|
||||||
if self.config.target.contains("windows") {
|
if self.config.target.contains("windows") {
|
||||||
cmd.env("IS_WINDOWS", "1");
|
cmd.env("IS_WINDOWS", "1");
|
||||||
|
|||||||
Reference in New Issue
Block a user