@@ -130,6 +130,7 @@ def get_env_dependencies(
130
130
exclude_pattern = None ,
131
131
permit_unsatisfiable_variants = False ,
132
132
merge_build_host_on_same_platform = True ,
133
+ extra_specs = None ,
133
134
):
134
135
specs = m .get_depends_top_and_out (env )
135
136
# replace x.x with our variant's numpy version, or else conda tries to literally go get x.x
@@ -148,6 +149,8 @@ def get_env_dependencies(
148
149
)
149
150
150
151
dependencies = set (dependencies )
152
+ if extra_specs :
153
+ dependencies |= set (extra_specs )
151
154
unsat = None
152
155
random_string = "" .join (
153
156
random .choice (string .ascii_uppercase + string .digits ) for _ in range (10 )
@@ -183,7 +186,7 @@ def get_env_dependencies(
183
186
specs = [package_record_to_requirement (prec ) for prec in precs ]
184
187
return (
185
188
utils .ensure_list (
186
- (specs + subpackages + pass_through_deps )
189
+ (specs + subpackages + pass_through_deps + ( extra_specs or []) )
187
190
or m .get_value (f"requirements/{ env } " , [])
188
191
),
189
192
precs ,
@@ -441,13 +444,15 @@ def _read_upstream_pin_files(
441
444
env ,
442
445
permit_unsatisfiable_variants ,
443
446
exclude_pattern ,
447
+ extra_specs ,
444
448
):
445
449
deps , precs , unsat = get_env_dependencies (
446
450
m ,
447
451
env ,
448
452
m .config .variant ,
449
453
exclude_pattern ,
450
454
permit_unsatisfiable_variants = permit_unsatisfiable_variants ,
455
+ extra_specs = extra_specs ,
451
456
)
452
457
# extend host deps with strong build run exports. This is important for things like
453
458
# vc feature activation to work correctly in the host env.
@@ -459,12 +464,18 @@ def _read_upstream_pin_files(
459
464
)
460
465
461
466
462
- def add_upstream_pins (m : MetaData , permit_unsatisfiable_variants , exclude_pattern ):
467
+ def add_upstream_pins (
468
+ m : MetaData , permit_unsatisfiable_variants , exclude_pattern , extra_specs
469
+ ):
463
470
"""Applies run_exports from any build deps to host and run sections"""
464
471
# if we have host deps, they're more important than the build deps.
465
472
requirements = m .get_section ("requirements" )
466
473
build_deps , build_unsat , extra_run_specs_from_build = _read_upstream_pin_files (
467
- m , "build" , permit_unsatisfiable_variants , exclude_pattern
474
+ m ,
475
+ "build" ,
476
+ permit_unsatisfiable_variants ,
477
+ exclude_pattern ,
478
+ [] if m .is_cross else extra_specs ,
468
479
)
469
480
470
481
# is there a 'host' section?
@@ -490,7 +501,7 @@ def add_upstream_pins(m: MetaData, permit_unsatisfiable_variants, exclude_patter
490
501
host_reqs .extend (extra_run_specs_from_build .get ("strong" , []))
491
502
492
503
host_deps , host_unsat , extra_run_specs_from_host = _read_upstream_pin_files (
493
- m , "host" , permit_unsatisfiable_variants , exclude_pattern
504
+ m , "host" , permit_unsatisfiable_variants , exclude_pattern , extra_specs
494
505
)
495
506
if m .noarch or m .noarch_python :
496
507
extra_run_specs = set (extra_run_specs_from_host .get ("noarch" , []))
@@ -647,9 +658,40 @@ def finalize_metadata(
647
658
utils .insert_variant_versions (requirements , m .config .variant , "build" )
648
659
utils .insert_variant_versions (requirements , m .config .variant , "host" )
649
660
661
+ host_requirements = requirements .get ("host" if m .is_cross else "build" , [])
662
+ host_requirement_names = [req .split (" " )[0 ] for req in host_requirements ]
663
+ extra_specs = []
664
+ if output and output_excludes and not is_top_level and host_requirement_names :
665
+ reqs = {}
666
+
667
+ # we first make a mapping of output -> requirements
668
+ for (name , _ ), (_ , other_meta ) in m .other_outputs .items ():
669
+ if name == m .name ():
670
+ continue
671
+ other_meta_reqs = other_meta .meta .get ("requirements" , {}).get ("run" , [])
672
+ reqs [name ] = set (other_meta_reqs )
673
+
674
+ seen = set ()
675
+ # for each subpackage that is a dependency we add its dependencies
676
+ # and transitive dependencies if the dependency of the subpackage
677
+ # is a subpackage.
678
+ to_process = set (
679
+ name for (name , _ ) in m .other_outputs if name in host_requirement_names
680
+ )
681
+ while to_process :
682
+ name = to_process .pop ()
683
+ if name == m .name ():
684
+ continue
685
+ for req in reqs [name ]:
686
+ req_name = req .split (" " )[0 ]
687
+ if req_name not in reqs :
688
+ extra_specs .append (req )
689
+ elif req_name not in seen :
690
+ to_process .add (req_name )
691
+
650
692
m = parent_metadata .get_output_metadata (m .get_rendered_output (m .name ()))
651
693
build_unsat , host_unsat = add_upstream_pins (
652
- m , permit_unsatisfiable_variants , exclude_pattern
694
+ m , permit_unsatisfiable_variants , exclude_pattern , extra_specs
653
695
)
654
696
# getting this AFTER add_upstream_pins is important, because that function adds deps
655
697
# to the metadata.
@@ -677,6 +719,7 @@ def finalize_metadata(
677
719
m .config .variant ,
678
720
exclude_pattern = exclude_pattern ,
679
721
permit_unsatisfiable_variants = permit_unsatisfiable_variants ,
722
+ extra_specs = extra_specs ,
680
723
)
681
724
full_build_dep_versions = {
682
725
dep .split ()[0 ]: " " .join (dep .split ()[1 :]) for dep in full_build_deps
0 commit comments