rustbuild: Add steps for linking a sysroot

When cross compiling for a new host, we can't actually run the host compiler to
generate its own libs. In theory, however, all stage2 compilers (for any host)
will produce the same libraries, so we just require the build compiler to
produce the necessary host libraries and then we link those into place.
This commit is contained in:
Alex Crichton 2016-02-24 23:50:32 -08:00
parent 06773878f3
commit e9a897c10f
3 changed files with 88 additions and 6 deletions

View File

@ -58,6 +58,30 @@ pub fn std<'a>(build: &'a Build, stage: u32, target: &str,
}
build.run(&mut cargo);
std_link(build, stage, target, compiler, host);
}
/// Link all libstd rlibs/dylibs into the sysroot location.
///
/// Links those artifacts generated in the given `stage` for `target` produced
/// by `compiler` into `host`'s sysroot.
pub fn std_link(build: &Build,
stage: u32,
target: &str,
compiler: &Compiler,
host: &str) {
let libdir = build.sysroot_libdir(stage, host, target);
let out_dir = build.cargo_out(stage, compiler.host, true, target);
// If we're linking one compiler host's output into another, then we weren't
// called from the `std` method above. In that case we clean out what's
// already there and then also link compiler-rt into place.
if host != compiler.host {
let _ = fs::remove_dir_all(&libdir);
t!(fs::create_dir_all(&libdir));
t!(fs::hard_link(&build.compiler_rt_built.borrow()[target],
libdir.join(staticlib("compiler-rt", target))));
}
add_to_sysroot(&out_dir, &libdir);
}
@ -150,8 +174,21 @@ pub fn rustc<'a>(build: &'a Build, stage: u32, target: &str,
}
build.run(&mut cargo);
let sysroot_libdir = build.sysroot_libdir(stage, host, target);
add_to_sysroot(&out_dir, &sysroot_libdir);
rustc_link(build, stage, target, compiler, compiler.host);
}
/// Link all librustc rlibs/dylibs into the sysroot location.
///
/// Links those artifacts generated in the given `stage` for `target` produced
/// by `compiler` into `host`'s sysroot.
pub fn rustc_link(build: &Build,
stage: u32,
target: &str,
compiler: &Compiler,
host: &str) {
let libdir = build.sysroot_libdir(stage, host, target);
let out_dir = build.cargo_out(stage, compiler.host, false, target);
add_to_sysroot(&out_dir, &libdir);
}
/// Cargo's output path for the standard library in a given stage, compiled

View File

@ -146,6 +146,14 @@ impl Build {
Librustc { stage, compiler } => {
compile::rustc(self, stage, target.target, &compiler);
}
LibstdLink { stage, compiler, host } => {
compile::std_link(self, stage, target.target,
&compiler, host);
}
LibrustcLink { stage, compiler, host } => {
compile::rustc_link(self, stage, target.target,
&compiler, host);
}
Rustc { stage: 0 } => {
assert!(target.target == self.config.build,
"only have one stage0 compiler");

View File

@ -32,6 +32,19 @@ macro_rules! targets {
(libstd, Libstd { stage: u32, compiler: Compiler<'a> }),
(librustc, Librustc { stage: u32, compiler: Compiler<'a> }),
// Links the standard library/librustc produced by the compiler
// provided into the host's directory also provided.
(libstd_link, LibstdLink {
stage: u32,
compiler: Compiler<'a>,
host: &'a str
}),
(librustc_link, LibrustcLink {
stage: u32,
compiler: Compiler<'a>,
host: &'a str
}),
// Steps for long-running native builds. Ideally these wouldn't
// actually exist and would be part of build scripts, but for now
// these are here.
@ -107,13 +120,25 @@ fn top_level(build: &Build) -> Vec<Step> {
continue
}
let host = t.target(host);
targets.push(host.librustc(stage, t.compiler(stage)));
if host.target == build.config.build {
targets.push(host.librustc(stage, host.compiler(stage)));
} else {
targets.push(host.librustc_link(stage, t.compiler(stage),
host.target));
}
for target in build.config.target.iter() {
if !build.flags.target.contains(target) {
continue
}
targets.push(host.target(target)
.libstd(stage, t.compiler(stage)));
if host.target == build.config.build {
targets.push(host.target(target)
.libstd(stage, host.compiler(stage)));
} else {
targets.push(host.target(target)
.libstd_link(stage, t.compiler(stage),
host.target));
}
}
}
}
@ -128,10 +153,14 @@ fn add_steps<'a>(build: &'a Build,
target: &Step<'a>,
targets: &mut Vec<Step<'a>>) {
for step in build.flags.step.iter() {
let compiler = host.compiler(stage);
let compiler = host.target(&build.config.build).compiler(stage);
match &step[..] {
"libstd" => targets.push(target.libstd(stage, compiler)),
"librustc" => targets.push(target.librustc(stage, compiler)),
"libstd-link" => targets.push(target.libstd_link(stage, compiler,
host.target)),
"librustc-link" => targets.push(target.librustc_link(stage, compiler,
host.target)),
"rustc" => targets.push(host.rustc(stage)),
"llvm" => targets.push(target.llvm(())),
"compiler-rt" => targets.push(target.compiler_rt(())),
@ -179,6 +208,14 @@ impl<'a> Step<'a> {
vec![self.compiler_rt(()),
self.rustc(compiler.stage).target(compiler.host)]
}
Source::LibrustcLink { stage, compiler, host } => {
vec![self.librustc(stage, compiler),
self.libstd_link(stage, compiler, host)]
}
Source::LibstdLink { stage, compiler, host } => {
vec![self.libstd(stage, compiler),
self.target(host).rustc(stage)]
}
Source::CompilerRt { _dummy } => {
vec![self.llvm(()).target(&build.config.build)]
}