From 845d376ce004a940cc824db57d6e4c2f72b2559b Mon Sep 17 00:00:00 2001 From: Herman Skogseth Date: Wed, 1 May 2024 14:58:33 +0200 Subject: [PATCH 1/2] Add integration test for building only the specified artifact library --- tests/testsuite/artifact_dep.rs | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index e4b6374f40f..9b8da344550 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -3189,3 +3189,77 @@ fn check_transitive_artifact_dependency_with_different_target() { .with_status(101) .run(); } + +#[cargo_test] +fn build_only_specified_artifact_library() { + // Create a project with: + // - A crate `bar` with both `staticlib` and `cdylib` as crate-types. + // - A crate `foo` which depends on either the `staticlib` or `cdylib` artifact of bar, + // whose build-script simply checks which library artifacts are present. + let create_project = |artifact_lib| { + project() + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "1.0.0" + + [lib] + crate-type = ["staticlib", "cdylib"] + "#, + ) + .file("bar/src/lib.rs", "") + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "1.0.0" + + [build-dependencies] + bar = {{ path = "bar", artifact = "{artifact_lib}" }} + "#), + ) + .file("src/lib.rs", "") + .file( + "build.rs", + r#" + fn main() { + println!("cdylib present: {}", std::env::var_os("CARGO_CDYLIB_FILE_BAR").is_some()); + println!("staticlib present: {}", std::env::var_os("CARGO_STATICLIB_FILE_BAR").is_some()); + } + "#, + ) + .build() + }; + + let cdylib = create_project("cdylib"); + cdylib + .cargo("build -Z bindeps") + .masquerade_as_nightly_cargo(&["bindeps"]) + .run(); + match_exact( + "cdylib present: true\nstaticlib present: true", + &build_script_output_string(&cdylib, "foo"), + "build script output", + "", + None, + ) + .unwrap(); + + let staticlib = create_project("staticlib"); + staticlib + .cargo("build -Z bindeps") + .masquerade_as_nightly_cargo(&["bindeps"]) + .run(); + match_exact( + "cdylib present: true\nstaticlib present: true", + &build_script_output_string(&staticlib, "foo"), + "build script output", + "", + None, + ) + .unwrap(); +} From 9a5cfbcbb9b5a73272a595c65f529de1e5ad9377 Mon Sep 17 00:00:00 2001 From: Herman Skogseth Date: Mon, 29 Apr 2024 22:44:14 +0200 Subject: [PATCH 2/2] Only build the specified artifact library when multiple types are available --- src/cargo/core/compiler/unit_dependencies.rs | 13 ++++++++----- tests/testsuite/artifact_dep.rs | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index 72f47c6491f..1690259747a 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs @@ -24,7 +24,7 @@ use crate::core::compiler::unit_graph::{UnitDep, UnitGraph}; use crate::core::compiler::{ CompileKind, CompileMode, CrateType, RustcTargetData, Unit, UnitInterner, }; -use crate::core::dependency::{Artifact, ArtifactTarget, DepKind}; +use crate::core::dependency::{Artifact, ArtifactKind, ArtifactTarget, DepKind}; use crate::core::profiles::{Profile, Profiles, UnitFor}; use crate::core::resolver::features::{FeaturesFor, ResolvedFeatures}; use crate::core::resolver::Resolve; @@ -555,17 +555,20 @@ fn artifact_targets_to_unit_deps( let ret = match_artifacts_kind_with_targets(dep, artifact_pkg.targets(), parent.pkg.name().as_str())? .into_iter() - .map(|(_artifact_kind, target)| target) - .flat_map(|target| { + .flat_map(|(artifact_kind, target)| { // We split target libraries into individual units, even though rustc is able - // to produce multiple kinds in an single invocation for the sole reason that + // to produce multiple kinds in a single invocation for the sole reason that // each artifact kind has its own output directory, something we can't easily // teach rustc for now. match target.kind() { TargetKind::Lib(kinds) => Box::new( kinds .iter() - .filter(|tk| matches!(tk, CrateType::Cdylib | CrateType::Staticlib)) + .filter(move |tk| match (tk, artifact_kind) { + (CrateType::Cdylib, ArtifactKind::Cdylib) => true, + (CrateType::Staticlib, ArtifactKind::Staticlib) => true, + _ => false, + }) .map(|target_kind| { new_unit_dep( state, diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index 9b8da344550..d4b7d6cf576 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -3241,7 +3241,7 @@ fn build_only_specified_artifact_library() { .masquerade_as_nightly_cargo(&["bindeps"]) .run(); match_exact( - "cdylib present: true\nstaticlib present: true", + "cdylib present: true\nstaticlib present: false", &build_script_output_string(&cdylib, "foo"), "build script output", "", @@ -3255,7 +3255,7 @@ fn build_only_specified_artifact_library() { .masquerade_as_nightly_cargo(&["bindeps"]) .run(); match_exact( - "cdylib present: true\nstaticlib present: true", + "cdylib present: false\nstaticlib present: true", &build_script_output_string(&staticlib, "foo"), "build script output", "",