summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-02-26 13:57:07 +0000
committerbors <bors@rust-lang.org>2024-02-26 13:57:07 +0000
commitb5f51498d169a886993bdc8c438b2b9b521f6673 (patch)
tree7013e23250387c1c304c4ee5e2872866d1a7c0e1
parentf415cb2088dab7917e015e0acb1e3ea1d262220a (diff)
parent34215b1b4a5db54ff09526aa8888d51bb458421c (diff)
Auto merge of #13490 - weihanglo:rustdoc-shared-libs, r=<try>try
fix(doctest): search native libs in build script outputs
-rw-r--r--src/cargo/core/compiler/compilation.rs44
-rw-r--r--tests/testsuite/test.rs48
2 files changed, 86 insertions, 6 deletions
diff --git a/src/cargo/core/compiler/compilation.rs b/src/cargo/core/compiler/compilation.rs
index 018792d2b..017c41b8a 100644
--- a/src/cargo/core/compiler/compilation.rs
+++ b/src/cargo/core/compiler/compilation.rs
@@ -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
@@ -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`.
@@ -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);
@@ -214,7 +233,7 @@ impl<'gctx> Compilation<'gctx> {
pkg,
None,
CompileKind::Host,
- false,
+ ToolKind::HostProcess,
)
}
@@ -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);
@@ -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(
diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs
index ae79e8df6..44a830134 100644
--- a/tests/testsuite/test.rs
+++ b/tests/testsuite/test.rs
@@ -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]
@@ -2768,6 +2769,53 @@ fn only_test_docs() {
}
#[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()
.file(