@@ -802,6 +802,63 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
802802 }
803803 }
804804
805+ /// Returns the `FeaturesFor` needed for this dependency.
806+ ///
807+ /// This includes the `FeaturesFor` for artifact dependencies, which
808+ /// might specify multiple targets.
809+ fn artifact_features_for (
810+ this : & mut FeatureResolver < ' _ , ' _ > ,
811+ pkg_id : PackageId ,
812+ dep : & Dependency ,
813+ lib_fk : FeaturesFor ,
814+ ) -> CargoResult < Vec < FeaturesFor > > {
815+ let Some ( artifact) = dep. artifact ( ) else {
816+ return Ok ( vec ! [ lib_fk] ) ;
817+ } ;
818+ let mut result = Vec :: new ( ) ;
819+ let host_triple = this. target_data . rustc . host ;
820+ // Not all targets may be queried before resolution since artifact
821+ // dependencies and per-pkg-targets are not immediately known.
822+ let mut activate_target = |target| {
823+ let name = dep. name_in_toml ( ) ;
824+ this. target_data
825+ . merge_compile_kind ( CompileKind :: Target ( target) )
826+ . with_context ( || {
827+ format ! (
828+ "failed to determine target information for target `{target}`.\n \
829+ Artifact dependency `{name}` in package `{pkg_id}` requires building \
830+ for `{target}`",
831+ target = target. rustc_target( )
832+ )
833+ } )
834+ } ;
835+
836+ if let Some ( target) = artifact. target ( ) {
837+ match target {
838+ ArtifactTarget :: Force ( target) => {
839+ activate_target ( target) ?;
840+ result. push ( FeaturesFor :: ArtifactDep ( target) )
841+ }
842+ // FIXME: this needs to interact with the `default-target`
843+ // and `forced-target` values of the dependency
844+ ArtifactTarget :: BuildDependencyAssumeTarget => {
845+ for kind in this. requested_targets {
846+ let target = match kind {
847+ CompileKind :: Host => CompileTarget :: new ( & host_triple) . unwrap ( ) ,
848+ CompileKind :: Target ( target) => * target,
849+ } ;
850+ activate_target ( target) ?;
851+ result. push ( FeaturesFor :: ArtifactDep ( target) ) ;
852+ }
853+ }
854+ }
855+ }
856+ if artifact. is_lib ( ) || artifact. target ( ) . is_none ( ) {
857+ result. push ( lib_fk) ;
858+ }
859+ Ok ( result)
860+ }
861+
805862 self . resolve
806863 . deps ( pkg_id)
807864 . map ( |( dep_id, deps) | {
@@ -850,79 +907,15 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
850907 // for various targets which are either specified in the manifest
851908 // or on the cargo command-line.
852909 let lib_fk = if fk == FeaturesFor :: default ( ) {
853- ( self . track_for_host && ( dep. is_build ( ) || self . has_proc_macro_lib ( dep_id) ) )
854- . then ( || FeaturesFor :: HostDep )
855- . unwrap_or_default ( )
910+ ( self . track_for_host
911+ && ( dep. is_build ( ) || self . has_proc_macro_lib ( dep_id) ) )
912+ . then ( || FeaturesFor :: HostDep )
913+ . unwrap_or_default ( )
856914 } else {
857915 fk
858916 } ;
859917
860- // `artifact_target_keys` are produced to fulfil the needs of artifacts that have a target specification.
861- let artifact_target_keys = dep
862- . artifact ( )
863- . map ( |artifact| {
864- let host_triple = self . target_data . rustc . host ;
865- // not all targets may be queried before resolution since artifact dependencies
866- // and per-pkg-targets are not immediately known.
867- let mut activate_target = |target| {
868- let name = dep. name_in_toml ( ) ;
869- self . target_data
870- . merge_compile_kind ( CompileKind :: Target ( target) )
871- . with_context ( || format ! ( "failed to determine target information for target `{target}`.\n \
872- Artifact dependency `{name}` in package `{pkg_id}` requires building for `{target}`", target = target. rustc_target( ) ) )
873- } ;
874- CargoResult :: Ok ( (
875- artifact. is_lib ( ) ,
876- artifact
877- . target ( )
878- . map ( |target| {
879- CargoResult :: Ok ( match target {
880- ArtifactTarget :: Force ( target) => {
881- activate_target ( target) ?;
882- vec ! [ FeaturesFor :: ArtifactDep ( target) ]
883- }
884- // FIXME: this needs to interact with the `default-target` and `forced-target` values
885- // of the dependency
886- ArtifactTarget :: BuildDependencyAssumeTarget => self
887- . requested_targets
888- . iter ( )
889- . map ( |kind| match kind {
890- CompileKind :: Host => {
891- CompileTarget :: new ( & host_triple)
892- . unwrap ( )
893- }
894- CompileKind :: Target ( target) => * target,
895- } )
896- . map ( |target| {
897- activate_target ( target) ?;
898- Ok ( FeaturesFor :: ArtifactDep ( target) )
899- } )
900- . collect :: < CargoResult < _ > > ( ) ?,
901- } )
902- } )
903- . transpose ( ) ?,
904- ) )
905- } )
906- . transpose ( ) ?;
907-
908- let dep_fks = match artifact_target_keys {
909- // The artifact is also a library and does specify custom
910- // targets.
911- // The library's feature key needs to be used alongside
912- // the keys artifact targets.
913- Some ( ( is_lib, Some ( mut dep_fks) ) ) if is_lib => {
914- dep_fks. push ( lib_fk) ;
915- dep_fks
916- }
917- // The artifact is not a library, but does specify
918- // custom targets.
919- // Use only these targets feature keys.
920- Some ( ( _, Some ( dep_fks) ) ) => dep_fks,
921- // There is no artifact in the current dependency
922- // or there is no target specified on the artifact.
923- // Use the standard feature key without any alteration.
924- Some ( ( _, None ) ) | None => vec ! [ lib_fk] ,
925- } ;
918+ let dep_fks = artifact_features_for ( self , pkg_id, dep, lib_fk) ?;
926919 Ok ( dep_fks. into_iter ( ) . map ( move |dep_fk| ( dep, dep_fk) ) )
927920 } )
928921 . flatten_ok ( )
0 commit comments