use serde::Deserialize;
use crate::builder::Cargo;
+use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
+use crate::cache::{Interned, INTERNER};
use crate::dist;
use crate::native;
+use crate::tool::SourceType;
use crate::util::{exe, is_dylib, symlink_dir};
-use crate::{Compiler, GitRepo, Mode};
-
-use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
-use crate::cache::{Interned, INTERNER};
+use crate::{Compiler, DependencyType, GitRepo, Mode};
#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Std {
// Even if we're not building std this stage, the new sysroot must
// still contain the third party objects needed by various targets.
copy_third_party_objects(builder, &compiler, target);
+ copy_self_contained_objects(builder, &compiler, target);
builder.ensure(StdLink {
compiler: compiler_to_use,
return;
}
- target_deps.extend(copy_third_party_objects(builder, &compiler, target).into_iter());
+ target_deps.extend(copy_third_party_objects(builder, &compiler, target));
+ target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
- let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
+ let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
std_cargo(builder, target, compiler.stage, &mut cargo);
builder.info(&format!(
}
}
+fn copy_and_stamp(
+ builder: &Builder<'_>,
+ libdir: &Path,
+ sourcedir: &Path,
+ name: &str,
+ target_deps: &mut Vec<(PathBuf, DependencyType)>,
+ dependency_type: DependencyType,
+) {
+ let target = libdir.join(name);
+ builder.copy(&sourcedir.join(name), &target);
+
+ target_deps.push((target, dependency_type));
+}
+
/// Copies third party objects needed by various targets.
fn copy_third_party_objects(
builder: &Builder<'_>,
compiler: &Compiler,
target: Interned<String>,
-) -> Vec<PathBuf> {
+) -> Vec<(PathBuf, DependencyType)> {
let libdir = builder.sysroot_libdir(*compiler, target);
-
let mut target_deps = vec![];
- let mut copy_and_stamp = |sourcedir: &Path, name: &str| {
- let target = libdir.join(name);
- builder.copy(&sourcedir.join(name), &target);
- target_deps.push(target);
+ // Copies libunwind.a compiled to be linked with x86_64-fortanix-unknown-sgx.
+ //
+ // This target needs to be linked to Fortanix's port of llvm's libunwind.
+ // libunwind requires support for rwlock and printing to stderr,
+ // which is provided by std for this target.
+ if target == "x86_64-fortanix-unknown-sgx" {
+ let src_path_env = "X86_FORTANIX_SGX_LIBS";
+ let src =
+ env::var(src_path_env).unwrap_or_else(|_| panic!("{} not found in env", src_path_env));
+ copy_and_stamp(
+ builder,
+ &*libdir,
+ Path::new(&src),
+ "libunwind.a",
+ &mut target_deps,
+ DependencyType::Target,
+ );
+ }
+
+ if builder.config.sanitizers && compiler.stage != 0 {
+ // The sanitizers are only copied in stage1 or above,
+ // to avoid creating dependency on LLVM.
+ target_deps.extend(
+ copy_sanitizers(builder, &compiler, target)
+ .into_iter()
+ .map(|d| (d, DependencyType::Target)),
+ );
+ }
+
+ target_deps
+}
+
+/// Copies third party objects needed by various targets for self-contained linkage.
+fn copy_self_contained_objects(
+ builder: &Builder<'_>,
+ compiler: &Compiler,
+ target: Interned<String>,
+) -> Vec<(PathBuf, DependencyType)> {
+ // cfg(bootstrap)
+ // Remove when upgrading bootstrap compiler.
+ let libdir_self_contained = if compiler.stage == 0 {
+ builder.sysroot_libdir(*compiler, target).to_path_buf()
+ } else {
+ builder.sysroot_libdir(*compiler, target).join("self-contained")
};
+ t!(fs::create_dir_all(&libdir_self_contained));
+ let mut target_deps = vec![];
// Copies the CRT objects.
//
if target.contains("musl") {
let srcdir = builder.musl_root(target).unwrap().join("lib");
for &obj in &["crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] {
- copy_and_stamp(&srcdir, obj);
+ copy_and_stamp(
+ builder,
+ &libdir_self_contained,
+ &srcdir,
+ obj,
+ &mut target_deps,
+ DependencyType::TargetSelfContained,
+ );
}
} else if target.ends_with("-wasi") {
let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
- copy_and_stamp(&srcdir, "crt1.o");
- }
-
- // Copies libunwind.a compiled to be linked with x86_64-fortanix-unknown-sgx.
- //
- // This target needs to be linked to Fortanix's port of llvm's libunwind.
- // libunwind requires support for rwlock and printing to stderr,
- // which is provided by std for this target.
- if target == "x86_64-fortanix-unknown-sgx" {
- let src_path_env = "X86_FORTANIX_SGX_LIBS";
- let src =
- env::var(src_path_env).unwrap_or_else(|_| panic!("{} not found in env", src_path_env));
- copy_and_stamp(Path::new(&src), "libunwind.a");
- }
-
- if builder.config.sanitizers && compiler.stage != 0 {
- // The sanitizers are only copied in stage1 or above,
- // to avoid creating dependency on LLVM.
- target_deps.extend(copy_sanitizers(builder, &compiler, target));
+ copy_and_stamp(
+ builder,
+ &libdir_self_contained,
+ &srcdir,
+ "crt1.o",
+ &mut target_deps,
+ DependencyType::TargetSelfContained,
+ );
+ } else if target.contains("windows-gnu") {
+ for obj in ["crt2.o", "dllcrt2.o"].iter() {
+ let src = compiler_file(builder, builder.cc(target), target, obj);
+ let target = libdir_self_contained.join(obj);
+ builder.copy(&src, &target);
+ target_deps.push((target, DependencyType::TargetSelfContained));
+ }
}
target_deps
}
impl Step for StartupObjects {
- type Output = Vec<PathBuf>;
+ type Output = Vec<(PathBuf, DependencyType)>;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/rtstartup")
/// They don't require any library support as they're just plain old object
/// files, so we just use the nightly snapshot compiler to always build them (as
/// no other compilers are guaranteed to be available).
- fn run(self, builder: &Builder<'_>) -> Vec<PathBuf> {
+ fn run(self, builder: &Builder<'_>) -> Vec<(PathBuf, DependencyType)> {
let for_compiler = self.compiler;
let target = self.target;
if !target.contains("windows-gnu") {
let target = sysroot_dir.join((*file).to_string() + ".o");
builder.copy(dst_file, &target);
- target_deps.push(target);
- }
-
- for obj in ["crt2.o", "dllcrt2.o"].iter() {
- let src = compiler_file(builder, builder.cc(target), target, obj);
- let target = sysroot_dir.join(obj);
- builder.copy(&src, &target);
- target_deps.push(target);
+ target_deps.push((target, DependencyType::Target));
}
target_deps
target: builder.config.build,
});
- let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build");
+ let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build");
rustc_cargo(builder, &mut cargo, target);
builder.info(&format!(
sysroot_host_dst: &Path,
stamp: &Path,
) {
+ let self_contained_dst = &sysroot_dst.join("self-contained");
t!(fs::create_dir_all(&sysroot_dst));
t!(fs::create_dir_all(&sysroot_host_dst));
- for (path, host) in builder.read_stamp_file(stamp) {
- if host {
- builder.copy(&path, &sysroot_host_dst.join(path.file_name().unwrap()));
- } else {
- builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
- }
+ t!(fs::create_dir_all(&self_contained_dst));
+ for (path, dependency_type) in builder.read_stamp_file(stamp) {
+ let dst = match dependency_type {
+ DependencyType::Host => sysroot_host_dst,
+ DependencyType::Target => sysroot_dst,
+ DependencyType::TargetSelfContained => self_contained_dst,
+ };
+ builder.copy(&path, &dst.join(path.file_name().unwrap()));
}
}
cargo: Cargo,
tail_args: Vec<String>,
stamp: &Path,
- additional_target_deps: Vec<PathBuf>,
+ additional_target_deps: Vec<(PathBuf, DependencyType)>,
is_check: bool,
) -> Vec<PathBuf> {
if builder.config.dry_run {
if filename.starts_with(&host_root_dir) {
// Unless it's a proc macro used in the compiler
if crate_types.iter().any(|t| t == "proc-macro") {
- deps.push((filename.to_path_buf(), true));
+ deps.push((filename.to_path_buf(), DependencyType::Host));
}
continue;
}
// If this was output in the `deps` dir then this is a precise file
// name (hash included) so we start tracking it.
if filename.starts_with(&target_deps_dir) {
- deps.push((filename.to_path_buf(), false));
+ deps.push((filename.to_path_buf(), DependencyType::Target));
continue;
}
let candidate = format!("{}.lib", path_to_add);
let candidate = PathBuf::from(candidate);
if candidate.exists() {
- deps.push((candidate, false));
+ deps.push((candidate, DependencyType::Target));
}
}
- deps.push((path_to_add.into(), false));
+ deps.push((path_to_add.into(), DependencyType::Target));
}
- deps.extend(additional_target_deps.into_iter().map(|d| (d, false)));
+ deps.extend(additional_target_deps);
deps.sort();
let mut new_contents = Vec::new();
- for (dep, proc_macro) in deps.iter() {
- new_contents.extend(if *proc_macro { b"h" } else { b"t" });
+ for (dep, dependency_type) in deps.iter() {
+ new_contents.extend(match *dependency_type {
+ DependencyType::Host => b"h",
+ DependencyType::Target => b"t",
+ DependencyType::TargetSelfContained => b"s",
+ });
new_contents.extend(dep.to_str().unwrap().as_bytes());
new_contents.extend(b"\0");
}