Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 46 additions & 9 deletions src/cargo/core/compiler/unit_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,17 +465,30 @@ fn calc_artifact_deps<'a>(
!unit.mode.is_run_custom_build(),
"BUG: This should be handled in a separate branch"
);
let package_target = artifact_package_target(
artifact,
artifact_pkg,
state.target_data.requested_kinds(),
);
let compile_kind = artifact
.target()
.and_then(|t| match t {
ArtifactTarget::BuildDependencyAssumeTarget => None,
ArtifactTarget::Force(kind) => Some(CompileKind::Target(kind)),
})
.or(package_target)
.unwrap_or(unit.kind);
let unit_for = match package_target {
Some(kind) => {
unit_for.with_artifact_features_from_resolved_compile_kind(Some(kind))
}
None => unit_for.with_artifact_features(artifact),
};
ret.extend(artifact_targets_to_unit_deps(
unit,
unit_for.with_artifact_features(artifact),
unit_for,
state,
artifact
.target()
.and_then(|t| match t {
ArtifactTarget::BuildDependencyAssumeTarget => None,
ArtifactTarget::Force(kind) => Some(CompileKind::Target(kind)),
})
.unwrap_or(unit.kind),
compile_kind,
artifact_pkg,
dep,
)?);
Expand Down Expand Up @@ -554,7 +567,14 @@ fn compute_deps_custom_build(
let artifact = dep.artifact().expect("artifact dep");
let resolved_artifact_compile_kind = artifact
.target()
.map(|target| target.to_resolved_compile_kind(root_unit_compile_target));
.map(|target| target.to_resolved_compile_kind(root_unit_compile_target))
.or_else(|| {
artifact_package_target(
artifact,
artifact_pkg,
state.target_data.requested_kinds(),
)
});

result.extend(artifact_targets_to_unit_deps(
unit,
Expand All @@ -572,6 +592,23 @@ fn compute_deps_custom_build(
Ok(result)
}

fn artifact_package_target(
artifact: &Artifact,
artifact_pkg: &Package,
requested_kinds: &[CompileKind],
) -> Option<CompileKind> {
if artifact.target().is_some() {
return None;
}
if let Some(kind) = artifact_pkg.manifest().forced_kind() {
return Some(kind);
}
if requested_kinds.iter().any(CompileKind::is_host) {
return artifact_pkg.manifest().default_kind();
}
None
}

/// Given a `parent` unit containing a dependency `dep` whose package is `artifact_pkg`,
/// find all targets in `artifact_pkg` which refer to the `dep`s artifact declaration
/// and turn them into units.
Expand Down
3 changes: 2 additions & 1 deletion src/cargo/core/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,8 @@ impl UnitFor {
match dep_artifact {
Some(artifact) => artifact
.target()
.and_then(|t| t.to_resolved_compile_target(self.root_compile_kind)),
.and_then(|t| t.to_resolved_compile_target(self.root_compile_kind))
.or(self.artifact_target_for_features),
None => self.artifact_target_for_features,
},
)
Expand Down
30 changes: 26 additions & 4 deletions src/cargo/core/resolver/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
fn artifact_features_for(
this: &mut FeatureResolver<'_, '_>,
pkg_id: PackageId,
dep_pkg_id: PackageId,
dep: &Dependency,
lib_fk: FeaturesFor,
unstable_json_spec: bool,
Expand All @@ -817,6 +818,21 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
return Ok(vec![lib_fk]);
};
let mut result = Vec::new();
let artifact_target = artifact.target().or_else(|| {
let dep_pkg = this
.package_set
.get_one(dep_pkg_id)
.expect("packages downloaded");
if let Some(CompileKind::Target(target)) = dep_pkg.manifest().forced_kind() {
return Some(ArtifactTarget::Force(target));
}
if this.requested_targets.iter().any(CompileKind::is_host) {
if let Some(CompileKind::Target(target)) = dep_pkg.manifest().default_kind() {
return Some(ArtifactTarget::Force(target));
}
}
None
});
let host_triple = this.target_data.rustc.host;
// Not all targets may be queried before resolution since artifact
// dependencies and per-pkg-targets are not immediately known.
Expand All @@ -834,7 +850,7 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
})
};

if let Some(target) = artifact.target() {
if let Some(target) = artifact_target {
match target {
ArtifactTarget::Force(target) => {
activate_target(target)?;
Expand All @@ -856,7 +872,7 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
}
}
}
if artifact.is_lib() || artifact.target().is_none() {
if artifact.is_lib() || artifact_target.is_none() {
result.push(lib_fk);
}
Ok(result)
Expand Down Expand Up @@ -919,8 +935,14 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
fk
};

let dep_fks =
artifact_features_for(self, pkg_id, dep, lib_fk, unstable_json_spec)?;
let dep_fks = artifact_features_for(
self,
pkg_id,
dep_id,
dep,
lib_fk,
unstable_json_spec,
)?;
Ok(dep_fks.into_iter().map(move |dep_fk| (dep, dep_fk)))
})
.flatten_ok()
Expand Down
5 changes: 5 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -1040,8 +1040,13 @@ Artifact-dependencies adds the following keys to a dependency declaration in `Ca
This field can only be specified when `artifact` is specified.

The default if this is not specified depends on the dependency kind.
If the dependency package specifies `package.forced-target`, that target is
used.
If no command-line target is specified and the dependency package specifies
`package.default-target`, that target is used.
For build dependencies, it will be built for the host target.
For all other dependencies, it will be built for the same targets the declaring package is built for.
An explicit artifact dependency `target` overrides either package target.

For a build dependency, this can also take the special value of `"target"` which means to build the dependency for the same targets that the package is being built for.

Expand Down
Loading
Loading