Skip to content

Commit 47be8e8

Browse files
Rollup merge of #114651 - tmfink:rustdoc-rustc-wrapper, r=GuillaumeGomez
rustdoc: add `--test-builder-wrapper` arg to support wrappers such as RUSTC_WRAPPER when building doctests Currently, `rustdoc` builds test crates with `rustc` directly instead of using [`RUSTC_WRAPPER`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-wrapper) (if any is set). This causes build issues in build systems that use `cargo` but tweak linking flags by setting the `RUSTC_WRAPPER` environment variable. This change is not meant to be final--it's only a minimal proof of concept. Please advise on the best way to proceed. Open questions: - [x] Does supporting the `rustc` wrappers make sense? - yes, `cargo-miri` for example needs a "hack" to workaround the issue - [X] What environment variable(s) should be read for the rustc wrapper? Should `rustdoc` [use the same names as `cargo`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-wrapper)? - None, since `rustdoc` takes arguments - [X] What name should be used for a `rustdoc` CLI option? - `--test-builder-wrapper` - [X] Should a separate workspace wrapper (like `RUSTC_WORKSPACE_WRAPPER`) be supported? - `--test-builder-wrapper` can be passed multiple times to get multiple wrappers passed - [X] How/where should this be documented? It's not obvious to all users that `cargo doc` actually causes `rustdoc` to compile tests with rust - Added doc to `src/doc/rustdoc/src/command-line-arguments.md` per `@GuillaumeGomez`
2 parents accc516 + d02e66d commit 47be8e8

File tree

5 files changed

+60
-2
lines changed

5 files changed

+60
-2
lines changed

src/doc/rustdoc/src/command-line-arguments.md

+29
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,32 @@ This flag is **deprecated** and **has no effect**.
427427
Rustdoc only supports Rust source code and Markdown input formats. If the
428428
file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file.
429429
Otherwise, it assumes that the input file is Rust.
430+
431+
## `--test-builder`: `rustc`-like program to build tests
432+
433+
Using this flag looks like this:
434+
435+
```bash
436+
$ rustdoc --test-builder /path/to/rustc src/lib.rs
437+
```
438+
439+
Rustdoc will use the provided program to compile tests instead of the default `rustc` program from
440+
the sysroot.
441+
442+
## `--test-builder-wrapper`: wrap calls to the test builder
443+
444+
Using this flag looks like this:
445+
446+
```bash
447+
$ rustdoc --test-builder-wrapper /path/to/rustc-wrapper src/lib.rs
448+
$ rustdoc \
449+
--test-builder-wrapper rustc-wrapper1 \
450+
--test-builder-wrapper rustc-wrapper2 \
451+
--test-builder rustc \
452+
src/lib.rs
453+
```
454+
455+
Similar to cargo `build.rustc-wrapper` option, this flag takes a `rustc` wrapper program.
456+
The first argument to the program will be the test builder program.
457+
458+
This flag can be passed multiple times to nest wrappers.

src/librustdoc/config.rs

+7
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ pub(crate) struct Options {
130130
/// default to loading from `$sysroot/bin/rustc`.
131131
pub(crate) test_builder: Option<PathBuf>,
132132

133+
/// Run these wrapper instead of rustc directly
134+
pub(crate) test_builder_wrappers: Vec<PathBuf>,
135+
133136
// Options that affect the documentation process
134137
/// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
135138
/// with and without documentation.
@@ -204,6 +207,7 @@ impl fmt::Debug for Options {
204207
.field("enable-per-target-ignores", &self.enable_per_target_ignores)
205208
.field("run_check", &self.run_check)
206209
.field("no_run", &self.no_run)
210+
.field("test_builder_wrappers", &self.test_builder_wrappers)
207211
.field("nocapture", &self.nocapture)
208212
.field("scrape_examples_options", &self.scrape_examples_options)
209213
.field("unstable_features", &self.unstable_features)
@@ -521,6 +525,8 @@ impl Options {
521525
dcx.fatal("the `--test` flag must be passed to enable `--no-run`");
522526
}
523527

528+
let test_builder_wrappers =
529+
matches.opt_strs("test-builder-wrapper").iter().map(PathBuf::from).collect();
524530
let out_dir = matches.opt_str("out-dir").map(|s| PathBuf::from(&s));
525531
let output = matches.opt_str("output").map(|s| PathBuf::from(&s));
526532
let output = match (out_dir, output) {
@@ -727,6 +733,7 @@ impl Options {
727733
test_builder,
728734
run_check,
729735
no_run,
736+
test_builder_wrappers,
730737
nocapture,
731738
crate_name,
732739
output_format,

src/librustdoc/doctest.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use tempfile::Builder as TempFileBuilder;
2525
use std::env;
2626
use std::io::{self, Write};
2727
use std::panic;
28-
use std::path::PathBuf;
28+
use std::path::{Path, PathBuf};
2929
use std::process::{self, Command, Stdio};
3030
use std::str;
3131
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -306,6 +306,18 @@ fn add_exe_suffix(input: String, target: &TargetTriple) -> String {
306306
input + &exe_suffix
307307
}
308308

309+
fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command {
310+
let mut args = rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary].into_iter());
311+
312+
let exe = args.next().expect("unable to create rustc command");
313+
let mut command = Command::new(exe);
314+
for arg in args {
315+
command.arg(arg);
316+
}
317+
318+
command
319+
}
320+
309321
fn run_test(
310322
test: &str,
311323
crate_name: &str,
@@ -334,7 +346,7 @@ fn run_test(
334346
.test_builder
335347
.as_deref()
336348
.unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc"));
337-
let mut compiler = Command::new(&rustc_binary);
349+
let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
338350
compiler.arg("--crate-type").arg("bin");
339351
for cfg in &rustdoc_options.cfgs {
340352
compiler.arg("--cfg").arg(&cfg);

src/librustdoc/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,14 @@ fn opts() -> Vec<RustcOptGroup> {
530530
unstable("test-builder", |o| {
531531
o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
532532
}),
533+
unstable("test-builder-wrapper", |o| {
534+
o.optmulti(
535+
"",
536+
"test-builder-wrapper",
537+
"Wrapper program to pass test-builder and arguments",
538+
"PATH",
539+
)
540+
}),
533541
unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")),
534542
unstable("generate-redirect-map", |o| {
535543
o.optflagmulti(

tests/run-make/issue-88756-default-output/output-default.stdout

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ Options:
147147

148148
--test-builder PATH
149149
The rustc-like binary to use as the test builder
150+
--test-builder-wrapper PATH
151+
Wrapper program to pass test-builder and arguments
150152
--check Run rustdoc checks
151153
--generate-redirect-map
152154
Generate JSON file at the top level instead of

0 commit comments

Comments
 (0)