-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
//! The Rust compiler.
//!
//! # Note
#![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#![feature(set_stdio)]
-#![feature(rustc_stack_internals)]
#![feature(no_debug)]
#![recursion_limit="256"]
}
let target = session::config::host_triple();
- let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
+ // get target libdir path based on executable binary path
+ let sysroot = filesearch::get_or_default_sysroot();
+ let mut libdir_candidates = vec![filesearch::make_target_lib_path(&sysroot, &target)];
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()) {
+ // use `parent` once to chop off the file name
+ if let Some(path) = dll.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
+ // in the compiler's libdir, for example `$sysroot/$libdir/*.dll`. The
// other is the target's libdir, for example
- // `$sysroot/lib/rustlib/$target/lib/*.dll`.
+ // `$sysroot/$libdir/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()));
+ // doesn't end in `$target` we *could* be in the main libdir, and always
+ // assume that we may be in the target libdir.
+ libdir_candidates.push(path.to_owned());
+
+ if !path.parent().map_or(false, |p| p.ends_with(target)) {
+ libdir_candidates.push(path.join(filesearch::target_lib_path(target)));
}
}
}
- let sysroot = sysroot_candidates.iter()
- .map(|sysroot| {
- let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
- sysroot.join(libdir).with_file_name(
+ let sysroot = libdir_candidates.iter()
+ .map(|libdir| {
+ debug!("Trying target libdir: {}", libdir.display());
+ libdir.with_file_name(
option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
})
.filter(|f| {
})
.next();
let sysroot = sysroot.unwrap_or_else(|| {
- let candidates = sysroot_candidates.iter()
+ let candidates = libdir_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);
+ in the libdir candidates:\n* {}", candidates);
early_error(ErrorOutputType::default(), &err);
});
info!("probing {} for a codegen backend", sysroot.display());
&state.expanded_crate.take().unwrap(),
state.crate_name.unwrap(),
ppm,
- state.arenas.unwrap(),
state.output_filenames.unwrap(),
opt_uii.clone(),
state.out_file);
where F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
- #[cfg(all(unix, not(target_os = "haiku")))]
- let spawn_thread = unsafe {
- // Fetch the current resource limits
- let mut rlim = libc::rlimit {
- rlim_cur: 0,
- rlim_max: 0,
- };
- if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
- let err = io::Error::last_os_error();
- error!("in_rustc_thread: error calling getrlimit: {}", err);
- true
- } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t {
- true
- } else if rlim.rlim_cur < STACK_SIZE as libc::rlim_t {
- std::rt::deinit_stack_guard();
- rlim.rlim_cur = STACK_SIZE as libc::rlim_t;
- if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
- let err = io::Error::last_os_error();
- error!("in_rustc_thread: error calling setrlimit: {}", err);
- std::rt::update_stack_guard();
- true
- } else {
- std::rt::update_stack_guard();
- false
- }
- } else {
- false
- }
- };
-
- // We set the stack size at link time. See src/rustc/rustc.rs.
- #[cfg(windows)]
- let spawn_thread = false;
-
- #[cfg(target_os = "haiku")]
- let spawn_thread = unsafe {
- // Haiku does not have setrlimit implemented for the stack size.
- // By default it does have the 16 MB stack limit, but we check this in
- // case the minimum STACK_SIZE changes or Haiku's defaults change.
- let mut rlim = libc::rlimit {
- rlim_cur: 0,
- rlim_max: 0,
- };
- if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
- let err = io::Error::last_os_error();
- error!("in_rustc_thread: error calling getrlimit: {}", err);
- true
- } else if rlim.rlim_cur >= STACK_SIZE {
- false
- } else {
- true
- }
- };
-
- #[cfg(not(any(windows, unix)))]
- let spawn_thread = true;
-
- // The or condition is added from backward compatibility.
- if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() {
+ // We need a thread for soundness of thread local storage in rustc. For debugging purposes
+ // we allow an escape hatch where everything runs on the main thread.
+ if env::var_os("RUSTC_UNSTABLE_NO_MAIN_THREAD").is_none() {
let mut cfg = thread::Builder::new().name(name);
- // FIXME: Hacks on hacks. If the env is trying to override the stack size
- // then *don't* set it explicitly.
+ // If the env is trying to override the stack size then *don't* set it explicitly.
+ // The libstd thread impl will fetch the `RUST_MIN_STACK` env var itself.
if env::var_os("RUST_MIN_STACK").is_none() {
cfg = cfg.stack_size(STACK_SIZE);
}