Skip to content

Commit e9a897c

Browse files
committed
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.
1 parent 0677387 commit e9a897c

File tree

3 files changed

+88
-6
lines changed

3 files changed

+88
-6
lines changed

src/bootstrap/build/compile.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ pub fn std<'a>(build: &'a Build, stage: u32, target: &str,
5858
}
5959

6060
build.run(&mut cargo);
61+
std_link(build, stage, target, compiler, host);
62+
}
63+
64+
/// Link all libstd rlibs/dylibs into the sysroot location.
65+
///
66+
/// Links those artifacts generated in the given `stage` for `target` produced
67+
/// by `compiler` into `host`'s sysroot.
68+
pub fn std_link(build: &Build,
69+
stage: u32,
70+
target: &str,
71+
compiler: &Compiler,
72+
host: &str) {
73+
let libdir = build.sysroot_libdir(stage, host, target);
74+
let out_dir = build.cargo_out(stage, compiler.host, true, target);
75+
76+
// If we're linking one compiler host's output into another, then we weren't
77+
// called from the `std` method above. In that case we clean out what's
78+
// already there and then also link compiler-rt into place.
79+
if host != compiler.host {
80+
let _ = fs::remove_dir_all(&libdir);
81+
t!(fs::create_dir_all(&libdir));
82+
t!(fs::hard_link(&build.compiler_rt_built.borrow()[target],
83+
libdir.join(staticlib("compiler-rt", target))));
84+
}
6185
add_to_sysroot(&out_dir, &libdir);
6286
}
6387

@@ -150,8 +174,21 @@ pub fn rustc<'a>(build: &'a Build, stage: u32, target: &str,
150174
}
151175
build.run(&mut cargo);
152176

153-
let sysroot_libdir = build.sysroot_libdir(stage, host, target);
154-
add_to_sysroot(&out_dir, &sysroot_libdir);
177+
rustc_link(build, stage, target, compiler, compiler.host);
178+
}
179+
180+
/// Link all librustc rlibs/dylibs into the sysroot location.
181+
///
182+
/// Links those artifacts generated in the given `stage` for `target` produced
183+
/// by `compiler` into `host`'s sysroot.
184+
pub fn rustc_link(build: &Build,
185+
stage: u32,
186+
target: &str,
187+
compiler: &Compiler,
188+
host: &str) {
189+
let libdir = build.sysroot_libdir(stage, host, target);
190+
let out_dir = build.cargo_out(stage, compiler.host, false, target);
191+
add_to_sysroot(&out_dir, &libdir);
155192
}
156193

157194
/// Cargo's output path for the standard library in a given stage, compiled

src/bootstrap/build/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ impl Build {
146146
Librustc { stage, compiler } => {
147147
compile::rustc(self, stage, target.target, &compiler);
148148
}
149+
LibstdLink { stage, compiler, host } => {
150+
compile::std_link(self, stage, target.target,
151+
&compiler, host);
152+
}
153+
LibrustcLink { stage, compiler, host } => {
154+
compile::rustc_link(self, stage, target.target,
155+
&compiler, host);
156+
}
149157
Rustc { stage: 0 } => {
150158
assert!(target.target == self.config.build,
151159
"only have one stage0 compiler");

src/bootstrap/build/step.rs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ macro_rules! targets {
3232
(libstd, Libstd { stage: u32, compiler: Compiler<'a> }),
3333
(librustc, Librustc { stage: u32, compiler: Compiler<'a> }),
3434

35+
// Links the standard library/librustc produced by the compiler
36+
// provided into the host's directory also provided.
37+
(libstd_link, LibstdLink {
38+
stage: u32,
39+
compiler: Compiler<'a>,
40+
host: &'a str
41+
}),
42+
(librustc_link, LibrustcLink {
43+
stage: u32,
44+
compiler: Compiler<'a>,
45+
host: &'a str
46+
}),
47+
3548
// Steps for long-running native builds. Ideally these wouldn't
3649
// actually exist and would be part of build scripts, but for now
3750
// these are here.
@@ -107,13 +120,25 @@ fn top_level(build: &Build) -> Vec<Step> {
107120
continue
108121
}
109122
let host = t.target(host);
110-
targets.push(host.librustc(stage, t.compiler(stage)));
123+
if host.target == build.config.build {
124+
targets.push(host.librustc(stage, host.compiler(stage)));
125+
} else {
126+
targets.push(host.librustc_link(stage, t.compiler(stage),
127+
host.target));
128+
}
111129
for target in build.config.target.iter() {
112130
if !build.flags.target.contains(target) {
113131
continue
114132
}
115-
targets.push(host.target(target)
116-
.libstd(stage, t.compiler(stage)));
133+
134+
if host.target == build.config.build {
135+
targets.push(host.target(target)
136+
.libstd(stage, host.compiler(stage)));
137+
} else {
138+
targets.push(host.target(target)
139+
.libstd_link(stage, t.compiler(stage),
140+
host.target));
141+
}
117142
}
118143
}
119144
}
@@ -128,10 +153,14 @@ fn add_steps<'a>(build: &'a Build,
128153
target: &Step<'a>,
129154
targets: &mut Vec<Step<'a>>) {
130155
for step in build.flags.step.iter() {
131-
let compiler = host.compiler(stage);
156+
let compiler = host.target(&build.config.build).compiler(stage);
132157
match &step[..] {
133158
"libstd" => targets.push(target.libstd(stage, compiler)),
134159
"librustc" => targets.push(target.librustc(stage, compiler)),
160+
"libstd-link" => targets.push(target.libstd_link(stage, compiler,
161+
host.target)),
162+
"librustc-link" => targets.push(target.librustc_link(stage, compiler,
163+
host.target)),
135164
"rustc" => targets.push(host.rustc(stage)),
136165
"llvm" => targets.push(target.llvm(())),
137166
"compiler-rt" => targets.push(target.compiler_rt(())),
@@ -179,6 +208,14 @@ impl<'a> Step<'a> {
179208
vec![self.compiler_rt(()),
180209
self.rustc(compiler.stage).target(compiler.host)]
181210
}
211+
Source::LibrustcLink { stage, compiler, host } => {
212+
vec![self.librustc(stage, compiler),
213+
self.libstd_link(stage, compiler, host)]
214+
}
215+
Source::LibstdLink { stage, compiler, host } => {
216+
vec![self.libstd(stage, compiler),
217+
self.target(host).rustc(stage)]
218+
}
182219
Source::CompilerRt { _dummy } => {
183220
vec![self.llvm(()).target(&build.config.build)]
184221
}

0 commit comments

Comments
 (0)