summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-01-22 07:29:24 -0800
committerAlex Crichton <alex@alexcrichton.com>2018-01-27 19:16:21 -0800
commit884715c65420141dc06753f242a224462b120109 (patch)
treea965ef66c12ca076d0f0d08a0ae9bbea302167d6
parentbacb5c58dfdde7c35e99b2b0d8171238cc33cf6c (diff)
downloadrust-884715c65420141dc06753f242a224462b120109.tar.gz
rustc: Load the `rustc_trans` crate at runtime
Building on the work of # 45684 this commit updates the compiler to unconditionally load the `rustc_trans` crate at runtime instead of linking to it at compile time. The end goal of this work is to implement # 46819 where rustc will have multiple backends available to it to load. This commit starts off by removing the `extern crate rustc_trans` from the driver. This involved moving some miscellaneous functionality into the `TransCrate` trait and also required an implementation of how to locate and load the trans backend. This ended up being a little tricky because the sysroot isn't always the right location (for example `--sysroot` arguments) so some extra code was added as well to probe a directory relative to the current dll (the rustc_driver dll). Rustbuild has been updated accordingly as well to have a separate compilation invocation for the `rustc_trans` crate and assembly it accordingly into the sysroot. Finally, the distribution logic for the `rustc` package was also updated to slurp up the trans backends folder. A number of assorted fallout changes were included here as well to ensure tests pass and such, and they should all be commented inline.
-rw-r--r--src/Cargo.lock3
-rw-r--r--src/Cargo.toml1
-rw-r--r--src/bootstrap/check.rs2
-rw-r--r--src/bootstrap/compile.rs234
-rw-r--r--src/bootstrap/dist.rs13
-rw-r--r--src/bootstrap/doc.rs2
-rw-r--r--src/bootstrap/lib.rs3
-rw-r--r--src/bootstrap/native.rs5
-rw-r--r--src/bootstrap/test.rs4
-rw-r--r--src/librustc/Cargo.toml3
-rw-r--r--src/librustc_driver/Cargo.toml6
-rw-r--r--src/librustc_driver/lib.rs290
-rw-r--r--src/librustc_driver/pretty.rs6
-rw-r--r--src/librustc_llvm/Cargo.toml2
-rw-r--r--src/librustc_llvm/build.rs1
-rw-r--r--src/librustc_metadata/dynamic_lib.rs27
-rw-r--r--src/librustc_trans/Cargo.toml4
-rw-r--r--src/librustc_trans/lib.rs26
-rw-r--r--src/librustc_trans_utils/trans_crate.rs16
-rw-r--r--src/librustdoc/core.rs5
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/librustdoc/test.rs5
-rw-r--r--src/rustc/Cargo.toml3
-rw-r--r--src/test/run-make/hotplug_codegen_backend/the_backend.rs4
-rw-r--r--src/test/run-make/issue-19371/foo.rs3
-rw-r--r--src/test/run-make/llvm-pass/Makefile6
-rw-r--r--src/test/run-make/llvm-pass/plugin.rs1
-rw-r--r--src/test/run-pass-fulldeps/create-dir-all-bare.rs12
-rw-r--r--src/test/run-pass-fulldeps/issue-15149.rs18
-rw-r--r--src/test/run-pass-fulldeps/rename-directory.rs10
-rw-r--r--src/test/run-pass-fulldeps/stdio-from.rs13
-rw-r--r--src/test/run-pass-fulldeps/switch-stdout.rs12
-rw-r--r--src/tools/compiletest/src/main.rs13
33 files changed, 553 insertions, 202 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index e7bf1b6b4e1..d26098903ee 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -1933,7 +1933,6 @@ dependencies = [
"rustc_privacy 0.0.0",
"rustc_resolve 0.0.0",
"rustc_save_analysis 0.0.0",
- "rustc_trans 0.0.0",
"rustc_trans_utils 0.0.0",
"rustc_typeck 0.0.0",
"serialize 0.0.0",
@@ -1984,6 +1983,7 @@ dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"build_helper 0.1.0",
"cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_cratesio_shim 0.0.0",
]
@@ -2121,6 +2121,7 @@ dependencies = [
"cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
diff --git a/src/Cargo.toml b/src/Cargo.toml
index ad795b23cf2..c22ba7a37c8 100644
--- a/src/Cargo.toml
+++ b/src/Cargo.toml
@@ -4,6 +4,7 @@ members = [
"rustc",
"libstd",
"libtest",
+ "librustc_trans",
"tools/cargotest",
"tools/clippy",
"tools/compiletest",
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 0bc82c4f9f2..e6871764b2c 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -94,7 +94,7 @@ impl Step for Rustc {
build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
- rustc_cargo(build, target, &mut cargo);
+ rustc_cargo(build, &mut cargo);
run_cargo(build,
&mut cargo,
&librustc_stamp(build, compiler, target),
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 21bbd82dd33..0b247c6f755 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -300,7 +300,11 @@ impl Step for StartupObjects {
}
for obj in ["crt2.o", "dllcrt2.o"].iter() {
- copy(&compiler_file(build.cc(target), obj), &sysroot_dir.join(obj));
+ let src = compiler_file(build,
+ build.cc(target),
+ target,
+ obj);
+ copy(&src, &sysroot_dir.join(obj));
}
}
}
@@ -454,10 +458,6 @@ impl Step for Rustc {
builder.ensure(Test { compiler, target });
- // Build LLVM for our target. This will implicitly build the host LLVM
- // if necessary.
- builder.ensure(native::Llvm { target });
-
if build.force_use_stage1(compiler, target) {
builder.ensure(Rustc {
compiler: builder.compiler(1, build.build),
@@ -487,7 +487,7 @@ impl Step for Rustc {
build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
- rustc_cargo(build, target, &mut cargo);
+ rustc_cargo(build, &mut cargo);
run_cargo(build,
&mut cargo,
&librustc_stamp(build, compiler, target),
@@ -501,14 +501,14 @@ impl Step for Rustc {
}
}
-/// Same as `std_cargo`, but for libtest
-pub fn rustc_cargo(build: &Build,
- target: Interned<String>,
- cargo: &mut Command) {
+pub fn rustc_cargo(build: &Build, cargo: &mut Command) {
cargo.arg("--features").arg(build.rustc_features())
.arg("--manifest-path")
.arg(build.src.join("src/rustc/Cargo.toml"));
+ rustc_cargo_env(build, cargo);
+}
+fn rustc_cargo_env(build: &Build, cargo: &mut Command) {
// Set some configuration variables picked up by build scripts and
// the compiler alike
cargo.env("CFG_RELEASE", build.rust_release())
@@ -536,27 +536,6 @@ pub fn rustc_cargo(build: &Build,
if !build.unstable_features() {
cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
}
- // Flag that rust llvm is in use
- if build.is_rust_llvm(target) {
- cargo.env("LLVM_RUSTLLVM", "1");
- }
- cargo.env("LLVM_CONFIG", build.llvm_config(target));
- let target_config = build.config.target_config.get(&target);
- if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
- cargo.env("CFG_LLVM_ROOT", s);
- }
- // Building with a static libstdc++ is only supported on linux right now,
- // not for MSVC or macOS
- if build.config.llvm_static_stdcpp &&
- !target.contains("freebsd") &&
- !target.contains("windows") &&
- !target.contains("apple") {
- cargo.env("LLVM_STATIC_STDCPP",
- compiler_file(build.cxx(target).unwrap(), "libstdc++.a"));
- }
- if build.config.llvm_link_shared {
- cargo.env("LLVM_LINK_SHARED", "1");
- }
if let Some(ref s) = build.config.rustc_default_linker {
cargo.env("CFG_DEFAULT_LINKER", s);
}
@@ -601,6 +580,137 @@ impl Step for RustcLink {
}
}
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct RustcTrans {
+ pub compiler: Compiler,
+ pub target: Interned<String>,
+}
+
+impl Step for RustcTrans {
+ type Output = ();
+ const ONLY_HOSTS: bool = true;
+ const DEFAULT: bool = true;
+
+ fn should_run(run: ShouldRun) -> ShouldRun {
+ run.path("src/librustc_trans").krate("rustc_trans")
+ }
+
+ fn make_run(run: RunConfig) {
+ run.builder.ensure(RustcTrans {
+ compiler: run.builder.compiler(run.builder.top_stage, run.host),
+ target: run.target,
+ });
+ }
+
+ fn run(self, builder: &Builder) {
+ let build = builder.build;
+ let compiler = self.compiler;
+ let target = self.target;
+
+ builder.ensure(Rustc { compiler, target });
+
+ // Build LLVM for our target. This will implicitly build the host LLVM
+ // if necessary.
+ builder.ensure(native::Llvm { target });
+
+ if build.force_use_stage1(compiler, target) {
+ builder.ensure(RustcTrans {
+ compiler: builder.compiler(1, build.build),
+ target,
+ });
+ return;
+ }
+
+ let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage));
+ println!("Building stage{} trans artifacts ({} -> {})",
+ compiler.stage, &compiler.host, target);
+
+ let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
+ cargo.arg("--manifest-path")
+ .arg(build.src.join("src/librustc_trans/Cargo.toml"))
+ .arg("--features").arg(build.rustc_features());
+ rustc_cargo_env(build, &mut cargo);
+
+ // Pass down configuration from the LLVM build into the build of
+ // librustc_llvm and librustc_trans.
+ if build.is_rust_llvm(target) {
+ cargo.env("LLVM_RUSTLLVM", "1");
+ }
+ cargo.env("LLVM_CONFIG", build.llvm_config(target));
+ let target_config = build.config.target_config.get(&target);
+ if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
+ cargo.env("CFG_LLVM_ROOT", s);
+ }
+ // Building with a static libstdc++ is only supported on linux right now,
+ // not for MSVC or macOS
+ if build.config.llvm_static_stdcpp &&
+ !target.contains("freebsd") &&
+ !target.contains("windows") &&
+ !target.contains("apple") {
+ let file = compiler_file(build,
+ build.cxx(target).unwrap(),
+ target,
+ "libstdc++.a");
+ cargo.env("LLVM_STATIC_STDCPP", file);
+ }
+ if build.config.llvm_link_shared {
+ cargo.env("LLVM_LINK_SHARED", "1");
+ }
+
+ run_cargo(build,
+ &mut cargo,
+ &librustc_trans_stamp(build, compiler, target),
+ false);
+ }
+}
+
+/// Creates the `codegen-backends` folder for a compiler that's about to be
+/// assembled as a complete compiler.
+///
+/// This will take the codegen artifacts produced by `compiler` and link them
+/// into an appropriate location for `target_compiler` to be a functional
+/// compiler.
+fn copy_codegen_backends_to_sysroot(builder: &Builder,
+ compiler: Compiler,
+ target_compiler: Compiler) {
+ let build = builder.build;
+ let target = target_compiler.host;
+
+ // Note that this step is different than all the other `*Link` steps in
+ // that it's not assembling a bunch of libraries but rather is primarily
+ // moving the codegen backend into place. The codegen backend of rustc is
+ // not linked into the main compiler by default but is rather dynamically
+ // selected at runtime for inclusion.
+ //
+ // Here we're looking for the output dylib of the `RustcTrans` step and
+ // we're copying that into the `codegen-backends` folder.
+ let libdir = builder.sysroot_libdir(target_compiler, target);
+ let dst = libdir.join("codegen-backends");
+ t!(fs::create_dir_all(&dst));
+ let stamp = librustc_trans_stamp(build, compiler, target);
+
+ let mut copied = None;
+ for file in read_stamp_file(&stamp) {
+ let filename = match file.file_name().and_then(|s| s.to_str()) {
+ Some(s) => s,
+ None => continue,
+ };
+ if !is_dylib(filename) || !filename.contains("rustc_trans-") {
+ continue
+ }
+ match copied {
+ None => copied = Some(file.clone()),
+ Some(ref s) => {
+ panic!("copied two codegen backends:\n{}\n{}",
+ s.display(),
+ file.display());
+ }
+ }
+ copy(&file, &dst.join(filename));
+ }
+ assert!(copied.is_some(), "failed to find a codegen backend to copy");
+}
+
/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
pub fn libstd_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
@@ -619,9 +729,20 @@ pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc.stamp")
}
-fn compiler_file(compiler: &Path, file: &str) -> PathBuf {
- let out = output(Command::new(compiler)
- .arg(format!("-print-file-name={}", file)));
+pub fn librustc_trans_stamp(build: &Build,
+ compiler: Compiler,
+ target: Interned<String>) -> PathBuf {
+ build.cargo_out(compiler, Mode::Librustc, target).join(".librustc_trans.stamp")
+}
+
+fn compiler_file(build: &Build,
+ compiler: &Path,
+ target: Interned<String>,
+ file: &str) -> PathBuf {
+ let mut cmd = Command::new(compiler);
+ cmd.args(build.cflags(target));
+ cmd.arg(format!("-print-file-name={}", file));
+ let out = output(&mut cmd);
PathBuf::from(out.trim())
}
@@ -690,20 +811,23 @@ impl Step for Assemble {
}
// Get the compiler that we'll use to bootstrap ourselves.
- let build_compiler = if target_compiler.host != build.build {
- // Build a compiler for the host platform. We cannot use the stage0
- // compiler for the host platform for this because it doesn't have
- // the libraries we need. FIXME: Perhaps we should download those
- // libraries? It would make builds faster...
- // FIXME: It may be faster if we build just a stage 1
- // compiler and then use that to bootstrap this compiler
- // forward.
- builder.compiler(target_compiler.stage - 1, build.build)
- } else {
- // Build the compiler we'll use to build the stage requested. This
- // may build more than one compiler (going down to stage 0).
- builder.compiler(target_compiler.stage - 1, target_compiler.host)
- };
+ //
+ // Note that this is where the recursive nature of the bootstrap
+ // happens, as this will request the previous stage's compiler on
+ // downwards to stage 0.
+ //
+ // Also note that we're building a compiler for the host platform. We
+ // only assume that we can run `build` artifacts, which means that to
+ // produce some other architecture compiler we need to start from
+ // `build` to get there.
+ //
+ // FIXME: Perhaps we should download those libraries?
+ // It would make builds faster...
+ //
+ // FIXME: It may be faster if we build just a stage 1 compiler and then
+ // use that to bootstrap this compiler forward.
+ let build_compiler =
+ builder.compiler(target_compiler.stage - 1, build.build);
// Build the libraries for this compiler to link to (i.e., the libraries
// it uses at runtime). NOTE: Crates the target compiler compiles don't
@@ -721,7 +845,14 @@ impl Step for Assemble {
builder.ensure(RustcLink { compiler, target_compiler, target });
}
} else {
- builder.ensure(Rustc { compiler: build_compiler, target: target_compiler.host });
+ builder.ensure(Rustc {
+ compiler: build_compiler,
+ target: target_compiler.host,
+ });
+ builder.ensure(RustcTrans {
+ compiler: build_compiler,
+ target: target_compiler.host,
+ });
}
let stage = target_compiler.stage;
@@ -740,9 +871,12 @@ impl Step for Assemble {
}
}
- let out_dir = build.cargo_out(build_compiler, Mode::Librustc, host);
+ copy_codegen_backends_to_sysroot(builder,
+ build_compiler,
+ target_compiler);
// Link the compiler binary itself into place
+ let out_dir = build.cargo_out(build_compiler, Mode::Librustc, host);
let rustc = out_dir.join(exe("rustc", &*host));
let bindir = sysroot.join("bin");
t!(fs::create_dir_all(&bindir));
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 224b31ef268..4127239dc49 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -434,6 +434,15 @@ impl Step for Rustc {
}
}
+ // Copy over the codegen backends
+ let backends_src = builder.sysroot_libdir(compiler, host)
+ .join("codegen-backends");
+ let backends_dst = image.join("lib/rustlib")
+ .join(&*host)
+ .join("lib/codegen-backends");
+ t!(fs::create_dir_all(&backends_dst));
+ cp_r(&backends_src, &backends_dst);
+
// Man pages
t!(fs::create_dir_all(image.join("share/man/man1")));
let man_src = build.src.join("src/doc/man");
@@ -581,7 +590,9 @@ impl Step for Std {
t!(fs::create_dir_all(&dst));
let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
- cp_r(&src, &dst);
+ cp_filtered(&src, &dst, &|path| {
+ path.file_name().and_then(|s| s.to_str()) != Some("codegen-backends")
+ });
let mut cmd = rust_installer(builder);
cmd.arg("generate")
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 9bf762a3b4b..6a75fc5112f 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -617,7 +617,7 @@ impl Step for Rustc {
t!(symlink_dir_force(&my_out, &out_dir));
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
- compile::rustc_cargo(build, target, &mut cargo);
+ compile::rustc_cargo(build, &mut cargo);
if build.config.compiler_docs {
// src/rustc/Cargo.toml contains a bin crate called rustc which
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index a6a5ba67723..8928bef9faa 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -432,9 +432,6 @@ impl Build {
if self.config.use_jemalloc {
features.push_str(" jemalloc");
}
- if self.config.llvm_enabled {
- features.push_str(" llvm");
- }
features
}
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index ba8cf3a8e2e..442098a7afa 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -57,11 +57,6 @@ impl Step for Llvm {
let build = builder.build;
let target = self.target;
- // If we're not compiling for LLVM bail out here.
- if !build.config.llvm_enabled {
- return;
- }
-
// If we're using a custom LLVM bail out here, but we can only use a
// custom LLVM for the build triple.
if let Some(config) = build.config.target_config.get(&target) {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 5faec279438..a316b0f7ef9 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -900,6 +900,8 @@ impl Step for Compiletest {
cmd.env("PROFILER_SUPPORT", "1");
}
+ cmd.env("RUST_TEST_TMPDIR", build.out.join("tmp"));
+
cmd.arg("--adb-path").arg("adb");
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
if target.contains("android") {
@@ -1209,7 +1211,7 @@ impl Step for Crate {
}
Mode::Librustc => {
builder.ensure(compile::Rustc { compiler, target });
- compile::rustc_cargo(build, target, &mut cargo);
+ compile::rustc_cargo(build, &mut cargo);
("librustc", "rustc-main")
}
_ => panic!("can only test libraries"),
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index f95dbcf411c..2c4898cb2c0 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -14,7 +14,7 @@ bitflags = "1.0"
fmt_macros = { path = "../libfmt_macros" }
graphviz = { path = "../libgraphviz" }
jobserver = "0.1"
-log = "0.4"
+log = { version = "0.4", features = ["release_max_level_info", "std"] }
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_back = { path = "../librustc_back" }
rustc_const_math = { path = "../librustc_const_math" }
@@ -26,7 +26,6 @@ syntax_pos = { path = "../libsyntax_pos" }
backtrace = "0.3.3"
byteorder = { version = "1.1", features = ["i128"]}
-
# Note that these dependencies are a lie, they're just here to get linkage to
# work.
#
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index 4f7bbd79275..18493b8bb39 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -11,7 +11,7 @@ crate-type = ["dylib"]
[dependencies]
arena = { path = "../libarena" }
graphviz = { path = "../libgraphviz" }
-log = { version = "0.4", features = ["release_max_level_info"] }
+log = "0.4"
env_logger = { version = "0.4", default-features = false }
rustc = { path = "../librustc" }
rustc_allocator = { path = "../librustc_allocator" }
@@ -29,7 +29,6 @@ rustc_plugin = { path = "../librustc_plugin" }
rustc_privacy = { path = "../librustc_privacy" }
rustc_resolve = { path = "../librustc_resolve" }
rustc_save_analysis = { path = "../librustc_save_analysis" }
-rustc_trans = { path = "../librustc_trans", optional = true }
rustc_trans_utils = { path = "../librustc_trans_utils" }
rustc_typeck = { path = "../librustc_typeck" }
serialize = { path = "../libserialize" }
@@ -38,6 +37,3 @@ syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }
ar = "0.3.0"
-
-[features]
-llvm = ["rustc_trans"]
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index cdb50a0ae48..029cceda532 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -47,8 +47,6 @@ extern crate rustc_metadata;
extern crate rustc_mir;
extern crate rustc_resolve;
extern crate rustc_save_analysis;
-#[cfg(feature="llvm")]
-pub extern crate rustc_trans;
extern crate rustc_trans_utils;
extern crate rustc_typeck;
extern crate serialize;
@@ -68,30 +66,36 @@ use rustc::session::{self, config, Session, build_session, CompileResult};
use rustc::session::CompileIncomplete;
use rustc::session::config::{Input, PrintRequest, ErrorOutputType};
use rustc::session::config::nightly_options;
+use rustc::session::filesearch;
use rustc::session::{early_error, early_warn};
use rustc::lint::Lint;
use rustc::lint;
use rustc::middle::cstore::CrateStore;
use rustc_metadata::locator;
use rustc_metadata::cstore::CStore;
+use rustc_metadata::dynamic_lib::DynamicLibrary;
use rustc::util::common::{time, ErrorReported};
use rustc_trans_utils::trans_crate::TransCrate;
use serialize::json::ToJson;
use std::any::Any;
-use std::cmp::max;
use std::cmp::Ordering::Equal;
+use std::cmp::max;
use std::default::Default;
+use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::env;
use std::ffi::OsString;
use std::io::{self, Read, Write};
use std::iter::repeat;
+use std::mem;
use std::panic;
-use std::path::PathBuf;
+use std::path::{PathBuf, Path};
use std::process::{self, Command, Stdio};
use std::rc::Rc;
use std::str;
+use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
+use std::sync::{Once, ONCE_INIT};
use std::thread;
use syntax::ast;
@@ -176,57 +180,247 @@ pub fn run<F>(run_compiler: F) -> isize
0
}
-#[cfg(not(feature="llvm"))]
-pub use rustc_trans_utils::trans_crate::MetadataOnlyTransCrate as DefaultTransCrate;
-#[cfg(feature="llvm")]
-pub use rustc_trans::LlvmTransCrate as DefaultTransCrate;
+fn load_backend_from_dylib(path: &Path) -> fn() -> Box<TransCrate> {
+ // Note that we're specifically using `open_global_now` here rather than
+ // `open`, namely we want the behavior on Unix of RTLD_GLOBAL and RTLD_NOW,
+ // where NOW means "bind everything right now" because we don't want
+ // surprises later on and RTLD_GLOBAL allows the symbols to be made
+ // available for future dynamic libraries opened. This is currently used by
+ // loading LLVM and then making its symbols available for other dynamic
+ // libraries.
+ let lib = match DynamicLibrary::open_global_now(path) {
+ Ok(lib) => lib,
+ Err(err) => {
+ let err = format!("couldn't load codegen backend {:?}: {:?}",
+ path,
+ err);
+ early_error(ErrorOutputType::default(), &err);
+ }
+ };
+ unsafe {
+ match lib.symbol("__rustc_codegen_backend") {
+ Ok(f) => {
+ mem::forget(lib);
+ mem::transmute::<*mut u8, _>(f)
+ }
+ Err(e) => {
+ let err = format!("couldn't load codegen backend as it \
+ doesn't export the `__rustc_codegen_backend` \
+ symbol: {:?}", e);
+ early_error(ErrorOutputType::default(), &err);
+ }
+ }
+ }
+}
-#[cfg(not(feature="llvm"))]
-pub mod rustc_trans {
- pub use rustc_trans_utils::trans_crate::MetadataOnlyTransCrate as LlvmTransCrate;
+pub fn get_trans(sess: &Session) -> Box<TransCrate> {
+ static INIT: Once = ONCE_INIT;
+ static mut LOAD: fn() -> Box<TransCrate> = || unreachable!();
+
+ INIT.call_once(|| {
+ let trans_name = sess.opts.debugging_opts.codegen_backend.as_ref();
+ let backend = match trans_name.map(|s| &**s) {
+ None |
+ Some("llvm") => get_trans_default(),
+ Some("metadata_only") => {
+ rustc_trans_utils::trans_crate::MetadataOnlyTransCrate::new
+ }
+ Some(filename) if filename.contains(".") => {
+ load_backend_from_dylib(filename.as_ref())
+ }
+ Some(trans_name) => {
+ sess.fatal(&format!("unknown codegen backend {}", trans_name));
+ }
+ };
- pub fn print_version() {}
- pub fn print_passes() {}
+ unsafe {
+ LOAD = backend;
+ }
+ });
+ let backend = unsafe { LOAD() };
+ backend.init(sess);
+ backend
}
-fn load_backend_from_dylib(sess: &Session, backend_name: &str) -> Box<TransCrate> {
- use std::path::Path;
- use rustc_metadata::dynamic_lib::DynamicLibrary;
-
- match DynamicLibrary::open(Some(Path::new(backend_name))) {
- Ok(lib) => {
- unsafe {
- let trans = {
- let __rustc_codegen_backend: unsafe fn(&Session) -> Box<TransCrate>;
- __rustc_codegen_backend = match lib.symbol("__rustc_codegen_backend") {
- Ok(f) => ::std::mem::transmute::<*mut u8, _>(f),
- Err(e) => sess.fatal(&format!("Couldnt load codegen backend as it\
- doesn't export the __rustc_backend_new symbol: {:?}", e)),
- };
- __rustc_codegen_backend(sess)
- };
- ::std::mem::forget(lib);
- trans
+fn get_trans_default() -> fn() -> Box<TransCrate> {
+ // For now we only allow this function to be called once as it'll dlopen a
+ // few things, which seems to work best if we only do that once. In
+ // general this assertion never trips due to the once guard in `get_trans`,
+ // but there's a few manual calls to this function in this file we protect
+ // against.
+ static LOADED: AtomicBool = ATOMIC_BOOL_INIT;
+ assert!(!LOADED.fetch_or(true, Ordering::SeqCst),
+ "cannot load the default trans backend twice");
+
+ // When we're compiling this library with `--test` it'll run as a binary but
+ // not actually exercise much functionality. As a result most of the logic
+ // here is defunkt (it assumes we're a dynamic library in a sysroot) so
+ // let's just return a dummy creation function which won't be used in
+ // general anyway.
+ if cfg!(test) {
+ return rustc_trans_utils::trans_crate::MetadataOnlyTransCrate::new
+ }
+
+ let target = session::config::host_triple();
+ let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
+ let path = current_dll_path()
+ .and_then(|s| s.canonicalize().ok());
+ if let Some(dll) = path {
+ // use `parent` twice to chop off the file name and then also the
+ // directory containing the dll which should be either `lib` or `bin`.
+ if let Some(path) = dll.parent().and_then(|p| p.parent()) {
+ // The original `path` pointed at the `rustc_driver` crate's dll.
+ // Now that dll should only be in one of two locations. The first is
+ // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
+ // other is the target's libdir, for example
+ // `$sysroot/lib/rustlib/$target/lib/*.dll`.
+ //
+ // We don't know which, so let's assume that if our `path` above
+ // ends in `$target` we *could* be in the target libdir, and always
+ // assume that we may be in the main libdir.
+ sysroot_candidates.push(path.to_owned());
+
+ if path.ends_with(target) {
+ sysroot_candidates.extend(path.parent() // chop off `$target`
+ .and_then(|p| p.parent()) // chop off `rustlib`
+ .and_then(|p| p.parent()) // chop off `lib`
+ .map(|s| s.to_owned()));
}
}
- Err(err) => {
- sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", backend_name, err));
+ }
+
+ let sysroot = sysroot_candidates.iter()
+ .map(|sysroot| {
+ let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
+ sysroot.join(&libdir).join("codegen-backends")
+ })
+ .filter(|f| {
+ info!("codegen backend candidate: {}", f.display());
+ f.exists()
+ })
+ .next();
+ let sysroot = match sysroot {
+ Some(path) => path,
+ None => {
+ let candidates = sysroot_candidates.iter()
+ .map(|p| p.display().to_string())
+ .collect::<Vec<_>>()
+ .join("\n* ");
+ let err = format!("failed to find a `codegen-backends` folder \
+ in the sysroot candidates:\n* {}", candidates);
+ early_error(ErrorOutputType::default(), &err);
+ }
+ };
+ info!("probing {} for a codegen backend", sysroot.display());
+
+ let d = match sysroot.read_dir() {
+ Ok(d) => d,
+ Err(e) => {
+ let err = format!("failed to load default codegen backend, couldn't \
+ read `{}`: {}", sysroot.display(), e);
+ early_error(ErrorOutputType::default(), &err);
}
+ };
+
+ let mut file: Option<PathBuf> = None;
+
+ for entry in d.filter_map(|e| e.ok()) {
+ let path = entry.path();
+ let filename = match path.file_name().and_then(|s| s.to_str()) {
+ Some(s) => s,
+ None => continue,
+ };
+ if !(filename.starts_with(DLL_PREFIX) && filename.ends_with(DLL_SUFFIX)) {
+ continue
+ }
+ let name = &filename[DLL_PREFIX.len() .. filename.len() - DLL_SUFFIX.len()];
+ if !name.starts_with("rustc_trans") {
+ continue
+ }
+ if let Some(ref prev) = file {
+ let err = format!("duplicate codegen backends found\n\
+ first: {}\n\
+ second: {}\n\
+ ", prev.display(), path.display());
+ early_error(ErrorOutputType::default(), &err);
+ }
+ file = Some(path.clone());
}
-}
-pub fn get_trans(sess: &Session) -> Box<TransCrate> {
- let trans_name = sess.opts.debugging_opts.codegen_backend.clone();
- match trans_name.as_ref().map(|s|&**s) {
- None => DefaultTransCrate::new(&sess),
- Some("llvm") => rustc_trans::LlvmTransCrate::new(&sess),
- Some("metadata_only") => {
- rustc_trans_utils::trans_crate::MetadataOnlyTransCrate::new(&sess)
+ match file {
+ Some(ref s) => return load_backend_from_dylib(s),
+ None => {
+ let err = format!("failed to load default codegen backend, no appropriate \
+ codegen dylib found in `{}`", sysroot.display());
+ early_error(ErrorOutputType::default(), &err);
}
- Some(filename) if filename.contains(".") => {
- load_backend_from_dylib(&sess, &filename)
+ }
+
+ #[cfg(unix)]
+ fn current_dll_path() -> Option<PathBuf> {
+ use std::ffi::{OsStr, CStr};
+ use std::os::unix::prelude::*;
+
+ unsafe {
+ let addr = current_dll_path as usize as *mut _;
+ let mut info = mem::zeroed();
+ if libc::dladdr(addr, &mut info) == 0 {
+ info!("dladdr failed");
+ return None
+ }
+ if info.dli_fname.is_null() {
+ info!("dladdr returned null pointer");
+ return None
+ }
+ let bytes = CStr::from_ptr(info.dli_fname).to_bytes();
+ let os = OsStr::from_bytes(bytes);
+ Some(PathBuf::from(os))
+ }
+ }
+
+ #[cfg(windows)]
+ fn current_dll_path() -> Option<PathBuf> {
+ use std::ffi::OsString;
+ use std::os::windows::prelude::*;
+
+ extern "system" {
+ fn GetModuleHandleExW(dwFlags: u32,
+ lpModuleName: usize,
+ phModule: *mut usize) -> i32;
+ fn GetModuleFileNameW(hModule: usize,
+ lpFilename: *mut u16,
+ nSize: u32) -> u32;
+ }
+
+ const GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS: u32 = 0x00000004;
+
+ unsafe {
+ let mut module = 0;
+ let r = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ current_dll_path as usize,
+ &mut module);
+ if r == 0 {
+ info!("GetModuleHandleExW failed: {}", io::Error::last_os_error());
+ return None
+ }
+ let mut space = Vec::with_capacity(1024);
+ let r = GetModuleFileNameW(module,
+ space.as_mut_ptr(),
+ space.capacity() as u32);
+ if r == 0 {
+ info!("GetModuleFileNameW failed: {}", io::Error::last_os_error());
+ return None
+ }
+ let r = r as usize;
+ if r >= space.capacity() {
+ info!("our buffer was too small? {}",
+ io::Error::last_os_error());
+ return None
+ }
+ space.set_len(r);
+ let os = OsString::from_wide(&space);
+ Some(PathBuf::from(os))
}
- Some(trans_name) => sess.fatal(&format!("Unknown codegen backend {}", trans_name)),
}
}
@@ -878,7 +1072,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) {
println!("commit-date: {}", unw(commit_date_str()));
println!("host: {}", config::host_triple());
println!("release: {}", unw(release_str()));
- rustc_trans::print_version();
+ get_trans_default()().print_version();
}
}
@@ -1175,7 +1369,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
}
if cg_flags.contains(&"passes=list".to_string()) {
- rustc_trans::print_passes();
+ get_trans_default()().print_passes();
return None;
}
@@ -1284,8 +1478,8 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
all_errors.extend_from_slice(&rustc_typeck::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_resolve::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS);
- #[cfg(feature="llvm")]
- all_errors.extend_from_slice(&rustc_trans::DIAGNOSTICS);
+ // FIXME: need to figure out a way to get these back in here
+ // all_errors.extend_from_slice(get_trans(sess).diagnostics());
all_errors.extend_from_slice(&rustc_trans_utils::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_const_eval::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS);
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 68f4b17a6a3..4ae6a93d698 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -228,7 +228,8 @@ impl PpSourceMode {
}
PpmTyped => {
let control = &driver::CompileController::basic();
- abort_on_err(driver::phase_3_run_analysis_passes(&*::DefaultTransCrate::new(&sess),
+ let trans = ::get_trans(sess);
+ abort_on_err(driver::phase_3_run_analysis_passes(&*trans,
control,
sess,
cstore,
@@ -1081,7 +1082,8 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
let mut out = Vec::new();
let control = &driver::CompileController::basic();
- abort_on_err(driver::phase_3_run_analysis_passes(&*::DefaultTransCrate::new(&sess),
+ let trans = ::get_trans(sess);
+ abort_on_err(driver::phase_3_run_analysis_passes(&*trans,
control,
sess,
cstore,
diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml
index a9566c4bcac..45e97127ede 100644
--- a/src/librustc_llvm/Cargo.toml
+++ b/src/librustc_llvm/Cargo.toml
@@ -7,13 +7,13 @@ build = "build.rs"
[lib]
name = "rustc_llvm"
path = "lib.rs"
-crate-type = ["dylib"]
[features]
static-libstdcpp = []
[dependencies]
bitflags = "1.0"
+libc = "0.2"
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
[build-dependencies]
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index 91dc3210e11..49b93f3c7d6 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -146,6 +146,7 @@ fn main() {
cfg.define(&flag, None);
}
+ println!("cargo:rerun-if-changed-env=LLVM_RUSTLLVM");
if env::var_os("LLVM_RUSTLLVM").is_some() {
cfg.define("LLVM_RUSTLLVM", None);
}
diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs
index 1b42fa03a4f..d7da0d00012 100644
--- a/src/librustc_metadata/dynamic_lib.rs
+++ b/src/librustc_metadata/dynamic_lib.rs
@@ -38,7 +38,17 @@ impl DynamicLibrary {
// run.
match maybe_library {
Err(err) => Err(err),
- Ok(handle) => Ok(DynamicLibrary { handle: handle })
+ Ok(handle) => Ok(DynamicLibrary { handle })
+ }
+ }
+
+ /// Load a dynamic library into the global namespace (RTLD_GLOBAL on Unix)
+ /// and do it now (don't use RTLD_LAZY on Unix).
+ pub fn open_global_now(filename: &Path) -> Result<DynamicLibrary, String> {
+ let maybe_library = dl::open_global_now(filename.as_os_str());
+ match maybe_library {
+ Err(err) => Err(err),
+ Ok(handle) => Ok(DynamicLibrary { handle })
}
}
@@ -145,15 +155,20 @@ mod dl {
})
}
- const LAZY: libc::c_int = 1;
+ pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
+ check_for_errors_in(|| unsafe {
+ let s = CString::new(filename.as_bytes()).unwrap();
+ libc::dlopen(s.as_ptr(), libc::RTLD_GLOBAL | libc::RTLD_NOW) as *mut u8
+ })
+ }
unsafe fn open_external(filename: &OsStr) -> *mut u8 {
let s = CString::new(filename.as_bytes()).unwrap();
- libc::dlopen(s.as_ptr(), LAZY) as *mut u8
+ libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
}
unsafe fn open_internal() -> *mut u8 {
- libc::dlopen(ptr::null(), LAZY) as *mut u8
+ libc::dlopen(ptr::null(), libc::RTLD_LAZY) as *mut u8
}
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
@@ -224,6 +239,10 @@ mod dl {
fn FreeLibrary(handle: HMODULE) -> BOOL;
}
+ pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
+ open(Some(filename))
+ }
+
pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
// disable "dll load failed" error dialog.
let prev_error_mode = unsafe {
diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml
index 79dd57b37f4..14591de31ca 100644
--- a/src/librustc_trans/Cargo.toml
+++ b/src/librustc_trans/Cargo.toml
@@ -13,6 +13,7 @@ test = false
bitflags = "1.0"
flate2 = "1.0"
jobserver = "0.1.5"
+libc = "0.2"
log = "0.4"
num_cpus = "1.0"
rustc = { path = "../librustc" }
@@ -36,3 +37,6 @@ tempdir = "0.3"
[target."cfg(windows)".dependencies]
cc = "1.0.1"
+
+[features]
+jemalloc = ["rustc_back/jemalloc"]
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index b67997081aa..908d3790170 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -69,7 +69,7 @@ extern crate tempdir;
use back::bytecode::RLIB_BYTECODE_EXTENSION;
-pub use llvm_util::{target_features, print_version, print_passes};
+pub use llvm_util::target_features;
use std::any::Any;
use std::path::PathBuf;
@@ -149,13 +149,16 @@ impl !Send for LlvmTransCrate {} // Llvm is on a per-thread basis
impl !Sync for LlvmTransCrate {}
impl LlvmTransCrate {
- pub fn new(sess: &Session) -> Box<TransCrate> {
- llvm_util::init(sess); // Make sure llvm is inited
+ pub fn new() -> Box<TransCrate> {
box LlvmTransCrate(())
}
}
impl TransCrate for LlvmTransCrate {
+ fn init(&self, sess: &Session) {
+ llvm_util::init(sess); // Make sure llvm is inited
+ }
+
fn print(&self, req: PrintRequest, sess: &Session) {
match req {
PrintRequest::RelocationModels => {
@@ -183,6 +186,19 @@ impl TransCrate for LlvmTransCrate {
}
}
+ fn print_passes(&self) {
+ llvm_util::print_passes();
+ }
+
+ fn print_version(&self) {
+ llvm_util::print_version();
+ }
+
+ #[cfg(not(stage0))]
+ fn diagnostics(&self) -> &[(&'static str, &'static str)] {
+ &DIAGNOSTICS
+ }
+
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
target_features(sess)
}
@@ -252,8 +268,8 @@ impl TransCrate for LlvmTransCrate {
/// This is the entrypoint for a hot plugged rustc_trans
#[no_mangle]
-pub fn __rustc_codegen_backend(sess: &Session) -> Box<TransCrate> {
- LlvmTransCrate::new(sess)
+pub fn __rustc_codegen_backend() -> Box<TransCrate> {
+ LlvmTransCrate::new()
}
struct ModuleTranslation {
diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs
index 49756d754fe..e14abdff339 100644
--- a/src/librustc_trans_utils/trans_crate.rs
+++ b/src/librustc_trans_utils/trans_crate.rs
@@ -48,8 +48,12 @@ use rustc_mir::monomorphize::collector;
use link::{build_link_meta, out_filename};
pub trait TransCrate {
+ fn init(&self, _sess: &Session) {}
fn print(&self, _req: PrintRequest, _sess: &Session) {}
fn target_features(&self, _sess: &Session) -> Vec<Symbol> { vec![] }
+ fn print_passes(&self) {}
+ fn print_version(&self) {}
+ fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
fn metadata_loader(&self) -> Box<MetadataLoader>;
fn provide(&self, _providers: &mut Providers);
@@ -168,7 +172,13 @@ pub struct OngoingCrateTranslation {
}
impl MetadataOnlyTransCrate {
- pub fn new(sess: &Session) -> Box<TransCrate> {
+ pub fn new() -> Box<TransCrate> {
+ box MetadataOnlyTransCrate(())
+ }
+}
+
+impl TransCrate for MetadataOnlyTransCrate {
+ fn init(&self, sess: &Session) {
for cty in sess.opts.crate_types.iter() {
match *cty {
CrateType::CrateTypeRlib | CrateType::CrateTypeDylib |
@@ -180,12 +190,8 @@ impl MetadataOnlyTransCrate {
},
}
}
-
- box MetadataOnlyTransCrate(())
}
-}
-impl TransCrate for MetadataOnlyTransCrate {
fn metadata_loader(&self) -> Box<MetadataLoader> {
box NoLlvmMetadataLoader
}
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 5fe4794389f..0674a0b5a3b 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -9,7 +9,7 @@
// except according to those terms.
use rustc_lint;
-use rustc_driver::{driver, target_features, abort_on_err};
+use rustc_driver::{self, driver, target_features, abort_on_err};
use rustc::session::{self, config};
use rustc::hir::def_id::DefId;
use rustc::hir::def::Def;
@@ -18,7 +18,6 @@ use rustc::ty::{self, TyCtxt, AllArenas};
use rustc::hir::map as hir_map;
use rustc::lint;
use rustc::util::nodemap::FxHashMap;
-use rustc_trans;
use rustc_resolve as resolve;
use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::CStore;
@@ -151,7 +150,7 @@ pub fn run_core(search_paths: SearchPaths,
let mut sess = session::build_session_(
sessopts, cpath, diagnostic_handler, codemap,
);
- let trans = rustc_trans::LlvmTransCrate::new(&sess);
+ let trans = rustc_driver::get_trans(&sess);
let cstore = Rc::new(CStore::new(trans.metadata_loader()));
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index ccd79e5b2c5..e39fe20310c 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -63,8 +63,6 @@ use std::path::{Path, PathBuf};
use std::process;
use std::sync::mpsc::channel;
-use rustc_driver::rustc_trans;
-
use externalfiles::ExternalHtml;
use rustc::session::search_paths::SearchPaths;
use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options,
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 10850f88f2d..d61b80c9aa0 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -33,7 +33,6 @@ use rustc_driver::{self, driver, Compilation};
use rustc_driver::driver::phase_2_configure_and_expand;
use rustc_metadata::cstore::CStore;
use rustc_resolve::MakeGlobMap;
-use rustc_trans;
use syntax::ast;
use syntax::codemap::CodeMap;
use syntax::feature_gate::UnstableFeatures;
@@ -84,7 +83,7 @@ pub fn run(input_path: &Path,
let mut sess = session::build_session_(
sessopts, Some(input_path.to_owned()), handler, codemap.clone(),
);
- let trans = rustc_trans::LlvmTransCrate::new(&sess);
+ let trans = rustc_driver::get_trans(&sess);
let cstore = Rc::new(CStore::new(trans.metadata_loader()));
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
sess.parse_sess.config =
@@ -249,7 +248,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
let mut sess = session::build_session_(
sessopts, None, diagnostic_handler, codemap,
);
- let trans = rustc_trans::LlvmTransCrate::new(&sess);
+ let trans = rustc_driver::get_trans(&sess);
let cstore = Rc::new(CStore::new(trans.metadata_loader()));
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml
index d185c061d5b..bbc4c2ee43e 100644
--- a/src/rustc/Cargo.toml
+++ b/src/rustc/Cargo.toml
@@ -7,12 +7,9 @@ version = "0.0.0"
name = "rustc"
path = "rustc.rs"
-# All optional dependencies so the features passed to this Cargo.toml select
-# what should actually be built.
[dependencies]
rustc_back = { path = "../librustc_back" }
rustc_driver = { path = "../librustc_driver" }
[features]
jemalloc = ["rustc_back/jemalloc"]
-llvm = ["rustc_driver/llvm"]
diff --git a/src/test/run-make/hotplug_codegen_backend/the_backend.rs b/src/test/run-make/hotplug_codegen_backend/the_backend.rs
index 0de404ed249..5972149590c 100644
--- a/src/test/run-make/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make/hotplug_codegen_backend/the_backend.rs
@@ -77,6 +77,6 @@ impl TransCrate for TheBackend {
/// This is the entrypoint for a hot plugged rustc_trans
#[no_mangle]
-pub fn __rustc_codegen_backend(sess: &Session) -> Box<TransCrate> {
- Box::new(TheBackend(MetadataOnlyTransCrate::new(sess)))
+pub fn __rustc_codegen_backend() -> Box<TransCrate> {
+ Box::new(TheBackend(MetadataOnlyTransCrate::new()))
}
diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs
index c360dde618e..b4b29e15ce1 100644
--- a/src/test/run-make/issue-19371/foo.rs
+++ b/src/test/run-make/issue-19371/foo.rs
@@ -15,7 +15,6 @@ extern crate rustc_driver;
extern crate rustc_lint;
extern crate rustc_metadata;
extern crate rustc_errors;
-extern crate rustc_trans;
extern crate rustc_trans_utils;
extern crate syntax;
@@ -63,7 +62,7 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>, Box<TransCrate>) {
let descriptions = Registry::new(&rustc::DIAGNOSTICS);
let sess = build_session(opts, None, descriptions);
- let trans = rustc_trans::LlvmTransCrate::new(&sess);
+ let trans = rustc_driver::get_trans(&sess);
let cstore = Rc::new(CStore::new(trans.metadata_loader()));
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
(sess, cstore, trans)
diff --git a/src/test/run-make/llvm-pass/Makefile b/src/test/run-make/llvm-pass/Makefile
index 0d31d2c8235..8a18aadf36a 100644
--- a/src/test/run-make/llvm-pass/Makefile
+++ b/src/test/run-make/llvm-pass/Makefile
@@ -1,5 +1,9 @@
-include ../tools.mk
+ifeq ($(UNAME),Darwin)
+PLUGIN_FLAGS := -C link-args=-Wl,-undefined,dynamic_lookup
+endif
+
ifeq ($(findstring stage1,$(RUST_BUILD_STAGE)),stage1)
# ignore stage1
all:
@@ -11,7 +15,7 @@ ifdef IS_WINDOWS
all:
else
all: $(call NATIVE_STATICLIB,llvm-function-pass) $(call NATIVE_STATICLIB,llvm-module-pass)
- $(RUSTC) plugin.rs -C prefer-dynamic
+ $(RUSTC) plugin.rs -C prefer-dynamic $(PLUGIN_FLAGS)
$(RUSTC) main.rs
$(TMPDIR)/libllvm-function-pass.o:
diff --git a/src/test/run-make/llvm-pass/plugin.rs b/src/test/run-make/llvm-pass/plugin.rs
index 37aab2bbd05..f77b2fca857 100644
--- a/src/test/run-make/llvm-pass/plugin.rs
+++ b/src/test/run-make/llvm-pass/plugin.rs
@@ -14,7 +14,6 @@
extern crate rustc;
extern crate rustc_plugin;
-extern crate rustc_trans;
#[link(name = "llvm-function-pass", kind = "static")]
#[link(name = "llvm-module-pass", kind = "static")]
diff --git a/src/test/run-pass-fulldeps/create-dir-all-bare.rs b/src/test/run-pass-fulldeps/create-dir-all-bare.rs
index ba42cb870c9..a35eed1f72d 100644
--- a/src/test/run-pass-fulldeps/create-dir-all-bare.rs
+++ b/src/test/run-pass-fulldeps/create-dir-all-bare.rs
@@ -8,18 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-cross-compile
-
-#![feature(rustc_private)]
-
-extern crate tempdir;
-
use std::env;
use std::fs;
-use tempdir::TempDir;
+use std::path::PathBuf;
fn main() {
- let td = TempDir::new("create-dir-all-bare").unwrap();
- env::set_current_dir(td.path()).unwrap();
+ let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ env::set_current_dir(&path).unwrap();
fs::create_dir_all("create-dir-all-bare").unwrap();
}
diff --git a/src/test/run-pass-fulldeps/issue-15149.rs b/src/test/run-pass-fulldeps/issue-15149.rs
index 121fd4a9825..15ac1d55cc8 100644
--- a/src/test/run-pass-fulldeps/issue-15149.rs
+++ b/src/test/run-pass-fulldeps/issue-15149.rs
@@ -11,15 +11,11 @@
// no-prefer-dynamic
// ignore-cross-compile
-#![feature(rustc_private)]
-
-extern crate tempdir;
-
use std::env;
use std::fs;
use std::process;
use std::str;
-use tempdir::TempDir;
+use std::path::PathBuf;
fn main() {
// If we're the child, make sure we were invoked correctly
@@ -41,8 +37,9 @@ fn test() {
let my_path = env::current_exe().unwrap();
let my_dir = my_path.parent().unwrap();
- let child_dir = TempDir::new_in(&my_dir, "issue-15140-child").unwrap();
- let child_dir = child_dir.path();
+ let child_dir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ let child_dir = child_dir.join("issue-15140-child");
+ fs::create_dir_all(&child_dir).unwrap();
let child_path = child_dir.join(&format!("mytest{}",
env::consts::EXE_SUFFIX));
@@ -63,11 +60,4 @@ fn test() {
format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}",
str::from_utf8(&child_output.stdout).unwrap(),
str::from_utf8(&child_output.stderr).unwrap()));
-
- let res = fs::remove_dir_all(&child_dir);
- if res.is_err() {
- // On Windows deleting just executed mytest.exe can fail because it's still locked
- std::thread::sleep_ms(1000);
- fs::remove_dir_all(&child_dir).unwrap();
- }
}
diff --git a/src/test/run-pass-fulldeps/rename-directory.rs b/src/test/run-pass-fulldeps/rename-directory.rs
index 7a2a4343522..417707e8932 100644
--- a/src/test/run-pass-fulldeps/rename-directory.rs
+++ b/src/test/run-pass-fulldeps/rename-directory.rs
@@ -13,17 +13,13 @@
// ignore-cross-compile
-#![feature(rustc_private)]
-
-extern crate tempdir;
-
+use std::env;
use std::ffi::CString;
use std::fs::{self, File};
-use tempdir::TempDir;
+use std::path::PathBuf;
fn rename_directory() {
- let tmpdir = TempDir::new("rename_directory").ok().expect("rename_directory failed");
- let tmpdir = tmpdir.path();
+ let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
let old_path = tmpdir.join("foo/bar/baz");
fs::create_dir_all(&old_path).unwrap();
let test_file = &old_path.join("temp.txt");
diff --git a/src/test/run-pass-fulldeps/stdio-from.rs b/src/test/run-pass-fulldeps/stdio-from.rs
index 535ab711f5b..5b28ce0f0c6 100644
--- a/src/test/run-pass-fulldeps/stdio-from.rs
+++ b/src/test/run-pass-fulldeps/stdio-from.rs
@@ -10,17 +10,12 @@
// ignore-cross-compile
-#![feature(rustc_private)]
-
-extern crate tempdir;
-
use std::env;
use std::fs::File;
use std::io;
use std::io::{Read, Write};
use std::process::{Command, Stdio};
-
-use tempdir::TempDir;
+use std::path::PathBuf;
fn main() {
if env::args().len() > 1 {
@@ -31,9 +26,9 @@ fn main() {
}
fn parent() -> io::Result<()> {
- let td = TempDir::new("foo").unwrap();
- let input = td.path().join("input");
- let output = td.path().join("output");
+ let td = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ let input = td.join("stdio-from-input");
+ let output = td.join("stdio-from-output");
File::create(&input)?.write_all(b"foo\n")?;
diff --git a/src/test/run-pass-fulldeps/switch-stdout.rs b/src/test/run-pass-fulldeps/switch-stdout.rs
index 16f7e283285..316b97f17ef 100644
--- a/src/test/run-pass-fulldeps/switch-stdout.rs
+++ b/src/test/run-pass-fulldeps/switch-stdout.rs
@@ -8,14 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(rustc_private)]
-
-extern crate tempdir;
-
+use std::env;
use std::fs::File;
use std::io::{Read, Write};
-
-use tempdir::TempDir;
+use std::path::PathBuf;
#[cfg(unix)]
fn switch_stdout_to(file: File) {
@@ -48,8 +44,8 @@ fn switch_stdout_to(file: File) {
}
fn main() {
- let td = TempDir::new("foo").unwrap();
- let path = td.path().join("bar");
+ let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
+ let path = path.join("switch-stdout-output");
let f = File::create(&path).unwrap();
println!("foo");
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 533aaf9cd27..b98a4248d81 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -667,9 +667,16 @@ fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> boo
for pretty_printer_file in &pretty_printer_files {
inputs.push(mtime(&rust_src_dir.join(pretty_printer_file)));
}
- for lib in config.run_lib_path.read_dir().unwrap() {
- let lib = lib.unwrap();
- inputs.push(mtime(&lib.path()));
+ let mut entries = config.run_lib_path.read_dir().unwrap()
+ .collect::<Vec<_>>();
+ while let Some(entry) = entries.pop() {
+ let entry = entry.unwrap();
+ let path = entry.path();
+ if entry.metadata().unwrap().is_file() {
+ inputs.push(mtime(&path));
+ } else {
+ entries.extend(path.read_dir().unwrap());
+ }
}
if let Some(ref rustdoc_path) = config.rustdoc_path {
inputs.push(mtime(&rustdoc_path));