Skip to content

Commit b98c476

Browse files
committed
Add sysroot detection in rustdoc
When building `rustdoc` without using `x.py`, the sysroot is not going to be detected automatically. It wasn't an issue when using `x.py`, and this commit should not have any effect when building `rustdoc` as part of the `rustc` build. Note: if you want to build rustdoc out-of-tree, you need to install the rustup components `rustc-dev` and `llvm-tools-preview`.
1 parent a38f8fb commit b98c476

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

src/librustdoc/lib.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,30 @@ pub fn main() {
9696
process::exit(exit_code);
9797
}
9898

99+
// Taken from
100+
// https://github.com/rust-lang/miri/blob/master/src/bin/miri.rs
101+
/// Returns the "default sysroot" that will be used if no `--sysroot` flag is set.
102+
/// Should be a compile-time constant.
103+
fn compile_time_sysroot() -> Option<String> {
104+
if option_env!("RUSTC_STAGE").is_some() {
105+
// This is being built as part of rustc, and gets shipped with rustup.
106+
// We can rely on the sysroot computation in librustc_session.
107+
return None;
108+
}
109+
// For builds outside rustc, we need to ensure that we got a sysroot
110+
// that gets used as a default. The sysroot computation in librustc_session would
111+
// end up somewhere in the build dir (see `get_or_default_sysroot`).
112+
// Taken from PR <https://github.com/Manishearth/rust-clippy/pull/911>.
113+
let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
114+
let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
115+
Some(match (home, toolchain) {
116+
(Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
117+
_ => option_env!("RUST_SYSROOT")
118+
.expect("To build rustdoc without rustup, set the `RUST_SYSROOT` env var at build time")
119+
.to_owned(),
120+
})
121+
}
122+
99123
fn get_args() -> Option<Vec<String>> {
100124
env::args_os()
101125
.enumerate()
@@ -109,7 +133,25 @@ fn get_args() -> Option<Vec<String>> {
109133
})
110134
.ok()
111135
})
112-
.collect()
136+
.collect::<Option<_>>()
137+
.map(|mut args: Vec<String>| {
138+
// Make sure we use the right default sysroot. The default sysroot is wrong,
139+
// because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
140+
//
141+
// Make sure we always call `compile_time_sysroot` as that also does some sanity-checks
142+
// of the environment we were built in.
143+
// FIXME: Ideally we'd turn a bad build env into a compile-time error via CTFE or so.
144+
if let Some(sysroot) = compile_time_sysroot() {
145+
let sysroot_flag = "--sysroot";
146+
if !args.iter().any(|e| e == sysroot_flag) {
147+
// We need to overwrite the default that librustc_session would compute.
148+
args.push(sysroot_flag.to_owned());
149+
args.push(sysroot);
150+
}
151+
}
152+
153+
args
154+
})
113155
}
114156

115157
fn stable<F>(name: &'static str, f: F) -> RustcOptGroup

0 commit comments

Comments
 (0)