Skip to content

Commit

Permalink
Auto merge of rust-lang#13490 - weihanglo:rustdoc-shared-libs, r=epage
Browse files Browse the repository at this point in the history
fix(doctest): search native libs in build script outputs
  • Loading branch information
bors committed Feb 26, 2024
2 parents cc6e326 + 34215b1 commit a7e9347
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 6 deletions.
44 changes: 38 additions & 6 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ use crate::core::compiler::{CompileKind, Metadata, Unit};
use crate::core::Package;
use crate::util::{config, CargoResult, GlobalContext};

/// Represents the kind of process we are creating.
#[derive(Debug)]
enum ToolKind {
/// See [`Compilation::rustc_process`].
Rustc,
/// See [`Compilation::rustdoc_process`].
Rustdoc,
/// See [`Compilation::host_process`].
HostProcess,
/// See [`Compilation::target_process`].
TargetProcess,
}

impl ToolKind {
fn is_rustc_tool(&self) -> bool {
matches!(self, ToolKind::Rustc | ToolKind::Rustdoc)
}
}

/// Structure with enough information to run `rustdoc --test`.
pub struct Doctest {
/// What's being doctested
Expand Down Expand Up @@ -176,7 +195,7 @@ impl<'gctx> Compilation<'gctx> {
};

let cmd = fill_rustc_tool_env(rustc, unit);
self.fill_env(cmd, &unit.pkg, None, unit.kind, true)
self.fill_env(cmd, &unit.pkg, None, unit.kind, ToolKind::Rustc)
}

/// Returns a [`ProcessBuilder`] for running `rustdoc`.
Expand All @@ -187,7 +206,7 @@ impl<'gctx> Compilation<'gctx> {
) -> CargoResult<ProcessBuilder> {
let rustdoc = ProcessBuilder::new(&*self.gctx.rustdoc()?);
let cmd = fill_rustc_tool_env(rustdoc, unit);
let mut cmd = self.fill_env(cmd, &unit.pkg, script_meta, unit.kind, true)?;
let mut cmd = self.fill_env(cmd, &unit.pkg, script_meta, unit.kind, ToolKind::Rustdoc)?;
cmd.retry_with_argfile(true);
unit.target.edition().cmd_edition_arg(&mut cmd);

Expand All @@ -214,7 +233,7 @@ impl<'gctx> Compilation<'gctx> {
pkg,
None,
CompileKind::Host,
false,
ToolKind::HostProcess,
)
}

Expand Down Expand Up @@ -249,7 +268,8 @@ impl<'gctx> Compilation<'gctx> {
} else {
ProcessBuilder::new(cmd)
};
let mut builder = self.fill_env(builder, pkg, script_meta, kind, false)?;
let tool_kind = ToolKind::TargetProcess;
let mut builder = self.fill_env(builder, pkg, script_meta, kind, tool_kind)?;

if let Some(client) = self.gctx.jobserver_from_env() {
builder.inherit_jobserver(client);
Expand All @@ -269,10 +289,22 @@ impl<'gctx> Compilation<'gctx> {
pkg: &Package,
script_meta: Option<Metadata>,
kind: CompileKind,
is_rustc_tool: bool,
tool_kind: ToolKind,
) -> CargoResult<ProcessBuilder> {
let mut search_path = Vec::new();
if is_rustc_tool {
if tool_kind.is_rustc_tool() {
if matches!(tool_kind, ToolKind::Rustdoc) {
// HACK: `rustdoc --test` not only compiles but executes doctests.
// Ideally only execution phase should have search paths appended,
// so the executions can find native libs just like other tests.
// However, there is no way to separate these two phase, so this
// hack is added for both phases.
// TODO: handle doctest-xcompile
search_path.extend(super::filter_dynamic_search_path(
self.native_dirs.iter(),
&self.root_output[&CompileKind::Host],
));
}
search_path.push(self.deps_output[&CompileKind::Host].clone());
} else {
search_path.extend(super::filter_dynamic_search_path(
Expand Down
48 changes: 48 additions & 0 deletions tests/testsuite/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use cargo_test_support::{
};
use cargo_test_support::{cross_compile, paths};
use cargo_test_support::{rustc_host, rustc_host_env, sleep_ms};
use cargo_util::paths::dylib_path_envvar;
use std::fs;

#[cargo_test]
Expand Down Expand Up @@ -2767,6 +2768,53 @@ fn only_test_docs() {
.run();
}

#[cargo_test]
fn doctest_with_library_paths() {
let p = project();
// Only link search directories within the target output directory are
// propagated through to dylib_path_envvar() (see #3366).
let dir1 = p.target_debug_dir().join("foo\\backslash");
let dir2 = p.target_debug_dir().join("dir=containing=equal=signs");

let p = p
.file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
.file(
"build.rs",
&format!(
r##"
fn main() {{
println!(r#"cargo::rustc-link-search=native={}"#);
println!(r#"cargo::rustc-link-search={}"#);
}}
"##,
dir1.display(),
dir2.display()
),
)
.file(
"src/lib.rs",
&format!(
r##"
/// ```
/// foo::assert_search_path();
/// ```
pub fn assert_search_path() {{
let search_path = std::env::var_os("{}").unwrap();
let paths = std::env::split_paths(&search_path).collect::<Vec<_>>();
assert!(paths.contains(&r#"{}"#.into()));
assert!(paths.contains(&r#"{}"#.into()));
}}
"##,
dylib_path_envvar(),
dir1.display(),
dir2.display()
),
)
.build();

p.cargo("test --doc").run();
}

#[cargo_test]
fn test_panic_abort_with_dep() {
let p = project()
Expand Down

0 comments on commit a7e9347

Please sign in to comment.