@@ -802,6 +802,63 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
802
802
}
803
803
}
804
804
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
+
805
862
self . resolve
806
863
. deps ( pkg_id)
807
864
. map ( |( dep_id, deps) | {
@@ -850,79 +907,15 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
850
907
// for various targets which are either specified in the manifest
851
908
// or on the cargo command-line.
852
909
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 ( )
856
914
} else {
857
915
fk
858
916
} ;
859
917
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) ?;
926
919
Ok ( dep_fks. into_iter ( ) . map ( move |dep_fk| ( dep, dep_fk) ) )
927
920
} )
928
921
. flatten_ok ( )
0 commit comments