diff --git a/crates/pixi_build_backend/src/common/variants.rs b/crates/pixi_build_backend/src/common/variants.rs index 1d1767631e..35d6e0a532 100644 --- a/crates/pixi_build_backend/src/common/variants.rs +++ b/crates/pixi_build_backend/src/common/variants.rs @@ -6,7 +6,6 @@ use miette::IntoDiagnostic; use rattler_build_jinja::Variable; use rattler_build_types::NormalizedKey; use rattler_build_variant_config::VariantConfig; -use rattler_conda_types::Platform; use crate::ProjectModel; @@ -14,7 +13,6 @@ use crate::ProjectModel; pub fn compute_variants( project_model: &P, input_variant_configuration: Option>>, - host_platform: Platform, ) -> miette::Result>> { // Create a variant config from the variant configuration in the parameters. let variant_config = VariantConfig { @@ -23,7 +21,7 @@ pub fn compute_variants( }; // Determine the variant keys that are used in the recipe. - let used_variants = project_model.used_variants(Some(host_platform)); + let used_variants = project_model.used_variants(); // Determine the combinations of the used variants. variant_config diff --git a/crates/pixi_build_backend/src/generated_recipe.rs b/crates/pixi_build_backend/src/generated_recipe.rs index ec4bd110e4..e65b2b5feb 100644 --- a/crates/pixi_build_backend/src/generated_recipe.rs +++ b/crates/pixi_build_backend/src/generated_recipe.rs @@ -16,7 +16,9 @@ use serde::de::DeserializeOwned; use thiserror::Error; use url::Url; -use crate::specs_conversion::from_targets_v1_to_conditional_requirements; +use crate::specs_conversion::{ + SelectorConversionError, from_targets_v1_to_conditional_requirements, +}; #[derive(Debug, Clone, Default)] pub struct PythonParams { @@ -151,6 +153,9 @@ pub enum GenerateRecipeError { #[source] MetadataProviderError, ), + #[error(transparent)] + #[diagnostic(transparent)] + InvalidSelectorExpression(#[from] SelectorConversionError), } #[derive(Clone)] @@ -247,7 +252,7 @@ impl GeneratedRecipe { ); let requirements = - from_targets_v1_to_conditional_requirements(&model.targets.unwrap_or_default()); + from_targets_v1_to_conditional_requirements(&model.targets.unwrap_or_default())?; macro_rules! derive_value { ($ident:ident) => { @@ -373,7 +378,7 @@ impl MetadataProvider for DefaultMetadataProvider { mod tests { use ordermap::OrderMap; use pixi_build_types::{ - BinaryPackageSpec, PackageSpec, SourcePackageName, Target, TargetSelector, Targets, + BinaryPackageSpec, ConditionalExpression, PackageSpec, SourcePackageName, Target, Targets, }; use rattler_conda_types::{Flag, PackageName}; @@ -408,7 +413,7 @@ mod tests { extra_dependencies: Some(extras_with_gtest()), ..Target::default() }), - targets: None, + conditional: None, }), ..ProjectModel::default() }; @@ -425,13 +430,13 @@ mod tests { ); } - /// Per-target extras must be wrapped in a `Conditional` block in the + /// Conditional extras must be wrapped in a `Conditional` block in the /// generated recipe rather than landing as a bare entry. #[test] fn generated_recipe_declares_per_target_extras() { - let mut platform_targets = OrderMap::new(); - platform_targets.insert( - TargetSelector::Win, + let mut conditional_targets = OrderMap::new(); + conditional_targets.insert( + ConditionalExpression::new("win"), Target { extra_dependencies: Some(extras_with_gtest()), ..Target::default() @@ -443,7 +448,7 @@ mod tests { version: Some("0.1.0".parse().unwrap()), targets: Some(Targets { default_target: None, - targets: Some(platform_targets), + conditional: Some(conditional_targets), }), ..ProjectModel::default() }; diff --git a/crates/pixi_build_backend/src/specs_conversion.rs b/crates/pixi_build_backend/src/specs_conversion.rs index 3e3c349a73..6921f275ad 100644 --- a/crates/pixi_build_backend/src/specs_conversion.rs +++ b/crates/pixi_build_backend/src/specs_conversion.rs @@ -4,7 +4,7 @@ use minijinja::Value; use ordermap::OrderMap; use pixi_build_types::{ BinaryPackageSpec, ExtraGroupName, PackageSpec, SourcePackageName, SourcePackageSpec, Target, - TargetSelector, Targets, + Targets, procedures::conda_build_v1::{ CondaBuildV1Dependency, CondaBuildV1DependencySource, CondaBuildV1Prefix, CondaBuildV1RunExports, @@ -21,14 +21,22 @@ use rattler_build_recipe::stage0::{ }; use crate::package_dependency::{PackageDependency, SourceMatchSpec}; +use miette::Diagnostic; use rattler_conda_types::{ Channel, MatchSpec, PackageName, PackageNameMatcher, package::RunExportsJson, }; use serde::Deserialize; +use thiserror::Error; use url::Url; use crate::encoded_source_spec_url::EncodedSourceSpecUrl; +#[derive(Debug, Error, Diagnostic)] +pub enum SelectorConversionError { + #[error("invalid selector expression `{expression}`: {message}")] + InvalidExpression { expression: String, message: String }, +} + pub fn from_source_url_to_source_package(source_url: Url) -> Option { match source_url.scheme() { "source" => Some(EncodedSourceSpecUrl::from(source_url).into()), @@ -43,23 +51,6 @@ pub fn from_source_matchspec_into_package_spec( .ok_or_else(|| miette::miette!("Only file, http/https and git are supported for now")) } -#[derive(Debug, Clone)] -pub enum PlatformKind { - Build, - Host, - Target, -} - -impl std::fmt::Display for PlatformKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - PlatformKind::Build => write!(f, "build"), - PlatformKind::Host => write!(f, "host"), - PlatformKind::Target => write!(f, "target"), - } - } -} - pub fn convert_variant_from_pixi_build_types(variant: pixi_build_types::VariantValue) -> Variable { match variant { pixi_build_types::VariantValue::String(s) => Variable::from(s), @@ -75,15 +66,6 @@ pub fn convert_variant_to_pixi_build_types( pixi_build_types::VariantValue::deserialize(value) } -pub fn to_rattler_build_selector(selector: &TargetSelector, platform_kind: PlatformKind) -> String { - match selector { - TargetSelector::Platform(p) | TargetSelector::Subdir(p) => { - format!("{platform_kind}_platform == '{p}'") - } - _ => selector.to_string(), - } -} - /// Convert a `PackageDependency` to a `SerializableMatchSpec` for use in /// rattler-build's `Requirements`. fn package_dependency_to_matchspec(dep: PackageDependency) -> SerializableMatchSpec { @@ -98,126 +80,112 @@ fn package_dependency_to_item(dep: PackageDependency) -> Item Requirements { - let mut build_items = ConditionalList::default(); - let mut host_items = ConditionalList::default(); - let mut run_items = ConditionalList::default(); - let mut run_constraints_items = ConditionalList::default(); - let mut extras: BTreeMap> = BTreeMap::new(); +/// Accumulates the per-section requirement items while converting targets. +#[derive(Default)] +struct RequirementItems { + build: ConditionalList, + host: ConditionalList, + run: ConditionalList, + run_constraints: ConditionalList, + extras: BTreeMap>, +} - // Add default target - if let Some(default_target) = &targets.default_target { - let package_requirements = PackageSpecDependencies::from(default_target); +impl RequirementItems { + /// Add the dependencies of `target`, wrapping each one in `condition` when + /// one is given. + fn add_target(&mut self, target: &Target, condition: Option<&JinjaExpression>) { + let to_item = |dep: PackageDependency| -> Item { + let item = package_dependency_to_item(dep); + match condition { + Some(condition) => Item::Conditional(Conditional { + condition: condition.clone(), + then: NestedItemList::single(item), + else_value: None, + condition_span: None, + }), + None => item, + } + }; - build_items.extend( - package_requirements + let requirements = PackageSpecDependencies::from(target); + self.build.extend( + requirements .build .into_iter() .map(|spec| spec.1) - .map(package_dependency_to_item), + .map(to_item), ); - - host_items.extend( - package_requirements + self.host.extend( + requirements .host .into_iter() .map(|spec| spec.1) - .map(package_dependency_to_item), + .map(to_item), ); - - run_items.extend( - package_requirements - .run - .into_iter() - .map(|spec| spec.1) - .map(package_dependency_to_item), - ); - - run_constraints_items.extend( - package_requirements + self.run + .extend(requirements.run.into_iter().map(|spec| spec.1).map(to_item)); + self.run_constraints.extend( + requirements .run_constraints .into_iter() .map(|spec| spec.1) - .map(package_dependency_to_item), + .map(to_item), ); - if let Some(default_extras) = &default_target.extra_dependencies { - for (group, deps) in default_extras { + if let Some(target_extras) = &target.extra_dependencies { + for (group, deps) in target_extras { let items = package_specs_to_package_dependency(deps.clone()) .unwrap() .into_iter() - .map(package_dependency_to_item); - extras.entry(group.to_string()).or_default().extend(items); + .map(to_item); + self.extras + .entry(group.to_string()) + .or_default() + .extend(items); } } } +} - // Add specific targets - if let Some(specific_targets) = &targets.targets { - for (selector, target) in specific_targets { - let package_requirements = PackageSpecDependencies::from(target); - let selector_str = to_rattler_build_selector(selector, PlatformKind::Host); - - // Helper to wrap a dep in a conditional - let make_conditional = |dep: PackageDependency| -> Item { - Item::Conditional(Conditional { - condition: JinjaExpression::new(selector_str.clone()) - .expect("valid jinja expression"), - then: NestedItemList::single(package_dependency_to_item(dep)), - else_value: None, - condition_span: None, - }) - }; +pub fn from_targets_v1_to_conditional_requirements( + targets: &Targets, +) -> Result { + let mut items = RequirementItems::default(); - build_items.extend( - package_requirements - .build - .into_iter() - .map(|spec| spec.1) - .map(make_conditional), - ); - host_items.extend( - package_requirements - .host - .into_iter() - .map(|spec| spec.1) - .map(make_conditional), - ); - run_items.extend( - package_requirements - .run - .into_iter() - .map(|spec| spec.1) - .map(make_conditional), - ); - run_constraints_items.extend( - package_requirements - .run_constraints - .into_iter() - .map(|spec| spec.1) - .map(make_conditional), - ); - - if let Some(target_extras) = &target.extra_dependencies { - for (group, deps) in target_extras { - let items = package_specs_to_package_dependency(deps.clone()) - .unwrap() - .into_iter() - .map(&make_conditional); - extras.entry(group.to_string()).or_default().extend(items); + // Add default target + if let Some(default_target) = &targets.default_target { + items.add_target(default_target, None); + } + + // Add conditional `if(...)` targets. The expression is handed to + // rattler-build verbatim; pixi does not evaluate it. + if let Some(conditional_targets) = &targets.conditional { + for (expression, target) in conditional_targets { + let condition = JinjaExpression::new(expression.to_string()).map_err(|message| { + SelectorConversionError::InvalidExpression { + expression: expression.to_string(), + message, } - } + })?; + items.add_target(target, Some(&condition)); } } - Requirements { - build: build_items, - host: host_items, - run: run_items, - run_constraints: run_constraints_items, + let RequirementItems { + build, + host, + run, + run_constraints, + extras, + } = items; + Ok(Requirements { + build, + host, + run, + run_constraints, extras, ..Default::default() - } + }) } pub(crate) fn source_package_spec_to_package_dependency( @@ -510,6 +478,7 @@ pub fn from_build_v1_args_to_finalized_dependencies( #[cfg(test)] mod test { + use pixi_build_types::ConditionalExpression; use rattler_conda_types::ParseMatchSpecOptions; use super::*; @@ -608,9 +577,9 @@ mod test { extra_dependencies: Some(extras), ..Target::default() }), - targets: None, + conditional: None, }; - let requirements = from_targets_v1_to_conditional_requirements(&targets); + let requirements = from_targets_v1_to_conditional_requirements(&targets).unwrap(); let value = serde_json::to_value(&requirements.extras).unwrap(); assert_eq!( @@ -621,10 +590,84 @@ mod test { ); } - /// Per-target extras must be wrapped in a `Conditional` so the resulting - /// recipe only pulls them in for the matching platform selector. + /// A conditional `if(...)` dependency is wrapped in a `Conditional` carrying + /// the user's expression verbatim. + #[test] + fn test_conditional_expression_passthrough() { + let mut dependencies = OrderMap::new(); + dependencies.insert( + SourcePackageName::from(PackageName::new_unchecked("foo")), + BinaryPackageSpec { + version: Some("*".parse().unwrap()), + ..BinaryPackageSpec::default() + } + .into(), + ); + + let mut conditional = OrderMap::new(); + conditional.insert( + ConditionalExpression::new("host_platform != build_platform"), + Target { + build_dependencies: Some(dependencies), + ..Target::default() + }, + ); + let targets = Targets { + default_target: None, + conditional: Some(conditional), + }; + + let requirements = from_targets_v1_to_conditional_requirements(&targets).unwrap(); + + let value = serde_json::to_string(&requirements.build).unwrap(); + assert!( + value.contains("host_platform != build_platform"), + "conditional expression must be preserved verbatim: {value}" + ); + assert!( + value.contains("foo"), + "conditional dependency must be present: {value}" + ); + } + + /// A malformed user-supplied expression selector must surface as an error + /// rather than panicking inside `JinjaExpression::new`. + #[test] + fn test_invalid_expression_selector_errors_instead_of_panicking() { + let mut dependencies = OrderMap::new(); + dependencies.insert( + SourcePackageName::from(PackageName::new_unchecked("foo")), + BinaryPackageSpec { + version: Some("*".parse().unwrap()), + ..BinaryPackageSpec::default() + } + .into(), + ); + + let mut conditional = OrderMap::new(); + conditional.insert( + ConditionalExpression::new(")("), + Target { + build_dependencies: Some(dependencies), + ..Target::default() + }, + ); + let targets = Targets { + default_target: None, + conditional: Some(conditional), + }; + + let result = from_targets_v1_to_conditional_requirements(&targets); + assert!( + result.is_err(), + "a malformed selector expression must return an error, not panic" + ); + } + + /// Conditional extras must be wrapped in a `Conditional` so the resulting + /// recipe only pulls them in when the expression holds. #[test] - fn test_per_target_extras_conversion() { + fn test_conditional_extras_conversion() { let mut dependencies = OrderMap::new(); dependencies.insert( SourcePackageName::from(PackageName::new_unchecked("gtest")), @@ -641,9 +684,9 @@ mod test { dependencies, ); - let mut platform_targets = OrderMap::new(); - platform_targets.insert( - TargetSelector::Win, + let mut conditional = OrderMap::new(); + conditional.insert( + ConditionalExpression::new("win"), Target { extra_dependencies: Some(extras), ..Target::default() @@ -651,10 +694,10 @@ mod test { ); let targets = Targets { default_target: None, - targets: Some(platform_targets), + conditional: Some(conditional), }; - let requirements = from_targets_v1_to_conditional_requirements(&targets); + let requirements = from_targets_v1_to_conditional_requirements(&targets).unwrap(); let test_group = requirements .extras .get("test") @@ -665,7 +708,7 @@ mod test { .expect("group has at least one item"); assert!( matches!(first, Item::Conditional(_)), - "per-target extras must be wrapped in a Conditional, got: {first:?}", + "conditional extras must be wrapped in a Conditional, got: {first:?}", ); } @@ -741,22 +784,22 @@ mod test { /// Regression test: `from_targets_v1_to_conditional_requirements` must /// populate `Requirements.run_constraints` from both the default target and - /// platform-specific targets. The variable was being created and threaded + /// conditional targets. The variable was being created and threaded /// to the output but never extended. #[test] fn test_targets_v1_run_constraints_in_requirements() { // Default-target run-constraint plus a linux-64 specific one. - let mut targets_map = OrderMap::new(); - targets_map.insert( - TargetSelector::Platform("linux-64".to_string()), + let mut conditional_map = OrderMap::new(); + conditional_map.insert( + ConditionalExpression::new("host_platform == 'linux-64'"), target_with_only_run_constraints("linux-only", ">=2.0"), ); let targets = Targets { default_target: Some(target_with_only_run_constraints("everywhere", ">=1.0")), - targets: Some(targets_map), + conditional: Some(conditional_map), }; - let req = from_targets_v1_to_conditional_requirements(&targets); + let req = from_targets_v1_to_conditional_requirements(&targets).unwrap(); assert!(req.build.is_empty()); assert!(req.host.is_empty()); assert!(req.run.is_empty()); @@ -777,10 +820,10 @@ mod test { .expect("expected a concrete match spec"); assert_eq!(default_value.0.to_string(), "everywhere >=1.0"); - // Platform-specific target → wrapped in a Conditional. + // Conditional target → wrapped in a Conditional. let conditional = match items.next().unwrap() { Item::Conditional(c) => c, - Item::Value(_) => panic!("expected platform-specific constraint to be Conditional"), + Item::Value(_) => panic!("expected conditional constraint to be Conditional"), }; let then_item = conditional .then diff --git a/crates/pixi_build_backend/src/traits/project.rs b/crates/pixi_build_backend/src/traits/project.rs index 60c6460678..e50790dfb8 100644 --- a/crates/pixi_build_backend/src/traits/project.rs +++ b/crates/pixi_build_backend/src/traits/project.rs @@ -9,7 +9,7 @@ use std::collections::HashSet; use itertools::Itertools; use pixi_build_types::{self as pbt}; use rattler_build_types::NormalizedKey; -use rattler_conda_types::{Platform, Version}; +use rattler_conda_types::Version; use super::{Dependencies, PackageSpec, targets::Targets}; @@ -22,17 +22,12 @@ pub trait ProjectModel { fn targets(&self) -> Option<&Self::Targets>; /// Return the dependencies of the project model - fn dependencies( - &self, - platform: Option, - ) -> Dependencies<'_, <::Targets as Targets>::Spec> { - self.targets() - .map(|t| t.dependencies(platform)) - .unwrap_or_default() + fn dependencies(&self) -> Dependencies<'_, <::Targets as Targets>::Spec> { + self.targets().map(|t| t.dependencies()).unwrap_or_default() } /// Return the used variants of the project model - fn used_variants(&self, platform: Option) -> HashSet; + fn used_variants(&self) -> HashSet; /// Return the name of the project model fn name(&self) -> Option<&String>; @@ -56,23 +51,23 @@ impl ProjectModel for pbt::ProjectModel { &self.version } - fn used_variants(&self, platform: Option) -> HashSet { + fn used_variants(&self) -> HashSet { let build_dependencies = self .targets() .iter() - .flat_map(|target| target.build_dependencies(platform)) + .flat_map(|target| target.build_dependencies()) .collect_vec(); let host_dependencies = self .targets() .iter() - .flat_map(|target| target.host_dependencies(platform)) + .flat_map(|target| target.host_dependencies()) .collect_vec(); let run_dependencies = self .targets() .iter() - .flat_map(|target| target.run_dependencies(platform)) + .flat_map(|target| target.run_dependencies()) .collect_vec(); build_dependencies diff --git a/crates/pixi_build_backend/src/traits/targets.rs b/crates/pixi_build_backend/src/traits/targets.rs index 9fd501f735..2b4752ac6f 100644 --- a/crates/pixi_build_backend/src/traits/targets.rs +++ b/crates/pixi_build_backend/src/traits/targets.rs @@ -6,7 +6,7 @@ //! * [`TargetSelector`] - An extension trait that extends the target selector with additional functionality. //! * [`Dependencies`] - A wrapper struct that contains all dependencies for a target. use indexmap::IndexMap; -use itertools::{Either, Itertools}; +use itertools::Itertools; use pixi_build_types::SourcePackageName; use rattler_conda_types::Platform; @@ -81,9 +81,12 @@ impl<'a, S> Dependencies<'a, S> { } /// A trait that represent a project target. +/// +/// Dependencies are carried on the default target plus conditional +/// `if()` entries. The conditional entries are evaluated by +/// rattler-build, not here, so the dependency accessors expose the default +/// target only. pub trait Targets { - /// The selector, in pixi this is something like `[target.linux-64] - type Selector: TargetSelector; /// The target it is resolving to type Target; @@ -96,54 +99,20 @@ pub trait Targets { /// Return a spec that matches any version fn empty_spec() -> Self::Spec; - /// Returns all targets - fn targets(&self) -> impl Iterator; - - /// Return all dependencies for the given platform - fn dependencies(&self, platform: Option) -> Dependencies<'_, Self::Spec>; - - /// Return the run dependencies for the given platform - fn run_dependencies( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &Self::Spec>; - - /// Return the run constraints for the given platform - fn run_constraints( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &Self::Spec>; - - /// Return the host dependencies for the given platform - fn host_dependencies( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &Self::Spec>; - - /// Return the build dependencies for the given platform - fn build_dependencies( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &Self::Spec>; - - /// Resolve the target for the given platform. - fn resolve(&self, platform: Option) -> impl Iterator { - if let Some(platform) = platform { - let iter = self - .default_target() - .into_iter() - .chain(self.targets().filter_map(move |(selector, target)| { - if selector.matches(platform) { - Some(target) - } else { - None - } - })); - Either::Right(iter) - } else { - Either::Left(self.default_target().into_iter()) - } - } + /// Return all dependencies of the default target + fn dependencies(&self) -> Dependencies<'_, Self::Spec>; + + /// Return the run dependencies of the default target + fn run_dependencies(&self) -> IndexMap<&SourcePackageName, &Self::Spec>; + + /// Return the run constraints of the default target + fn run_constraints(&self) -> IndexMap<&SourcePackageName, &Self::Spec>; + + /// Return the host dependencies of the default target + fn host_dependencies(&self) -> IndexMap<&SourcePackageName, &Self::Spec>; + + /// Return the build dependencies of the default target + fn build_dependencies(&self) -> IndexMap<&SourcePackageName, &Self::Spec>; } // === Below here are the implementations for v1 === @@ -161,7 +130,6 @@ impl TargetSelector for pbt::TargetSelector { } impl Targets for pbt::Targets { - type Selector = pbt::TargetSelector; type Target = pbt::Target; type Spec = pbt::PackageSpec; @@ -170,71 +138,47 @@ impl Targets for pbt::Targets { self.default_target.as_ref() } - fn targets(&self) -> impl Iterator { - self.targets.iter().flatten() - } - fn empty_spec() -> pbt::PackageSpec { rattler_conda_types::VersionSpec::Any.into() } - fn run_dependencies( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { - let targets = self.resolve(platform).collect_vec(); - - targets - .iter() + fn run_dependencies(&self) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { + self.default_target() + .into_iter() .flat_map(|t| t.run_dependencies.iter()) .flatten() .collect::>() } - fn run_constraints( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { - let targets = self.resolve(platform).collect_vec(); - - targets - .iter() + fn run_constraints(&self) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { + self.default_target() + .into_iter() .flat_map(|t| t.run_constraints.iter()) .flatten() .collect::>() } - fn host_dependencies( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { - let targets = self.resolve(platform).collect_vec(); - - targets - .iter() + fn host_dependencies(&self) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { + self.default_target() + .into_iter() .flat_map(|t| t.host_dependencies.iter()) .flatten() .collect::>() } - fn build_dependencies( - &self, - platform: Option, - ) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { - let targets = self.resolve(platform).collect_vec(); - - targets - .iter() + fn build_dependencies(&self) -> IndexMap<&SourcePackageName, &pbt::PackageSpec> { + self.default_target() + .into_iter() .flat_map(|t| t.build_dependencies.iter()) .flatten() .collect::>() } - fn dependencies(&self, platform: Option) -> Dependencies<'_, Self::Spec> { - let build_deps = self.build_dependencies(platform); - let host_deps = self.host_dependencies(platform); - let run_deps = self.run_dependencies(platform); - let run_constraints = self.run_constraints(platform); + fn dependencies(&self) -> Dependencies<'_, Self::Spec> { + let build_deps = self.build_dependencies(); + let host_deps = self.host_dependencies(); + let run_deps = self.run_dependencies(); + let run_constraints = self.run_constraints(); Dependencies::new(run_deps, run_constraints, host_deps, build_deps) } diff --git a/crates/pixi_build_backend/tests/integration/common/model.rs b/crates/pixi_build_backend/tests/integration/common/model.rs index 4238785136..79253fefc0 100644 --- a/crates/pixi_build_backend/tests/integration/common/model.rs +++ b/crates/pixi_build_backend/tests/integration/common/model.rs @@ -1,8 +1,9 @@ /// This file contains the test model, which is a minimal example of a ProjectModel /// that can be used to create a ProjectModel from a JSON fixture file. use pixi_build_types::{ - BinaryPackageSpec as PbtBinaryPackageSpec, PackageSpec as PbtPackageSpec, PathSpec, - ProjectModel, Target as PbtTarget, TargetSelector as PbtTargetSelector, Targets as PbtTargets, + BinaryPackageSpec as PbtBinaryPackageSpec, ConditionalExpression, + PackageSpec as PbtPackageSpec, PathSpec, ProjectModel, Target as PbtTarget, + Targets as PbtTargets, }; use rattler_conda_types::{PackageName, ParseStrictness, Version, VersionSpec}; @@ -103,22 +104,22 @@ pub(crate) fn load_project_model_from_json(filename: &str) -> TestProjectModel { pub(crate) fn convert_test_model_to_project_model_v1(test_model: TestProjectModel) -> ProjectModel { use std::str::FromStr; - // Convert the targets + // Convert the targets. Selector targets lower to the equivalent + // conditional expression, mirroring what pixi does at parse time. + let conditional: ordermap::OrderMap = test_model + .targets + .targets + .into_iter() + .map(|(selector, target)| { + ( + target_selector_expression(selector), + convert_target_to_v1(&target), + ) + }) + .collect(); let targets_v1 = PbtTargets { default_target: Some(convert_target_to_v1(&test_model.targets.default_target)), - targets: Some( - test_model - .targets - .targets - .into_iter() - .map(|(selector, target)| { - ( - convert_target_selector_to_v1(selector), - convert_target_to_v1(&target), - ) - }) - .collect(), - ), + conditional: (!conditional.is_empty()).then_some(conditional), }; ProjectModel { @@ -216,15 +217,16 @@ fn convert_target_to_v1(target: &Target) -> PbtTarget { } } -/// Converts a test TargetSelector to TargetSelector -fn convert_target_selector_to_v1(selector: TargetSelector) -> PbtTargetSelector { - match selector { - TargetSelector::Unix => PbtTargetSelector::Unix, - TargetSelector::Linux => PbtTargetSelector::Linux, - TargetSelector::Win => PbtTargetSelector::Win, - TargetSelector::MacOs => PbtTargetSelector::MacOs, - TargetSelector::Platform(p) => PbtTargetSelector::Platform(p), - } +/// The conditional expression a test TargetSelector lowers to, mirroring the +/// lowering pixi performs at manifest parse time. +fn target_selector_expression(selector: TargetSelector) -> ConditionalExpression { + ConditionalExpression::new(match selector { + TargetSelector::Unix => "unix".to_string(), + TargetSelector::Linux => "linux".to_string(), + TargetSelector::Win => "win".to_string(), + TargetSelector::MacOs => "osx".to_string(), + TargetSelector::Platform(p) => format!("host_platform == '{p}'"), + }) } /// Converts a test PackageSpec to PackageSpec diff --git a/crates/pixi_build_backend/tests/integration/protocol.rs b/crates/pixi_build_backend/tests/integration/protocol.rs index 8e074e90a1..b349323051 100644 --- a/crates/pixi_build_backend/tests/integration/protocol.rs +++ b/crates/pixi_build_backend/tests/integration/protocol.rs @@ -8,8 +8,8 @@ use pixi_build_backend::{ utils::test::intermediate_conda_outputs, }; use pixi_build_types::{ - BinaryPackageSpec, ExtraGroupName, PackageSpec, PathSpec, ProjectModel, SourcePackageName, - Target, TargetSelector, Targets, + BinaryPackageSpec, ConditionalExpression, ExtraGroupName, PackageSpec, PathSpec, ProjectModel, + SourcePackageName, Target, Targets, procedures::conda_build_v1::{CondaBuildV1Output, CondaBuildV1Params}, }; use rattler_build_core::console_utils::LoggingOutputHandler; @@ -257,9 +257,9 @@ async fn test_conda_outputs_extra_dependencies() { let mut win_extras = OrderMap::new(); win_extras.insert(ExtraGroupName::new("gpu").unwrap(), gpu_group); - let mut platform_targets = OrderMap::new(); - platform_targets.insert( - TargetSelector::Win, + let mut conditional_targets = OrderMap::new(); + conditional_targets.insert( + ConditionalExpression::new("win"), Target { extra_dependencies: Some(win_extras), ..Target::default() @@ -274,7 +274,7 @@ async fn test_conda_outputs_extra_dependencies() { extra_dependencies: Some(default_extras), ..Target::default() }), - targets: Some(platform_targets), + conditional: Some(conditional_targets), }), ..ProjectModel::default() }; diff --git a/crates/pixi_build_backend_passthrough/src/lib.rs b/crates/pixi_build_backend_passthrough/src/lib.rs index 1d25612bb4..f2bac20979 100644 --- a/crates/pixi_build_backend_passthrough/src/lib.rs +++ b/crates/pixi_build_backend_passthrough/src/lib.rs @@ -20,7 +20,7 @@ use pixi_build_frontend::{ }; use pixi_build_types::{ BackendCapabilities, BinaryPackageSpec, ConstraintSpec, ExtraGroupName, NamedSpec, PackageSpec, - ProjectModel, SourcePackageName, Target, TargetSelector, Targets, VariantValue, + ProjectModel, SourcePackageName, Target, Targets, VariantValue, procedures::{ conda_build_v1::{CondaBuildV1Params, CondaBuildV1Result}, conda_outputs::{ @@ -310,6 +310,8 @@ fn generate_variant_outputs( package_run_exports: Option<&RunExportsJson>, config: &PassthroughBackendConfig, ) -> Vec { + reject_conditional_targets(project_model); + // Check if we have variant configurations and dependencies with "*" let variant_keys = find_variant_keys(project_model, params); @@ -400,24 +402,14 @@ fn find_variant_keys(project_model: &ProjectModel, params: &CondaOutputsParams) } }; - // Check default target + // Check default target. Conditional targets are rejected by + // `reject_conditional_targets` before this point. if let Some(default_target) = &targets.default_target { check_deps(default_target.build_dependencies.as_ref()); check_deps(default_target.host_dependencies.as_ref()); check_deps(default_target.run_dependencies.as_ref()); } - // Check platform-specific targets - if let Some(targets_map) = &targets.targets { - for (selector, target) in targets_map { - if matches_target_selector(selector, params.host_platform) { - check_deps(target.build_dependencies.as_ref()); - check_deps(target.host_dependencies.as_ref()); - check_deps(target.run_dependencies.as_ref()); - } - } - } - variant_keys.into_iter().collect() } @@ -566,7 +558,6 @@ fn create_output( let mut run_dependencies = extract_dependencies( &project_model.targets, |t| t.run_dependencies.as_ref(), - params.host_platform, &variant, ); @@ -574,7 +565,6 @@ fn create_output( let host_deps = extract_dependencies( &project_model.targets, |t| t.host_dependencies.as_ref(), - params.host_platform, &variant, ); @@ -596,9 +586,7 @@ fn create_output( // Extra groups come from the project model, and - // when the backend was handed a pre-built package - from its index.json. let mut extra_dependencies = convert_extra_depends(&index_json.experimental_extra_depends); - for (group, specs) in - extract_extra_dependencies(&project_model.targets, params.host_platform, &variant) - { + for (group, specs) in extract_extra_dependencies(&project_model.targets, &variant) { extra_dependencies.entry(group).or_default().extend(specs); } @@ -606,7 +594,6 @@ fn create_output( build_dependencies: Some(extract_dependencies( &project_model.targets, |t| t.build_dependencies.as_ref(), - params.host_platform, &variant, )), host_dependencies: Some(host_deps), @@ -648,10 +635,9 @@ fn create_output( fn extract_dependencies Option<&OrderMap>>( targets: &Option, extract: F, - platform: Platform, variant: &BTreeMap, ) -> CondaOutputDependencies { - let depends = applicable_targets(targets, platform) + let depends = applicable_targets(targets) .into_iter() .flat_map(|target| extract(target).into_iter().flat_map(OrderMap::iter)) .map(|(name, spec)| NamedSpec { @@ -666,25 +652,12 @@ fn extract_dependencies Option<&OrderMap, platform: Platform) -> Vec<&Target> { +/// Returns the default target. Conditional targets are rejected by +/// `reject_conditional_targets` before this point. +fn applicable_targets(targets: &Option) -> Vec<&Target> { targets .iter() - .flat_map(|targets| { - targets - .default_target - .iter() - .chain( - targets - .targets - .iter() - .flatten() - .flat_map(move |(selector, target)| { - matches_target_selector(selector, platform).then_some(target) - }), - ) - }) + .flat_map(|targets| targets.default_target.iter()) .collect() } @@ -715,15 +688,13 @@ fn resolve_dependency_spec( } /// Extracts the extra groups declared by the project -/// model for the given platform, mirroring how `extract_dependencies` walks -/// targets. Groups declared across multiple matching targets are merged. +/// model, mirroring how `extract_dependencies` walks targets. fn extract_extra_dependencies( targets: &Option, - platform: Platform, variant: &BTreeMap, ) -> BTreeMap>> { let mut result: BTreeMap>> = BTreeMap::new(); - for target in applicable_targets(targets, platform) { + for target in applicable_targets(targets) { let Some(extras) = target.extra_dependencies.as_ref() else { continue; }; @@ -896,16 +867,15 @@ fn convert_run_exports_json( } } -/// Returns true if the given [`TargetSelector`] matches the specified -/// `platform`. -fn matches_target_selector(selector: &TargetSelector, platform: Platform) -> bool { - match selector { - TargetSelector::Unix => platform.is_unix(), - TargetSelector::Linux => platform.is_linux(), - TargetSelector::Win => platform.is_windows(), - TargetSelector::MacOs => platform.is_osx(), - TargetSelector::Platform(target_platform) => target_platform == platform.as_str(), - TargetSelector::Subdir(subdir) => subdir == platform.as_str(), +/// The passthrough backend has no jinja evaluator and therefore cannot decide +/// whether an `if(...)` conditional applies. Panic rather than silently dropping +/// the conditional dependencies; a real backend evaluates these via +/// rattler-build. +fn reject_conditional_targets(project_model: &ProjectModel) { + if let Some(targets) = &project_model.targets + && targets.conditional.as_ref().is_some_and(|c| !c.is_empty()) + { + unimplemented!("passthrough backend cannot evaluate if(...) conditional dependencies") } } @@ -1202,7 +1172,7 @@ where #[cfg(test)] mod tests { - use pixi_build_types::{BinaryPackageSpec, PackageSpec}; + use pixi_build_types::{BinaryPackageSpec, ConditionalExpression, PackageSpec}; use rattler_conda_types::{ParseStrictness, VersionSpec}; use super::*; @@ -1236,6 +1206,27 @@ mod tests { assert!(is_star_requirement(&spec)); } + #[test] + #[should_panic(expected = "passthrough backend cannot evaluate if(")] + fn test_passthrough_rejects_conditional_dependencies() { + // The passthrough backend has no jinja evaluator, so conditional + // `if(...)` dependencies must fail loudly rather than being silently + // dropped. + let mut conditional = OrderMap::new(); + conditional.insert( + ConditionalExpression::new("host_platform != build_platform"), + Target::default(), + ); + let project_model = ProjectModel { + targets: Some(Targets { + conditional: Some(conditional), + ..Targets::default() + }), + ..ProjectModel::default() + }; + reject_conditional_targets(&project_model); + } + #[test] fn test_generate_variant_combinations_empty() { let variants = generate_variant_combinations(&[]); diff --git a/crates/pixi_build_cmake/src/main.rs b/crates/pixi_build_cmake/src/main.rs index 01fd937f3c..0db3b0ac8d 100644 --- a/crates/pixi_build_cmake/src/main.rs +++ b/crates/pixi_build_cmake/src/main.rs @@ -91,7 +91,7 @@ impl GenerateRecipe for CMakeGenerator { // This properly handles target selectors like [target.linux-64] by using // the ProjectModel trait's platform-aware API instead of trying to evaluate // rattler-build selectors with simple string comparison. - let model_dependencies = model.dependencies(Some(host_platform)); + let model_dependencies = model.dependencies(); // Get the list of compilers from config, defaulting to ["cxx"] if not specified let compilers = config diff --git a/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@inherit__nested.snap b/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@inherit__nested.snap index ffda773c76..cf33769305 100644 --- a/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@inherit__nested.snap +++ b/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@inherit__nested.snap @@ -38,6 +38,5 @@ init-params: buildDependencies: {} runDependencies: {} runConstraints: {} - targets: {} configuration: ~ target-configuration: ~ diff --git a/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@nested__nested.snap b/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@nested__nested.snap index a16ba2c6ab..d1f81a9d53 100644 --- a/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@nested__nested.snap +++ b/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@nested__nested.snap @@ -38,6 +38,5 @@ init-params: buildDependencies: {} runDependencies: {} runConstraints: {} - targets: {} configuration: ~ target-configuration: ~ diff --git a/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@simple.snap b/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@simple.snap index 711a652cec..c0bc63d796 100644 --- a/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@simple.snap +++ b/crates/pixi_build_discovery/tests/snapshots/discovery__discovery@simple.snap @@ -38,6 +38,5 @@ init-params: buildDependencies: {} runDependencies: {} runConstraints: {} - targets: {} configuration: ~ target-configuration: ~ diff --git a/crates/pixi_build_mojo/src/main.rs b/crates/pixi_build_mojo/src/main.rs index 0a407bfb22..8f65ead640 100644 --- a/crates/pixi_build_mojo/src/main.rs +++ b/crates/pixi_build_mojo/src/main.rs @@ -82,7 +82,7 @@ impl GenerateRecipe for MojoGenerator { // This properly handles target selectors like [target.linux-64] by using // the ProjectModel trait's platform-aware API instead of trying to evaluate // rattler-build selectors with simple string comparison. - let model_dependencies = model.dependencies(Some(host_platform)); + let model_dependencies = model.dependencies(); let compilers = config.compilers.clone().unwrap_or_default(); diff --git a/crates/pixi_build_python/src/main.rs b/crates/pixi_build_python/src/main.rs index c5f060c150..533679bae7 100644 --- a/crates/pixi_build_python/src/main.rs +++ b/crates/pixi_build_python/src/main.rs @@ -171,7 +171,7 @@ impl GenerateRecipe for PythonGenerator { // This properly handles target selectors like [target.linux-64] by using // the ProjectModel trait's platform-aware API instead of trying to evaluate // rattler-build selectors with simple string comparison. - let model_dependencies = model.dependencies(Some(host_platform)); + let model_dependencies = model.dependencies(); let cython_pkg = pixi_build_types::SourcePackageName::from( rattler_conda_types::PackageName::new_unchecked("cython"), ); diff --git a/crates/pixi_build_r/src/main.rs b/crates/pixi_build_r/src/main.rs index 15afa48204..10d6b16a64 100644 --- a/crates/pixi_build_r/src/main.rs +++ b/crates/pixi_build_r/src/main.rs @@ -97,7 +97,7 @@ impl GenerateRecipe for RGenerator { GeneratedRecipe::from_model(model.clone(), &mut metadata_provider).into_diagnostic()?; let requirements = &mut generated_recipe.recipe.requirements; - let model_dependencies = model.dependencies(Some(host_platform)); + let model_dependencies = model.dependencies(); // Auto-detect or use configured compilers let compilers = match &config.compilers { diff --git a/crates/pixi_build_rattler_build/src/protocol.rs b/crates/pixi_build_rattler_build/src/protocol.rs index b9433e98b2..3939132e70 100644 --- a/crates/pixi_build_rattler_build/src/protocol.rs +++ b/crates/pixi_build_rattler_build/src/protocol.rs @@ -707,8 +707,8 @@ impl ProtocolInstantiator for RattlerBuildBackendInstantiator { extract_workspace_deps(default_target, &mut workspace_dependencies)?; } - if let Some(targets) = target.targets { - for (_, target) in targets { + if let Some(conditional) = target.conditional { + for (_, target) in conditional { extract_workspace_deps(target, &mut workspace_dependencies)?; } } diff --git a/crates/pixi_build_rust/src/main.rs b/crates/pixi_build_rust/src/main.rs index 2714acbf83..3ca3119912 100644 --- a/crates/pixi_build_rust/src/main.rs +++ b/crates/pixi_build_rust/src/main.rs @@ -80,7 +80,7 @@ impl GenerateRecipe for RustGenerator { // This properly handles target selectors like [target.linux-64] by using // the ProjectModel trait's platform-aware API instead of trying to evaluate // rattler-build selectors with simple string comparison. - let model_dependencies = model.dependencies(Some(host_platform)); + let model_dependencies = model.dependencies(); // Get the list of compilers from config, defaulting to ["rust", "c"] if not // specified. The rust compilers already depend on the c compiler. @@ -853,8 +853,8 @@ mod tests { "name": "foobar", "version": "0.1.0", "targets": { - "targets": { - "linux-64": { + "conditional": { + "host_platform == 'linux-64'": { "buildDependencies": { "openssl": { "binary": { @@ -867,26 +867,16 @@ mod tests { } }); - // Test that the ProjectModel correctly filters dependencies for Linux64 - let linux_deps = project_model.dependencies(Some(Platform::Linux64)); + // Conditional dependencies are not part of the default target; they are + // evaluated by rattler-build, not the backend. + let default_deps = project_model.dependencies(); assert!( - linux_deps + !default_deps .build .contains_key(&pixi_build_types::SourcePackageName::from( PackageName::new_unchecked("openssl") )), - "openssl should be in build dependencies for Linux64" - ); - - // Test that the ProjectModel correctly excludes dependencies for Osx64 - let osx_deps = project_model.dependencies(Some(Platform::Osx64)); - assert!( - !osx_deps - .build - .contains_key(&pixi_build_types::SourcePackageName::from( - PackageName::new_unchecked("openssl") - )), - "openssl should NOT be in build dependencies for Osx64" + "openssl should NOT be in the default build dependencies" ); // Test that the intermediate recipe contains the conditional items with correct condition @@ -950,7 +940,7 @@ mod tests { "name": "foobar", "version": "0.1.0", "targets": { - "targets": { + "conditional": { "unix": { "buildDependencies": { "gcc": { @@ -964,37 +954,16 @@ mod tests { } }); - // Test that the ProjectModel correctly filters dependencies for Linux64 (unix) - let linux_deps = project_model.dependencies(Some(Platform::Linux64)); - assert!( - linux_deps - .build - .contains_key(&pixi_build_types::SourcePackageName::from( - PackageName::new_unchecked("gcc") - )), - "gcc should be in build dependencies for Linux64 (unix)" - ); - - // Test that the ProjectModel correctly filters dependencies for Osx64 (unix) - let osx_deps = project_model.dependencies(Some(Platform::Osx64)); - assert!( - osx_deps - .build - .contains_key(&pixi_build_types::SourcePackageName::from( - PackageName::new_unchecked("gcc") - )), - "gcc should be in build dependencies for Osx64 (unix)" - ); - - // Test that the ProjectModel correctly excludes dependencies for Win64 (not unix) - let win_deps = project_model.dependencies(Some(Platform::Win64)); + // Conditional dependencies are not part of the default target; they are + // evaluated by rattler-build, not the backend. + let default_deps = project_model.dependencies(); assert!( - !win_deps + !default_deps .build .contains_key(&pixi_build_types::SourcePackageName::from( PackageName::new_unchecked("gcc") )), - "gcc should NOT be in build dependencies for Win64 (not unix)" + "gcc should NOT be in the default build dependencies" ); // Test that the intermediate recipe contains the conditional items with correct condition diff --git a/crates/pixi_build_type_conversions/src/project_model.rs b/crates/pixi_build_type_conversions/src/project_model.rs index 968622b978..7c48447656 100644 --- a/crates/pixi_build_type_conversions/src/project_model.rs +++ b/crates/pixi_build_type_conversions/src/project_model.rs @@ -11,7 +11,7 @@ use ordermap::OrderMap; // different types use pixi_build_types::{self as pbt}; -use pixi_manifest::{PackageManifest, PackageTarget, TargetSelector, Targets}; +use pixi_manifest::{PackageManifest, PackageTarget, TargetSelector}; use pixi_spec::{GitReference, MatchspecFields, PixiSpec, SourceLocationSpec, SpecConversionError}; use rattler_conda_types::{ChannelConfig, NamelessMatchSpec, PackageName}; @@ -197,6 +197,9 @@ fn to_target_v1( }) } +/// Converts a manifest [`TargetSelector`] to its wire form. Only used for the +/// per-target backend configuration (`[package.build.target.]`); +/// dependencies carry conditional expressions instead. pub fn to_target_selector_v1(selector: &TargetSelector) -> pbt::TargetSelector { match selector { TargetSelector::Platform(platform) => pbt::TargetSelector::Platform(platform.to_string()), @@ -209,22 +212,24 @@ pub fn to_target_selector_v1(selector: &TargetSelector) -> pbt::TargetSelector { } fn to_targets_v1( - targets: &Targets, + manifest: &PackageManifest, channel_config: &ChannelConfig, ) -> Result { - let selected_targets = targets + // Conditional `if(...)` dependencies are not platform selectors; they are + // carried separately and passed through to rattler-build, which evaluates + // the expression. The deprecated `[package.target.*]` tables are already + // lowered into conditional dependencies at parse time. + let conditional = manifest + .conditional_dependencies .iter() - .filter_map(|(k, v)| { - v.map(|selector| { - to_target_v1(k, channel_config) - .map(|target| (to_target_selector_v1(selector), target)) - }) + .map(|(expression, target)| { + to_target_v1(target, channel_config).map(|target| (expression.clone(), target)) }) - .collect::, _>>()?; + .collect::, _>>()?; Ok(pbt::Targets { - default_target: Some(to_target_v1(targets.default(), channel_config)?), - targets: Some(selected_targets), + default_target: Some(to_target_v1(&manifest.dependencies, channel_config)?), + conditional: (!conditional.is_empty()).then_some(conditional), }) } @@ -247,7 +252,7 @@ pub fn to_project_model_v1( homepage: manifest.package.homepage.clone(), repository: manifest.package.repository.clone(), documentation: manifest.package.documentation.clone(), - targets: Some(to_targets_v1(&manifest.targets, channel_config)?), + targets: Some(to_targets_v1(manifest, channel_config)?), secrets: manifest.build.secrets.clone(), }; Ok(project) diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@advanced_cpp.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@advanced_cpp.snap index 2a3f626303..b2c194e8f2 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@advanced_cpp.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@advanced_cpp.snap @@ -1,5 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs +assertion_line: 327 expression: project_model --- { @@ -21,7 +22,6 @@ expression: project_model "buildDependencies": {}, "runDependencies": {}, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@cpp.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@cpp.snap index 6c205d30c6..a157ded921 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@cpp.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@cpp.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 324 +assertion_line: 327 expression: project_model --- { @@ -74,7 +74,6 @@ expression: project_model "buildDependencies": {}, "runDependencies": {}, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@dev.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@dev.snap index f519296107..b06c5de3e2 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@dev.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@dev.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 324 +assertion_line: 327 expression: project_model --- { @@ -76,7 +76,6 @@ expression: project_model } }, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@getting_started.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@getting_started.snap index c78f045c0b..6042fe857f 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@getting_started.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@getting_started.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 324 +assertion_line: 327 expression: project_model --- { @@ -58,7 +58,6 @@ expression: project_model } }, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@python.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@python.snap index f74d310972..95d9c1bd8e 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@python.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@python.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 324 +assertion_line: 327 expression: project_model --- { @@ -58,7 +58,6 @@ expression: project_model } }, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace.snap index e950e27753..a8a65b9b06 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 324 +assertion_line: 327 expression: project_model --- { @@ -70,7 +70,6 @@ expression: project_model } }, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace_variants.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace_variants.snap index 84f28a194a..234b84177e 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace_variants.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_docs@workspace_variants.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 324 +assertion_line: 327 expression: project_model --- { @@ -87,7 +87,6 @@ expression: project_model } }, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@array-api-extra.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@array-api-extra.snap index 91c124dae9..3ee90ed35f 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@array-api-extra.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@array-api-extra.snap @@ -1,5 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs +assertion_line: 318 expression: project_model --- { @@ -21,7 +22,6 @@ expression: project_model "buildDependencies": {}, "runDependencies": {}, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@conditional-dependencies.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@conditional-dependencies.snap new file mode 100644 index 0000000000..8159b588b7 --- /dev/null +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@conditional-dependencies.snap @@ -0,0 +1,70 @@ +--- +source: crates/pixi_build_type_conversions/src/project_model.rs +assertion_line: 318 +expression: project_model +--- +{ + "name": "cuda_probe", + "buildStringPrefix": null, + "buildNumber": null, + "version": "0.1.0", + "description": "A C++ executable that demonstrates if(...) conditional dependencies", + "authors": null, + "license": null, + "licenseFile": null, + "readme": null, + "homepage": null, + "repository": null, + "documentation": null, + "targets": { + "defaultTarget": { + "hostDependencies": {}, + "buildDependencies": {}, + "runDependencies": {}, + "runConstraints": {} + }, + "conditional": { + "linux or win": { + "hostDependencies": {}, + "buildDependencies": {}, + "runDependencies": { + "cuda-nvcc": { + "binary": { + "version": "12.*", + "build": null, + "buildNumber": null, + "fileName": null, + "extras": null, + "flags": null, + "channel": null, + "subdir": null, + "md5": null, + "sha256": null, + "url": null, + "license": null, + "condition": null + } + }, + "cuda-version": { + "binary": { + "version": "12.*", + "build": null, + "buildNumber": null, + "fileName": null, + "extras": null, + "flags": null, + "channel": null, + "subdir": null, + "md5": null, + "sha256": null, + "url": null, + "license": null, + "condition": null + } + } + }, + "runConstraints": {} + } + } + } +} diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-git-source.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-git-source.snap index 6005f84642..7b1de8f74b 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-git-source.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-git-source.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 315 +assertion_line: 318 expression: project_model --- { @@ -40,7 +40,6 @@ expression: project_model "buildDependencies": {}, "runDependencies": {}, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-sdl.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-sdl.snap index a55de22958..686c33d6fa 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-sdl.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@cpp-sdl.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 315 +assertion_line: 318 expression: project_model --- { @@ -42,7 +42,6 @@ expression: project_model "buildDependencies": {}, "runDependencies": {}, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@dev.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@dev.snap index f444120f28..d7c4300f4d 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@dev.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@dev.snap @@ -1,6 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs -assertion_line: 315 +assertion_line: 318 expression: project_model --- { @@ -93,7 +93,6 @@ expression: project_model } }, "runConstraints": {} - }, - "targets": {} + } } } diff --git a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@v3.snap b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@v3.snap index eb2ceeaf7b..f05667a9fb 100644 --- a/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@v3.snap +++ b/crates/pixi_build_type_conversions/src/snapshots/pixi_build_type_conversions__project_model__tests__conversions_v1_examples@v3.snap @@ -1,5 +1,6 @@ --- source: crates/pixi_build_type_conversions/src/project_model.rs +assertion_line: 318 expression: project_model --- { @@ -87,7 +88,6 @@ expression: project_model } } } - }, - "targets": {} + } } } diff --git a/crates/pixi_build_types/src/lib.rs b/crates/pixi_build_types/src/lib.rs index 6d6abede38..81cabd1980 100644 --- a/crates/pixi_build_types/src/lib.rs +++ b/crates/pixi_build_types/src/lib.rs @@ -16,9 +16,10 @@ pub use conda_package_metadata::CondaPackageMetadata; pub use extra_group_name::{ExtraGroupName, InvalidExtraGroupName, MAX_EXTRA_GROUP_NAME_LEN}; pub use input_glob_set::InputGlobSet; pub use project_model::{ - BinaryPackageSpec, ConstraintSpec, GitReference, GitSpec, NamedSpec, PackageSpec, PathSpec, - PinBound, PinCompatibleSpec, PinExpression, ProjectModel, SourcePackageLocationSpec, - SourcePackageName, SourcePackageSpec, Target, TargetSelector, Targets, UrlSpec, + BinaryPackageSpec, ConditionalExpression, ConstraintSpec, GitReference, GitSpec, NamedSpec, + PackageSpec, PathSpec, PinBound, PinCompatibleSpec, PinExpression, ProjectModel, + SourcePackageLocationSpec, SourcePackageName, SourcePackageSpec, Target, TargetSelector, + Targets, UrlSpec, }; use rattler_conda_types::{ GenericVirtualPackage, PackageName, Platform, Version, VersionSpec, @@ -32,7 +33,10 @@ pub use variant::VariantValue; // Version 2: Name in project models can be `None`. // Version 3: Outputs with the same name must have unique variants. // Version 4: (BREAKING) Add matchspec fields to source record, cleanup types, remove version from project model and streamline use of directory vs dir. -// Version 5: (BREAKING) Serialize match specs in `conda/build_v1` as structured objects instead of strings and add extra dependency groups. +// Version 5: (BREAKING) Serialize match specs in `conda/build_v1` as +// structured objects instead of strings, add extra dependency groups, +// and add `if()` target selectors that are passed through +// to rattler-build. Older backends would silently mishandle them. /// The constraint for the pixi build api version package /// Adding this constraint when solving a pixi build backend environment ensures diff --git a/crates/pixi_build_types/src/project_model.rs b/crates/pixi_build_types/src/project_model.rs index 8f574fd700..20fce7ddfe 100644 --- a/crates/pixi_build_types/src/project_model.rs +++ b/crates/pixi_build_types/src/project_model.rs @@ -91,8 +91,49 @@ impl IsDefault for ProjectModel { } } -/// Represents a target selector. Currently, we only support explicit platform -/// selection. +/// A free-form conditional selector expression that is passed through to +/// rattler-build, e.g. `host_platform == build_platform`. This is the bare +/// inner text of an `if()` selector key, without the wrapper. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +#[serde(transparent)] +pub struct ConditionalExpression(String); + +impl ConditionalExpression { + /// Creates a new conditional expression from its bare inner text. + pub fn new(expression: impl Into) -> Self { + Self(expression.into()) + } + + /// Returns the bare inner expression without the `if(...)` wrapper. + pub fn as_str(&self) -> &str { + &self.0 + } + + /// Consumes the expression and returns the inner string. + pub fn into_inner(self) -> String { + self.0 + } +} + +impl Display for ConditionalExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl From for ConditionalExpression { + fn from(value: String) -> Self { + Self(value) + } +} + +/// Represents a platform-based target selector. +/// +/// Dependencies no longer use platform selectors; they are carried as +/// conditional `if()` entries in [`Targets::conditional`]. This +/// type only keys the per-target backend configuration +/// (`[package.build.target.]`) in the initialize request. #[derive(Debug, Clone, DeserializeFromStr, SerializeDisplay, Eq, PartialEq)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TargetSelector { @@ -103,7 +144,6 @@ pub enum TargetSelector { MacOs, Subdir(String), Platform(String), - // TODO: Add minijinja coolness here. } impl Display for TargetSelector { @@ -140,20 +180,48 @@ impl FromStr for TargetSelector { } } +impl Hash for TargetSelector { + /// Custom hash implementation that uses discriminant values to keep the + /// hash as stable as possible when adding new enum variants. + fn hash(&self, state: &mut H) { + match self { + TargetSelector::Unix => 0u8.hash(state), + TargetSelector::Linux => 1u8.hash(state), + TargetSelector::Win => 2u8.hash(state), + TargetSelector::MacOs => 3u8.hash(state), + TargetSelector::Subdir(s) => { + 4u8.hash(state); + s.hash(state); + } + TargetSelector::Platform(p) => { + 5u8.hash(state); + p.hash(state); + } + } + } +} + /// A collect of targets including a default target. +/// +/// Platform-specific dependencies are carried exclusively as conditional +/// `if()` entries; the frontend lowers the deprecated +/// `[package.target.]` tables to the equivalent expression before +/// sending the project model. #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[serde(rename_all = "camelCase")] pub struct Targets { pub default_target: Option, - /// We use an [`OrderMap`] to preserve the order in which the items where - /// defined in the manifest. + /// Conditional `if()` dependencies. The expression is passed + /// through to rattler-build, which evaluates it; pixi does not. Keyed by the + /// bare inner expression without the `if(...)` wrapper. + #[serde(default, skip_serializing_if = "Option::is_none")] #[cfg_attr( feature = "schemars", - schemars(with = "Option>") + schemars(with = "Option>") )] - pub targets: Option>, + pub conditional: Option>, } impl Targets { @@ -162,9 +230,9 @@ impl Targets { pub fn is_empty(&self) -> bool { let has_meaningless_default_target = self.default_target.as_ref().is_none_or(|t| t.is_empty()); - let has_only_empty_targets = self.targets.as_ref().is_none_or(|t| t.is_empty()); + let has_only_empty_conditional = self.conditional.as_ref().is_none_or(|t| t.is_empty()); - has_meaningless_default_target && has_only_empty_targets + has_meaningless_default_target && has_only_empty_conditional } } @@ -649,27 +717,6 @@ impl Hash for ProjectModel { } } -impl Hash for TargetSelector { - /// Custom hash implementation that uses discriminant values to keep the - /// hash as stable as possible when adding new enum variants. - fn hash(&self, state: &mut H) { - match self { - TargetSelector::Unix => 0u8.hash(state), - TargetSelector::Linux => 1u8.hash(state), - TargetSelector::Win => 2u8.hash(state), - TargetSelector::MacOs => 3u8.hash(state), - TargetSelector::Subdir(s) => { - 4u8.hash(state); - s.hash(state); - } - TargetSelector::Platform(p) => { - 5u8.hash(state); - p.hash(state); - } - } - } -} - impl Hash for Targets { /// Custom hash implementation using StableHashBuilder to ensure different /// field configurations produce different hashes while maintaining @@ -677,12 +724,12 @@ impl Hash for Targets { fn hash(&self, state: &mut H) { let Targets { default_target, - targets, + conditional, } = self; StableHashBuilder::::new() .field("default_target", default_target) - .field("targets", targets) + .field("conditional", conditional) .finish(state); } } @@ -943,6 +990,15 @@ mod tests { hasher.finish() } + #[test] + fn test_conditional_expression_roundtrip() { + // A conditional expression carries its bare inner text and displays it + // verbatim. + let expression = ConditionalExpression::new("host_platform == build_platform"); + assert_eq!(expression.to_string(), "host_platform == build_platform"); + assert_eq!(expression.as_str(), "host_platform == build_platform"); + } + #[test] fn test_hash_stability_with_default_values() { // Create a minimal ProjectModelV1 instance @@ -971,7 +1027,7 @@ mod tests { // non-default/non-empty values project_model.targets = Some(Targets { default_target: None, - targets: Some(OrderMap::new()), + conditional: Some(OrderMap::new()), }); let hash2 = calculate_hash(&project_model); @@ -985,7 +1041,7 @@ mod tests { }; project_model.targets = Some(Targets { default_target: Some(empty_target), - targets: Some(OrderMap::new()), + conditional: Some(OrderMap::new()), }); let hash3 = calculate_hash(&project_model); @@ -1048,7 +1104,7 @@ mod tests { }; project_model.targets = Some(Targets { default_target: Some(target_with_deps), - targets: Some(OrderMap::new()), + conditional: Some(OrderMap::new()), }); let hash3 = calculate_hash(&project_model); @@ -1165,7 +1221,7 @@ mod tests { fn serialize_targets_v1_with_default_target() { let targets = Targets { default_target: Some(create_sample_target_v1()), - targets: None, + conditional: None, }; let serialized = serde_json::to_string(&targets).unwrap(); @@ -1174,33 +1230,19 @@ mod tests { } #[test] - fn serialize_targets_v1_with_multiple_targets() { - let platform_strs = [ - "unix", - "win", - "macos", - "linux-64", - "linux-arm64", - "linux-ppc64le", - "osx-64", - "osx-arm64", - "win-64", - "win-arm64", - ]; + fn serialize_targets_v1_with_conditional_targets() { + let expressions = ["unix", "win", "osx", "host_platform == 'linux-64'"]; let targets = Targets { default_target: None, - targets: Some( - platform_strs + conditional: Some( + expressions .iter() - .map(|s| { - let selector = match *s { - "unix" => TargetSelector::Unix, - "win" => TargetSelector::Win, - "macos" => TargetSelector::MacOs, - other => TargetSelector::Platform(other.to_string()), - }; - (selector, create_sample_target_v1()) + .map(|expression| { + ( + ConditionalExpression::new(*expression), + create_sample_target_v1(), + ) }) .collect(), ), @@ -1208,21 +1250,20 @@ mod tests { let serialized = serde_json::to_string(&targets).unwrap(); - for platform in platform_strs { - assert!(serialized.contains(platform), "Missing: {platform}"); + for expression in expressions { + assert!(serialized.contains(expression), "Missing: {expression}"); } } #[test] fn deserialize_targets_v1_with_empty_fields() { let json = r#"{ - "defaultTarget": null, - "targets": null + "defaultTarget": null }"#; let deserialized: Targets = serde_json::from_str(json).unwrap(); assert!(deserialized.default_target.is_none()); - assert!(deserialized.targets.is_none()); + assert!(deserialized.conditional.is_none()); } #[test] @@ -1237,7 +1278,7 @@ mod tests { "buildDependencies": null, "runDependencies": null }, - "targets": { + "conditional": { "unix": { "hostDependencies": null, "buildDependencies": null, @@ -1248,12 +1289,11 @@ mod tests { let deserialized: Targets = serde_json::from_str(json).unwrap(); assert!(deserialized.default_target.is_some()); - assert!(deserialized.targets.is_some()); assert!( deserialized - .targets + .conditional .unwrap() - .contains_key(&TargetSelector::Unix) + .contains_key(&ConditionalExpression::new("unix")) ); } @@ -1368,12 +1408,12 @@ mod tests { // Test with TargetsV1 as well let targets1 = Targets { default_target: Some(target1), - targets: None, + conditional: None, }; let targets2 = Targets { default_target: Some(target2), - targets: None, + conditional: None, }; let targets_hash1 = calculate_hash(&targets1); diff --git a/crates/pixi_manifest/src/manifests/package.rs b/crates/pixi_manifest/src/manifests/package.rs index 2b606d56d8..1e8e9d94a4 100644 --- a/crates/pixi_manifest/src/manifests/package.rs +++ b/crates/pixi_manifest/src/manifests/package.rs @@ -1,5 +1,8 @@ +use indexmap::IndexMap; +use pixi_build_types::ConditionalExpression; + use crate::target::PackageTarget; -use crate::{PackageBuild, Targets, package::Package}; +use crate::{PackageBuild, package::Package}; /// Holds the parsed content of the package part of a pixi manifest. This /// describes the part related to the package only. @@ -11,6 +14,13 @@ pub struct PackageManifest { /// Information about the build system for the package pub build: PackageBuild, - /// Defines the dependencies of the package - pub targets: Targets, + /// The unconditional dependencies of the package. + pub dependencies: PackageTarget, + + /// Dependencies guarded by an `if()` conditional. These are not + /// platform selectors; the expression is passed through to rattler-build, + /// which decides whether the dependencies apply. The deprecated + /// `[package.target.]` tables are lowered into entries of this + /// map at parse time. + pub conditional_dependencies: IndexMap, } diff --git a/crates/pixi_manifest/src/target.rs b/crates/pixi_manifest/src/target.rs index 090642413a..aec952abdb 100644 --- a/crates/pixi_manifest/src/target.rs +++ b/crates/pixi_manifest/src/target.rs @@ -446,8 +446,12 @@ impl PackageTarget { } } -/// Represents a target selector. Currently we only support explicit platform -/// selection. +/// Represents a target selector. +/// +/// Target selectors choose a configuration based on the platform. `if(...)` +/// conditional dependencies are not platform selectors; they are modelled +/// separately as [`pixi_build_types::ConditionalExpression`] and only exist on +/// the package manifest. #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum TargetSelector { // Platform specific configuration @@ -457,7 +461,6 @@ pub enum TargetSelector { Linux, Win, MacOs, - // TODO: Add minijinja coolness here. } impl TargetSelector { @@ -509,10 +512,29 @@ impl From for TargetSelector { } } +/// Error returned when a target selector key cannot be parsed. +#[derive(Debug, thiserror::Error)] +pub enum ParseTargetSelectorError { + #[error(transparent)] + Platform(#[from] ParsePlatformError), + + /// The key looks like an `if(...)` expression selector, which is only valid + /// in the `[package]` dependency tables. + #[error( + "`{0}` is not a valid target selector. Expression selectors (`if(...)`) are only supported inside the `[package]` dependency tables (e.g. `[package.build-dependencies.\"if(host_platform == 'linux-64')\"]`); `[target.*]` accepts platform names only" + )] + Expression(String), +} + impl FromStr for TargetSelector { - type Err = ParsePlatformError; + type Err = ParseTargetSelectorError; fn from_str(s: &str) -> Result { + // `(` cannot appear in a platform or family name, so a key containing it + // is an attempt at an expression selector, which is package-only. + if key_looks_conditional(s) { + return Err(ParseTargetSelectorError::Expression(s.to_string())); + } if let Some(selector) = family_name_to_selector(s) { return Ok(selector); } @@ -522,7 +544,8 @@ impl FromStr for TargetSelector { let Ok(platform) = PixiPlatformName::try_from(s) else { return Err(ParsePlatformError { string: s.to_string(), - }); + } + .into()); }; Ok(TargetSelector::Platform(platform)) } @@ -541,6 +564,25 @@ pub(crate) fn family_name_to_selector(s: &str) -> Option { } } +/// If `key` is a well-formed `if()` wrapper, return the trimmed +/// inner expression. Returns `None` when the key is not wrapped or the +/// expression is empty. +/// +/// `(` is not a valid character in a package name, platform, or family, so a +/// key containing `(` is always intended as a conditional selector; callers +/// use [`key_looks_conditional`] to detect that case and report a malformed +/// expression when this function returns `None`. +pub(crate) fn parse_if_expression(key: &str) -> Option<&str> { + let inner = key.strip_prefix("if(")?.strip_suffix(')')?.trim(); + (!inner.is_empty()).then_some(inner) +} + +/// Returns true when `key` is intended as a conditional selector, i.e. it +/// contains a `(`. Such keys must be a well-formed `if()`. +pub(crate) fn key_looks_conditional(key: &str) -> bool { + key.contains('(') +} + /// A collect of targets including a default target. #[derive(Debug, Clone, Default)] pub struct Targets { diff --git a/crates/pixi_manifest/src/toml/manifest.rs b/crates/pixi_manifest/src/toml/manifest.rs index cff5f236f3..2c8d5bfa74 100644 --- a/crates/pixi_manifest/src/toml/manifest.rs +++ b/crates/pixi_manifest/src/toml/manifest.rs @@ -1337,8 +1337,7 @@ mod test { "#, ); let host_deps = pkg - .targets - .default() + .dependencies .dependencies .get(&crate::SpecType::Host) .expect("host bucket"); @@ -1573,6 +1572,33 @@ mod test { )); } + #[test] + fn test_expression_selector_rejected_in_workspace_target() { + // `if(...)` expression selectors are only valid inside the `[package]` + // dependency tables; in a workspace `[target.*]` they must be rejected + // with a hint pointing users at the package dependency tables. + assert_snapshot!(expect_parse_failure( + r#" + [workspace] + name = "test" + channels = [] + platforms = ['linux-64'] + + [target."if(host_platform == build_platform)".dependencies] + foo = "*" + "#, + ), @r###" + × `if(host_platform == build_platform)` is not a valid target selector. Expression selectors (`if(...)`) are only supported inside the `[package]` dependency tables (e.g. `[package.build- + │ dependencies."if(host_platform == 'linux-64')"]`); `[target.*]` accepts platform names only + ╭─[pixi.toml:7:18] + 6 │ + 7 │ [target."if(host_platform == build_platform)".dependencies] + · ─────────────────────────────────── + 8 │ foo = "*" + ╰──── + "###); + } + #[test] fn test_unknown_feature() { assert_snapshot!(expect_parse_failure( diff --git a/crates/pixi_manifest/src/toml/package.rs b/crates/pixi_manifest/src/toml/package.rs index 1e19d6af5d..f5e4e3c8e0 100644 --- a/crates/pixi_manifest/src/toml/package.rs +++ b/crates/pixi_manifest/src/toml/package.rs @@ -1,6 +1,7 @@ use std::path::{Path, PathBuf}; use indexmap::IndexMap; +use pixi_build_types::ConditionalExpression; use pixi_spec::TomlSpec; pub use pixi_toml::TomlFromStr; use pixi_toml::{DeserializeAs, Same, TomlIndexMap, TomlWith}; @@ -10,13 +11,20 @@ use toml_span::{DeserError, Span, Spanned, Value, de_helpers::TableHelper}; use url::Url; use crate::{ - PackageManifest, Preview, TargetSelector, Targets, TomlError, WithWarnings, + PackageManifest, Preview, TargetSelector, TomlError, WithWarnings, error::GenericError, package::Package, + target::PackageTarget, toml::{ TomlPackageBuild, manifest::ExternalWorkspaceProperties, package_target::TomlPackageTarget, }, - utils::{PixiSpanned, inheritable_package_map::InheritablePackageMap}, + utils::{ + PixiSpanned, + inheritable_package_map::{ + ConditionalInheritablePackageMap, ConditionalSpecs, InheritablePackageMap, + }, + }, + warning::Deprecation, }; /// Represents a field that can either have a direct value or inherit from @@ -133,11 +141,12 @@ pub struct TomlPackage { // Fields that are package-specific and cannot be inherited pub build: TomlPackageBuild, - pub host_dependencies: Option>, - pub build_dependencies: Option>, - pub run_dependencies: Option>, - pub extra_dependencies: IndexMap, PixiSpanned>, - pub run_constraints: Option>, + pub host_dependencies: Option>, + pub build_dependencies: Option>, + pub run_dependencies: Option>, + pub extra_dependencies: + IndexMap, PixiSpanned>, + pub run_constraints: Option>, pub target: IndexMap, TomlPackageTarget>, pub span: Span, @@ -359,23 +368,120 @@ impl TomlPackage { "version", )?; + // Split each package-level dependency table into its unconditional + // entries and any `if()` sub-tables. + let (run_unconditional, run_conditional) = split_section(self.run_dependencies); + let (constraints_unconditional, constraints_conditional) = + split_section(self.run_constraints); + let (host_unconditional, host_conditional) = split_section(self.host_dependencies); + let (build_unconditional, build_conditional) = split_section(self.build_dependencies); + + let mut extra_unconditional: IndexMap< + PixiSpanned, + PixiSpanned, + > = IndexMap::new(); + let mut extra_conditional: Vec<(PixiSpanned, ConditionalSpecs)> = Vec::new(); + for (group, PixiSpanned { value, span }) in self.extra_dependencies { + let (unconditional, conditional) = value.into_parts(); + if !unconditional.is_empty() { + extra_unconditional.insert( + group.clone(), + PixiSpanned { + value: unconditional, + span, + }, + ); + } + for spec in conditional { + extra_conditional.push((group.clone(), spec)); + } + } + + // Unconditional entries form the default target. let default_package_target = TomlPackageTarget { - run_dependencies: self.run_dependencies, - run_constraints: self.run_constraints, - host_dependencies: self.host_dependencies, - build_dependencies: self.build_dependencies, - extra_dependencies: self.extra_dependencies, + run_dependencies: run_unconditional, + run_constraints: constraints_unconditional, + host_dependencies: host_unconditional, + build_dependencies: build_unconditional, + extra_dependencies: extra_unconditional, } .into_package_target(preview, &workspace_dependencies)?; - let targets = self - .target - .into_iter() - .map(|(selector, target)| { - let target = target.into_package_target(preview, &workspace_dependencies)?; - Ok::<_, TomlError>((selector, target)) - }) - .collect::>()?; + // Fold the conditional sub-tables into one `TomlPackageTarget` per + // distinct expression, merging across the dependency sections. + type SectionField = + fn(&mut TomlPackageTarget) -> &mut Option>; + let sections: [(Vec, SectionField); 4] = [ + (run_conditional, |target| &mut target.run_dependencies), + (constraints_conditional, |target| { + &mut target.run_constraints + }), + (host_conditional, |target| &mut target.host_dependencies), + (build_conditional, |target| &mut target.build_dependencies), + ]; + let mut conditional_targets: IndexMap = + IndexMap::new(); + for (specs, field) in sections { + for spec in specs { + *field(conditional_targets.entry(spec.expression).or_default()) = + Some(PixiSpanned { + value: spec.specs, + span: Some(spec.value_span), + }); + } + } + for (group, spec) in extra_conditional { + conditional_targets + .entry(spec.expression) + .or_default() + .extra_dependencies + .insert( + group, + PixiSpanned { + value: spec.specs, + span: Some(spec.value_span), + }, + ); + } + + // The legacy `[package.target.PLATFORM]` syntax is deprecated but still + // supported: each table lowers to the conditional dependency tables for + // the equivalent expression. Emit a deprecation warning that spells out + // that replacement. + for (selector, toml_target) in self.target { + let expression = target_selector_expression(&selector.value); + warnings.push( + Deprecation::package_target( + package_target_replacement_help(expression.as_str(), &toml_target), + selector.span.clone(), + ) + .into(), + ); + if conditional_targets.contains_key(&expression) { + return Err(GenericError::new(format!( + "duplicate condition: `[package.target.{}]` is equivalent to `\"if({expression})\"`", + selector.value + )) + .with_opt_span(selector.span) + .with_span_label("this target table lowers to the same condition") + .with_help(format!( + "Move the dependencies into the `\"if({expression})\"` tables and remove the `[package.target.{}]` table", + selector.value + )) + .into()); + } + conditional_targets.insert(expression, toml_target); + } + + // `if(...)` conditionals are not platform selectors; they are kept + // separate and passed through to rattler-build, which evaluates the + // expression. + let mut conditional_dependencies: IndexMap = + IndexMap::new(); + for (expression, toml_target) in conditional_targets { + let target = toml_target.into_package_target(preview, &workspace_dependencies)?; + conditional_dependencies.insert(expression, target); + } if let Some(WorkspaceInheritableField::Value(Spanned { value: license, @@ -506,12 +612,83 @@ impl TomlPackage { )?, }, build: build_result.value, - targets: Targets::from_default_and_user_defined(default_package_target, targets), + dependencies: default_package_target, + conditional_dependencies, }) .with_warnings(warnings)) } } +/// The conditional expression a deprecated `[package.target.SELECTOR]` table +/// lowers to. +/// +/// Platform selectors map to `host_platform == ''` (the behavior the +/// legacy syntax already had); family selectors (`unix`/`linux`/`win`/`osx`) +/// map to the bare rattler-build boolean of the same name. Note that the +/// `macos` alias maps to `osx`, the only spelling defined in rattler-build's +/// jinja context. +fn target_selector_expression(selector: &TargetSelector) -> ConditionalExpression { + match selector { + TargetSelector::Platform(_) | TargetSelector::Subdir(_) => { + ConditionalExpression::new(format!("host_platform == '{selector}'")) + } + other => ConditionalExpression::new(other.to_string()), + } +} + +/// Build the tailored `help` text suggesting the conditional dependency tables +/// that replace a deprecated `[package.target.SELECTOR]` entry. +fn package_target_replacement_help(expression: &str, toml_target: &TomlPackageTarget) -> String { + let mut lines = Vec::new(); + let mut push_line = |section: &str| { + lines.push(format!(" [package.{section}.\"if({expression})\"]")); + }; + if toml_target.build_dependencies.is_some() { + push_line("build-dependencies"); + } + if toml_target.host_dependencies.is_some() { + push_line("host-dependencies"); + } + if toml_target.run_dependencies.is_some() { + push_line("run-dependencies"); + } + if toml_target.run_constraints.is_some() { + push_line("run-constraints"); + } + if !toml_target.extra_dependencies.is_empty() { + lines.push(format!( + " [package.extra-dependencies..\"if({expression})\"]" + )); + } + + format!( + "Move the dependencies under a conditional dependency table instead:\n{}", + lines.join("\n") + ) +} + +/// Split a package-level dependency table into its unconditional entries (which +/// belong to the default target) and the list of `if()` sub-tables. +/// Returns `None` for the unconditional part when it is empty. +fn split_section( + field: Option>, +) -> ( + Option>, + Vec, +) { + match field { + None => (None, Vec::new()), + Some(PixiSpanned { value, span }) => { + let (unconditional, conditional) = value.into_parts(); + let unconditional = (!unconditional.is_empty()).then_some(PixiSpanned { + value: unconditional, + span, + }); + (unconditional, conditional) + } + } +} + fn workspace_cannot_be_false() -> GenericError { GenericError::new("`workspace` cannot be false") .with_help("By default no fields are inherited from the workspace") @@ -553,11 +730,12 @@ mod test { use insta::assert_snapshot; use pixi_spec::PixiSpec; use pixi_test_utils::format_parse_error; - use rattler_conda_types::{PackageName, Platform}; + use rattler_conda_types::PackageName; use tempfile::TempDir; use super::*; - use crate::{KnownPreviewFeature, SpecType, TargetSelector, toml::FromTomlStr}; + use crate::{KnownPreviewFeature, SpecType, toml::FromTomlStr}; + use pixi_build_types::ConditionalExpression; /// Parses a manifest using only `Preview::default()` and asserts it succeeds. fn parse_package(input: &str) -> PackageManifest { @@ -726,8 +904,7 @@ mod test { .value; let test_extra = manifest - .targets - .default() + .dependencies .extra_dependencies .get("test") .expect("test extra exists"); @@ -768,13 +945,13 @@ mod test { .value; let win_target = manifest - .targets - .for_target(&TargetSelector::Win) + .conditional_dependencies + .get(&ConditionalExpression::new("win")) .expect("win target exists"); assert!(win_target.extra_dependencies.contains_key("test")); assert!(win_target.extra_dependencies.contains_key("bench")); // Default target should NOT have the per-target extras. - assert!(manifest.targets.default().extra_dependencies.is_empty()); + assert!(manifest.dependencies.extra_dependencies.is_empty()); } #[test] @@ -1304,7 +1481,7 @@ mod test { "#; let manifest = parse_package(input); - let deps = &manifest.targets.default().dependencies; + let deps = &manifest.dependencies.dependencies; assert_single_version(deps, SpecType::Run, "run-dep", "==1.0"); assert_single_version(deps, SpecType::Host, "host-dep", "==2.0"); @@ -1336,17 +1513,17 @@ mod test { let manifest = parse_package(input); // Default target only has the shared run dep. - let default_deps = &manifest.targets.default().dependencies; + let default_deps = &manifest.dependencies.dependencies; assert_single_version(default_deps, SpecType::Run, "shared", "==1.0"); assert!( !default_deps.contains_key(&SpecType::RunConstraints), "run-constraints should not leak into default target", ); - // linux-64 target has its own deps and constraints. + // The linux-64 target lowers to the equivalent conditional expression. let linux = manifest - .targets - .for_target(&TargetSelector::Subdir(Platform::Linux64)) + .conditional_dependencies + .get(&ConditionalExpression::new("host_platform == 'linux-64'")) .expect("linux-64 target should exist"); assert_single_version(&linux.dependencies, SpecType::Run, "only-linux", "==2.0"); assert_single_version( @@ -1357,6 +1534,235 @@ mod test { ); } + #[test] + fn test_package_conditional_dependencies() { + // `if()` keys inside the package dependency tables become + // `Expression` targets; plain entries stay on the default target. + let input = r#" + name = "pkg" + version = "1.0" + + [build] + backend = { name = "bla", version = "1.0" } + + [run-dependencies] + shared = "==1.0" + + [build-dependencies."if(host_platform != build_platform)"] + cross-tool = "==2.0" + + [host-dependencies."if(host_platform == 'linux-64')"] + libgl = "==3.0" + "#; + + let manifest = parse_package(input); + + // Plain entry stays on the default target. + assert_single_version( + &manifest.dependencies.dependencies, + SpecType::Run, + "shared", + "==1.0", + ); + + // Each `if(...)` block produces a conditional target with only the + // matching dependency bucket populated. + let cross = manifest + .conditional_dependencies + .get(&ConditionalExpression::new( + "host_platform != build_platform", + )) + .expect("conditional target should exist"); + assert_single_version(&cross.dependencies, SpecType::Build, "cross-tool", "==2.0"); + + let linux = manifest + .conditional_dependencies + .get(&ConditionalExpression::new("host_platform == 'linux-64'")) + .expect("conditional target should exist"); + assert_single_version(&linux.dependencies, SpecType::Host, "libgl", "==3.0"); + } + + #[test] + fn test_package_conditional_merges_same_expression() { + // The same expression used across sections folds into a single target. + let input = r#" + name = "pkg" + version = "1.0" + + [build] + backend = { name = "bla", version = "1.0" } + + [build-dependencies."if(host_platform == 'linux-64')"] + build-only = "==1.0" + + [run-dependencies."if(host_platform == 'linux-64')"] + run-only = "==2.0" + "#; + + let manifest = parse_package(input); + assert_eq!( + manifest.conditional_dependencies.len(), + 1, + "the two sections must merge into one target" + ); + + let target = manifest + .conditional_dependencies + .get(&ConditionalExpression::new("host_platform == 'linux-64'")) + .expect("conditional target should exist"); + assert_single_version(&target.dependencies, SpecType::Build, "build-only", "==1.0"); + assert_single_version(&target.dependencies, SpecType::Run, "run-only", "==2.0"); + } + + #[test] + fn test_package_conditional_malformed_expression() { + // A key containing `(` that is not a well-formed `if(...)` is rejected. + assert_snapshot!(expect_parse_failure( + r#" + name = "pkg" + version = "1.0" + + [build] + backend = { name = "bla", version = "1.0" } + + [build-dependencies."matches(python, '>=3.10')"] + foo = "*" + "#, + ), @r###" + × `matches(python, '>=3.10')` is not a valid selector. Wrap the expression in `if(...)`, e.g. `if(host_platform == 'linux-64')` + ╭─[pixi.toml:8:30] + 7 │ + 8 │ [build-dependencies."matches(python, '>=3.10')"] + · ───────────────────────── + 9 │ foo = "*" + ╰──── + "###); + } + + #[test] + fn test_package_target_emits_deprecation_warning() { + // The legacy `[package.target.*]` syntax still parses, but produces a + // deprecation warning suggesting the conditional form. + let input = r#" + name = "pkg" + version = "1.0" + + [build] + backend = { name = "bla", version = "1.0" } + + [target.linux-64.build-dependencies] + foo = "==1.0" + "#; + + let mut parsed = TomlPackage::from_toml_str(input) + .and_then(|w| { + w.into_manifest( + WorkspacePackageProperties::default(), + PackageDefaults::default(), + &Preview::default(), + Path::new(""), + ) + }) + .expect("legacy target syntax must still parse"); + + assert!( + !parsed.warnings.is_empty(), + "legacy target syntax must emit a deprecation warning" + ); + // The rendered warning names the deprecated table and spells out the + // exact conditional syntax to use instead. + assert_snapshot!( + format_parse_error(input, parsed.warnings.remove(0)), + @r#" + ⚠ the `[package.target]` tables are deprecated in favor of conditional dependencies + ╭─[pixi.toml:8:17] + 7 │ + 8 │ [target.linux-64.build-dependencies] + · ────┬─── + · ╰── deprecated target selector + 9 │ foo = "==1.0" + ╰──── + help: Move the dependencies under a conditional dependency table instead: + [package.build-dependencies."if(host_platform == 'linux-64')"] + "# + ); + + // The legacy target still works: it lowers to the equivalent + // conditional dependency entry. + let linux = parsed + .value + .conditional_dependencies + .get(&ConditionalExpression::new("host_platform == 'linux-64'")) + .expect("linux-64 target should lower to a conditional entry"); + assert_single_version(&linux.dependencies, SpecType::Build, "foo", "==1.0"); + } + + #[test] + fn test_package_target_collides_with_equivalent_conditional() { + // A deprecated target table and an explicit `if(...)` table that lower + // to the same expression are rejected; silently merging them would hide + // a half-finished migration. + let input = r#" + name = "pkg" + version = "1.0" + + [build] + backend = { name = "bla", version = "1.0" } + + [run-dependencies."if(host_platform == 'linux-64')"] + foo = "==1.0" + + [target.linux-64.build-dependencies] + bar = "==2.0" + "#; + + let parse_error = TomlPackage::from_toml_str(input) + .and_then(|w| { + w.into_manifest( + WorkspacePackageProperties::default(), + PackageDefaults::default(), + &Preview::default(), + Path::new(""), + ) + }) + .unwrap_err(); + assert_snapshot!(format_parse_error(input, parse_error), @r#" + × duplicate condition: `[package.target.linux-64]` is equivalent to `"if(host_platform == 'linux-64')"` + ╭─[pixi.toml:11:17] + 10 │ + 11 │ [target.linux-64.build-dependencies] + · ────┬─── + · ╰── this target table lowers to the same condition + 12 │ bar = "==2.0" + ╰──── + help: Move the dependencies into the `"if(host_platform == 'linux-64')"` tables and remove the `[package.target.linux-64]` table + "#); + } + + #[test] + fn test_package_target_osx_lowers_to_osx_expression() { + // `[package.target.osx]` must lower to the rattler-build family boolean + // `osx`; `macos` is not defined in rattler-build's jinja context and + // would silently evaluate to false. + let input = r#" + name = "pkg" + version = "1.0" + + [build] + backend = { name = "bla", version = "1.0" } + + [target.osx.run-dependencies] + foo = "==1.0" + "#; + + let manifest = parse_package(input); + let target = manifest + .conditional_dependencies + .get(&ConditionalExpression::new("osx")) + .expect("the osx target must lower to the `osx` conditional expression"); + assert_single_version(&target.dependencies, SpecType::Run, "foo", "==1.0"); + } + #[test] fn test_run_constraints_source_spec_requires_pixi_build() { // Source specs in [package.run-constraints] must be rejected unless the diff --git a/crates/pixi_manifest/src/utils/inheritable_package_map.rs b/crates/pixi_manifest/src/utils/inheritable_package_map.rs index faa3058d24..c63b0694fd 100644 --- a/crates/pixi_manifest/src/utils/inheritable_package_map.rs +++ b/crates/pixi_manifest/src/utils/inheritable_package_map.rs @@ -2,6 +2,7 @@ use std::{ops::Range, str::FromStr}; use indexmap::IndexMap; use itertools::Itertools; +use pixi_build_types::ConditionalExpression; use pixi_spec::{PixiSpec, TomlSpec}; use rattler_conda_types::PackageName; use toml_span::{ @@ -10,7 +11,12 @@ use toml_span::{ value::{Table, ValueInner}, }; -use crate::{TomlError, error::GenericError, utils::package_map::UniquePackageMap}; +use crate::{ + TomlError, + error::GenericError, + target::{key_looks_conditional, parse_if_expression}, + utils::package_map::UniquePackageMap, +}; /// Entry in a `[package.*-dependencies]` table that may inherit from /// `[workspace.dependencies]`. @@ -208,6 +214,109 @@ impl<'de> toml_span::Deserialize<'de> for InheritablePackageMap { } } +/// A single `if()` sub-table inside a package dependency table. +#[derive(Debug)] +pub struct ConditionalSpecs { + /// The bare inner expression, without the `if(...)` wrapper. + pub expression: ConditionalExpression, + /// Span of the sub-table value. + pub value_span: Range, + /// The dependencies declared under this condition. + pub specs: InheritablePackageMap, +} + +/// A package dependency table that, in addition to plain `name = spec` entries, +/// may contain conditional sub-tables keyed by `if()`. Plain +/// entries land in `unconditional`; each `if(...)` sub-table becomes a +/// [`ConditionalSpecs`] in source order. +/// +/// Keys are routed by `key_looks_conditional`: +/// a key containing `(` must be a well-formed `if()` or it is +/// reported as an error. +#[derive(Default, Debug)] +pub struct ConditionalInheritablePackageMap { + pub unconditional: InheritablePackageMap, + pub conditional: Vec, +} + +impl ConditionalInheritablePackageMap { + /// Split into the unconditional map and the list of conditional sub-tables. + pub fn into_parts(self) -> (InheritablePackageMap, Vec) { + (self.unconditional, self.conditional) + } +} + +impl<'de> toml_span::Deserialize<'de> for ConditionalInheritablePackageMap { + fn deserialize(value: &mut Value<'de>) -> Result { + let span = value.span; + let table = match value.take() { + ValueInner::Table(table) => table, + inner => return Err(expected("a table", inner, span).into()), + }; + + let mut errors = DeserError { errors: vec![] }; + let mut plain: Table<'de> = Table::new(); + let mut conditional = Vec::new(); + + for (key, mut entry_value) in table.into_iter().sorted_by_key(|(k, _)| k.span.start) { + if key_looks_conditional(&key.name) { + match parse_if_expression(&key.name) { + Some(expression) => { + let value_span = entry_value.span; + match InheritablePackageMap::deserialize(&mut entry_value) { + Ok(specs) => conditional.push(ConditionalSpecs { + expression: ConditionalExpression::new(expression), + value_span: value_span.start..value_span.end, + specs, + }), + Err(e) => errors.merge(e), + } + } + None => { + errors.errors.push(toml_span::Error { + kind: toml_span::ErrorKind::Custom( + format!( + "`{}` is not a valid selector. Wrap the expression in `if(...)`, e.g. `if(host_platform == 'linux-64')`", + key.name + ) + .into(), + ), + span: key.span, + line_info: None, + }); + } + } + } else { + plain.insert(key, entry_value); + } + } + + // Delegate the plain entries to `InheritablePackageMap` so name parsing, + // duplicate detection and spec parsing stay in one place. + let unconditional = if plain.is_empty() { + InheritablePackageMap::default() + } else { + let mut tmp = Value::with_span(ValueInner::Table(plain), span); + match InheritablePackageMap::deserialize(&mut tmp) { + Ok(map) => map, + Err(e) => { + errors.merge(e); + InheritablePackageMap::default() + } + } + }; + + if errors.errors.is_empty() { + Ok(Self { + unconditional, + conditional, + }) + } else { + Err(errors) + } + } +} + fn parse_inheritable_entry(value: &mut Value<'_>) -> Result { let outer_span = value.span; match value.take() { diff --git a/crates/pixi_manifest/src/warning/deprecation.rs b/crates/pixi_manifest/src/warning/deprecation.rs index 6350040cd8..485eca7cc9 100644 --- a/crates/pixi_manifest/src/warning/deprecation.rs +++ b/crates/pixi_manifest/src/warning/deprecation.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, fmt::Display}; +use std::{borrow::Cow, fmt::Display, ops::Range}; use miette::{Diagnostic, LabeledSpan, Severity, SourceSpan}; use thiserror::Error; @@ -25,6 +25,27 @@ impl Deprecation { help: None, } } + + /// Deprecation of the legacy `[package.target.*]` dependency tables in + /// favor of `if()` conditional dependency tables. `help` carries + /// the tailored replacement suggestion. + pub fn package_target(help: String, span: Option>) -> Self { + let labels = span + .map(|span| { + vec![LabeledSpan::new_primary_with_span( + Some("deprecated target selector".to_string()), + SourceSpan::new(span.start.into(), span.end - span.start), + )] + }) + .unwrap_or_default(); + Self { + message: + "the `[package.target]` tables are deprecated in favor of conditional dependencies" + .into(), + labels, + help: Some(help.into()), + } + } } impl Diagnostic for Deprecation { diff --git a/docs/build/dependency_types.md b/docs/build/dependency_types.md index dba8e21ac2..cc6bf72bec 100644 --- a/docs/build/dependency_types.md +++ b/docs/build/dependency_types.md @@ -12,6 +12,9 @@ Each dependency is used at a different step of the package building process. Let's delve deeper into the various types of package dependencies and their specific roles in the build process. +!!! note "pixi-build-rattler-build" + The `pixi-build-rattler-build` backend only regards dependencies defined in the `recipe.yaml` + ### [Build Dependencies](../reference/pixi_manifest.md#build-dependencies) !!! note "pixi-build-cmake" When using the `pixi-build-cmake` backend you do not need to specify `cmake` or the compiler as a dependency. @@ -150,6 +153,41 @@ They never cause a package to be installed on their own. To do that, use run-dep This corresponds to conda's `run_constrained` package metadata. +## Conditional Dependencies + +Any of the dependency tables above can hold dependencies that only apply when a condition holds. +Write the condition as an `if()` key inside the dependency table: + +```toml +# Only needed when cross-compiling (host platform differs from build platform). +[package.build-dependencies."if(host_platform != build_platform)"] +cross-python = "*" + +# Only on Linux. +[package.host-dependencies."if(host_platform == 'linux-64')"] +libgl-devel = ">=1.7.0,<2" + +# Based on a build variant. +[package.host-dependencies."if(matches(python, '>=3.10'))"] +exceptiongroup = "*" +``` + +The expression is passed through verbatim to the build-backend. +At the time of this writing all build backends are backed by [rattler-build](https://rattler.build), so any selector it understands works, including the boolean operators `and`, `or` and `not`. +Three platform variables are available: + +- `build_platform`: the platform the build runs on. +- `host_platform`: the platform the package is built for. + Differs from `build_platform` when cross-compiling. +- `target_platform`: the run platform. + Differs from `host_platform` for `noarch` packages. + +The platform families `unix`, `linux`, `win` and `osx` are also available as bare booleans, e.g. `if(unix)`. + +!!! note + `if(...)` conditions are only available in the `[package]` dependency tables. + The workspace `[target.*]` tables continue to accept platform names only. + ## Inheriting Versions From the Workspace When several packages in the same workspace share dependency versions you can diff --git a/docs/build/workspace_dependencies.md b/docs/build/workspace_dependencies.md index fee7c73cd5..4589041fec 100644 --- a/docs/build/workspace_dependencies.md +++ b/docs/build/workspace_dependencies.md @@ -11,7 +11,7 @@ of dependency specs that packages opt into per entry. `[workspace.dependencies]` is part of the `pixi-build` preview and applies **only to package dependencies** (`[package.*-dependencies]`, `[package.run-constraints]` and `[package.build.backend]`, including their - `[package.target..*]` variants). + `"if()"` conditional sub-tables). The workspace-level environment tables (`[dependencies]`, `[host-dependencies]`, `[build-dependencies]`, `[pypi-dependencies]`, `[constraints]`) do **not** participate; entries there continue to be @@ -71,7 +71,7 @@ The inheritance marker is recognized in every package dependency table: - `[package.build-dependencies]` - `[package.run-dependencies]` - `[package.run-constraints]` -- `[package.target..*]` variants of the above +- `"if()"` conditional sub-tables of the above - `[package.build.backend]` (the lookup key is the backend's `name`) ## Layering package overrides diff --git a/examples/pixi-build/conditional-dependencies/.gitattributes b/examples/pixi-build/conditional-dependencies/.gitattributes new file mode 100644 index 0000000000..997504b465 --- /dev/null +++ b/examples/pixi-build/conditional-dependencies/.gitattributes @@ -0,0 +1,2 @@ +# SCM syntax highlighting & preventing 3-way merges +pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/examples/pixi-build/conditional-dependencies/.gitignore b/examples/pixi-build/conditional-dependencies/.gitignore new file mode 100644 index 0000000000..ae849e65b8 --- /dev/null +++ b/examples/pixi-build/conditional-dependencies/.gitignore @@ -0,0 +1,3 @@ +# pixi environments +.pixi/* +!.pixi/config.toml diff --git a/examples/pixi-build/conditional-dependencies/CMakeLists.txt b/examples/pixi-build/conditional-dependencies/CMakeLists.txt new file mode 100644 index 0000000000..20f17563d9 --- /dev/null +++ b/examples/pixi-build/conditional-dependencies/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.18) +project(cuda_probe LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + +add_executable(cuda_probe src/main.cc) + +# The CUDA runtime is only pulled in as a host-dependency on platforms where +# conda-forge ships it (see the `if(...)` block in pixi.toml). When it is +# present we light up the CUDA code path; otherwise we build a CPU-only binary +# from the exact same sources. +find_package(CUDAToolkit QUIET) +if(CUDAToolkit_FOUND) + message(STATUS "CUDA toolkit ${CUDAToolkit_VERSION} found, enabling CUDA support") + target_compile_definitions(cuda_probe PRIVATE + HAS_CUDA + CUDA_VERSION_STRING="${CUDAToolkit_VERSION}") + target_link_libraries(cuda_probe PRIVATE CUDA::cudart) +else() + message(STATUS "No CUDA toolkit found, building CPU-only") +endif() + +include(GNUInstallDirs) +install(TARGETS cuda_probe RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/examples/pixi-build/conditional-dependencies/README.md b/examples/pixi-build/conditional-dependencies/README.md new file mode 100644 index 0000000000..5c87c27097 --- /dev/null +++ b/examples/pixi-build/conditional-dependencies/README.md @@ -0,0 +1,34 @@ +# Conditional dependencies + +A minimal C++ package that shows off `if(...)` conditional dependencies in a +Pixi `[package]` section. + +`cuda_probe` is a tiny executable that reports which compiler built it and +whether it was compiled with CUDA support. The CUDA runtime is only available +on conda-forge for Linux and Windows, so the manifest asks for it only there: + +```toml +[package.host-dependencies."if(linux or win)"] +cuda-version = "12.*" +cuda-cudart-dev = "12.*" +``` + +On Linux/Windows the build links against the CUDA runtime and the program +queries the visible device count. On macOS the block is skipped entirely and +the very same sources build a CPU-only binary. + +## Run it + +```bash +pixi run start +``` + +On a machine without conditional-dependency support you would instead see the +old `[package.target.*]` tables. The `if()` form accepts anything +rattler-build understands (`and`, `or`, `not`, `matches(...)`, ...) and exposes +these variables: + +- `build_platform` the platform the build runs on +- `host_platform` the platform the package is built for (differs when cross-compiling) +- `target_platform` the run platform (differs from `host_platform` for `noarch`) +- the bare booleans `unix`, `linux`, `win` and `osx` diff --git a/examples/pixi-build/conditional-dependencies/pixi.lock b/examples/pixi-build/conditional-dependencies/pixi.lock new file mode 100644 index 0000000000..75939b8de1 --- /dev/null +++ b/examples/pixi-build/conditional-dependencies/pixi.lock @@ -0,0 +1,2912 @@ +version: 7 +platforms: +- name: linux-64 +- name: osx-64 +- name: osx-arm64 +- name: win-64 +environments: + default: + channels: + - url: https://prefix.dev/pixi-build-backends/ + - url: https://prefix.dev/conda-forge/ + packages: + linux-64: + - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://prefix.dev/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda + - conda: https://prefix.dev/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-crt-tools-12.9.86-ha770c72_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-cudart-12.9.79-h5888daf_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-cudart-static-12.9.79-h5888daf_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc-12.9.86-hcdd1206_6.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc-tools-12.9.86-he02047a_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc_linux-64-12.9.86-he0b4e1d_6.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-nvvm-impl-12.9.86-h4bc722e_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/cuda-nvvm-tools-12.9.86-h4bc722e_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h235f0fe_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_25.conda + - conda: https://prefix.dev/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/gxx_linux-64-14.3.0-h72ca5df_25.conda + - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libnvptxcompiler-dev-12.9.86-ha770c72_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-cccl_linux-64-12.9.27-ha770c72_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-crt-dev_linux-64-12.9.86-ha770c72_2.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-static_linux-64-12.9.79-h3f2d84a_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-cudart_linux-64-12.9.79-h3f2d84a_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-driver-dev_linux-64-12.9.79-h3f2d84a_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-nvcc-dev_linux-64-12.9.86-he91c749_2.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-nvvm-dev_linux-64-12.9.86-ha770c72_2.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda + - conda: https://prefix.dev/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda + - conda: https://prefix.dev/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_119.conda + - conda: https://prefix.dev/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda + - conda: https://prefix.dev/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_119.conda + - conda: https://prefix.dev/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda + - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda_source: cuda_probe[139d67dc] @ . + osx-64: + - conda: https://prefix.dev/conda-forge/osx-64/libcxx-22.1.7-h19cb2f5_0.conda + - conda_source: cuda_probe[d2e722fe] @ . + osx-arm64: + - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-22.1.7-h55c6f16_0.conda + - conda_source: cuda_probe[b008fffd] @ . + win-64: + - conda: https://prefix.dev/conda-forge/noarch/cuda-cccl_win-64-12.9.27-h57928b3_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-crt-dev_win-64-12.9.86-h57928b3_2.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-dev_win-64-12.9.79-he0c23c2_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-static_win-64-12.9.79-he0c23c2_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-cudart_win-64-12.9.79-he0c23c2_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-nvcc-dev_win-64-12.9.86-h36c15f3_2.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-nvvm-dev_win-64-12.9.86-h57928b3_2.conda + - conda: https://prefix.dev/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda + - conda: https://prefix.dev/conda-forge/noarch/libnvptxcompiler-dev_win-64-12.9.86-h57928b3_2.conda + - conda: https://prefix.dev/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-crt-tools-12.9.86-h57928b3_2.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-cudart-12.9.79-he0c23c2_0.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-cudart-dev-12.9.79-he0c23c2_0.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-cudart-static-12.9.79-he0c23c2_0.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc-12.9.86-h8f04d04_6.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc-impl-12.9.86-h53cbb54_2.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc-tools-12.9.86-he0c23c2_2.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc_win-64-12.9.86-hd70436c_6.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-nvvm-impl-12.9.86-h2466b09_2.conda + - conda: https://prefix.dev/conda-forge/win-64/cuda-nvvm-tools-12.9.86-h2466b09_2.conda + - conda: https://prefix.dev/conda-forge/win-64/libnvptxcompiler-dev-12.9.86-h57928b3_2.conda + - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://prefix.dev/conda-forge/win-64/vc-14.5-h1b7c187_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vs2019_win-64-19.29.30139-h7dcff83_38.conda + - conda_source: cuda_probe[239c2f87] @ . +packages: +- conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 + md5: a9f577daf3de00bca7c3c76c0ecbd1de + depends: + - __glibc >=2.17,<3.0.a0 + - libgomp >=7.5.0 + constrains: + - openmp_impl <0.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - _openmp_mutex >=4.5 + size: 28948 + timestamp: 1770939786096 +- conda: https://prefix.dev/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda + sha256: 0a7d405064f53b9d91d92515f1460f7906ee5e8523f3cd8973430e81219f4917 + md5: 8165352fdce2d2025bf884dc0ee85700 + depends: + - ld_impl_linux-64 2.45.1 default_hbd61a6d_102 + - sysroot_linux-64 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + run_exports: {} + size: 3661455 + timestamp: 1774197460085 +- conda: https://prefix.dev/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda + sha256: 78a58d523d072b7f8e591b8f8572822e044b31764ed7e8d170392e7bc6d58339 + md5: 2a307a17309d358c9b42afdd3199ddcc + depends: + - binutils_impl_linux-64 2.45.1 default_hfdba357_102 + license: GPL-3.0-only + license_family: GPL + run_exports: {} + size: 36304 + timestamp: 1774197485247 +- conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 + md5: d2ffd7602c02f2b316fd921d39876885 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: bzip2-1.0.6 + license_family: BSD + run_exports: + weak: + - bzip2 >=1.0.8,<2.0a0 + size: 260182 + timestamp: 1771350215188 +- conda: https://prefix.dev/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + run_exports: + weak: + - c-ares >=1.34.6,<2.0a0 + size: 207882 + timestamp: 1765214722852 +- conda: https://prefix.dev/conda-forge/linux-64/cmake-4.3.3-hc85cc9f_0.conda + sha256: 796276f96ea27acaba1f25755977f6c12dfbc886fd1db713263c795184168f59 + md5: 30a266b5d91bc45fccbcc45588b2db79 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.20.0,<9.0a0 + - libexpat >=2.8.1,<3.0a0 + - libgcc >=14 + - liblzma >=5.8.3,<6.0a0 + - libstdcxx >=14 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 23085721 + timestamp: 1779398000620 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-crt-tools-12.9.86-ha770c72_2.conda + sha256: 2da9964591af14ba11b2379bed01d56e7185260ee0998d1a939add7fb752db45 + md5: 503a94e20d2690d534d676a764a1852c + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 29138 + timestamp: 1753975252445 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-cudart-12.9.79-h5888daf_0.conda + sha256: 57d1294ecfaf9dc8cdb5fc4be3e63ebc7614538bddb5de53cfd9b1b7de43aed5 + md5: cb15315d19b58bd9cd424084e58ad081 + depends: + - __glibc >=2.17,<3.0.a0 + - cuda-cudart_linux-64 12.9.79 h3f2d84a_0 + - cuda-version >=12.9,<12.10.0a0 + - libgcc >=13 + - libstdcxx >=13 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 23242 + timestamp: 1749218416505 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda + sha256: 04d8235cb3cb3510c0492c3515a9d1a6053b50ef39be42b60cafb05044b5f4c6 + md5: ba38a7c3b4c14625de45784b773f0c71 + depends: + - __glibc >=2.17,<3.0.a0 + - cuda-cudart 12.9.79 h5888daf_0 + - cuda-cudart-dev_linux-64 12.9.79 h3f2d84a_0 + - cuda-cudart-static 12.9.79 h5888daf_0 + - cuda-version >=12.9,<12.10.0a0 + - libgcc >=13 + - libstdcxx >=13 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: + weak: + - cuda-cudart >=12.9.79,<13.0a0 + size: 23687 + timestamp: 1749218464010 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-cudart-static-12.9.79-h5888daf_0.conda + sha256: 6261e1d9af80e1ec308e3e5e2ff825d189ef922d24093beaf6efca12e67ce060 + md5: d3c4ac48f4967f09dd910d9c15d40c81 + depends: + - __glibc >=2.17,<3.0.a0 + - cuda-cudart-static_linux-64 12.9.79 h3f2d84a_0 + - cuda-version >=12.9,<12.10.0a0 + - libgcc >=13 + - libstdcxx >=13 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 23283 + timestamp: 1749218442382 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc-12.9.86-hcdd1206_6.conda + sha256: f7c5de6b1f0f463f73c78cc73439027cdd5cb94fb4ce099116969812973cabcb + md5: 02289b10ac97bac35ad1add086c5072a + depends: + - cuda-nvcc_linux-64 12.9.86.* + - gcc_linux-64 + - gxx_linux-64 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 25472 + timestamp: 1771619493470 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda + sha256: 961cf20d411b7685cd744e6c6ed35efea547d095c62151d6f3053d9931bb994d + md5: 67458d2685e7503933efa550f3ee40f3 + depends: + - cuda-cudart >=12.9.79,<13.0a0 + - cuda-cudart-dev + - cuda-nvcc-dev_linux-64 12.9.86 he91c749_2 + - cuda-nvcc-tools 12.9.86 he02047a_2 + - cuda-nvvm-impl 12.9.86 h4bc722e_2 + - cuda-version >=12.9,<12.10.0a0 + - libnvptxcompiler-dev 12.9.86 ha770c72_2 + constrains: + - gcc_impl_linux-64 >=6,<15.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27215 + timestamp: 1753975546846 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc-tools-12.9.86-he02047a_2.conda + sha256: 0e849be7b5e4832ca218ec2c48a9ba3a15a984f629e2e54f38a53f4f57220341 + md5: dc256c9864c2e8e9c817fbca1c84a4bc + depends: + - __glibc >=2.17,<3.0.a0 + - cuda-crt-tools 12.9.86 ha770c72_2 + - cuda-nvvm-tools 12.9.86 h4bc722e_2 + - cuda-version >=12.9,<12.10.0a0 + - libgcc >=12 + - libstdcxx >=12 + constrains: + - gcc_impl_linux-64 >=6,<15.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27380012 + timestamp: 1753975454194 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-nvcc_linux-64-12.9.86-he0b4e1d_6.conda + sha256: c506221dafb7cfd081f7d12d01d8e8ab9b29adfcc7d69d61fedd3232174e4016 + md5: 359d05bc3ec5d3a467eb558e3844aea2 + depends: + - __glibc >=2.17,<3.0.a0 + - cuda-cudart-dev_linux-64 12.9.* + - cuda-driver-dev_linux-64 12.9.* + - cuda-nvcc-dev_linux-64 12.9.86.* + - cuda-nvcc-impl 12.9.86.* + - cuda-nvcc-tools 12.9.86.* + - sysroot_linux-64 >=2.17,<3.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: + strong: + - cuda-version >=12.9,<13 + size: 27575 + timestamp: 1771619492974 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-nvvm-impl-12.9.86-h4bc722e_2.conda + sha256: f4d34556174e4faa9d374ba2244707082870e1bbc1bb441ad3d9d2cea37da6af + md5: 82125dd3c0c4aa009faa00e2829b93d8 + depends: + - __glibc >=2.17,<3.0.a0 + - cuda-version >=12.9,<12.10.0a0 + - libgcc >=12 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 21425520 + timestamp: 1753975283188 +- conda: https://prefix.dev/conda-forge/linux-64/cuda-nvvm-tools-12.9.86-h4bc722e_2.conda + sha256: 45f5e881ed0d973132a5475a0b5c066db6e748ef3a831a14dba8374b252e0067 + md5: f9af26e4079adcd72688a8e8dbecb229 + depends: + - __glibc >=2.17,<3.0.a0 + - cuda-version >=12.9,<12.10.0a0 + - libgcc >=12 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 24246736 + timestamp: 1753975332907 +- conda: https://prefix.dev/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h235f0fe_19.conda + sha256: 1e2500ca976d4831c953d1c6db7b238d2e6806910b930e3eb631b79ba5c3ba41 + md5: 99936dc616b7ce97b0468759b8a7c64e + depends: + - binutils_impl_linux-64 >=2.45 + - libgcc >=14.3.0 + - libgcc-devel_linux-64 14.3.0 hf649bbc_119 + - libgomp >=14.3.0 + - libsanitizer 14.3.0 h8f1669f_19 + - libstdcxx >=14.3.0 + - libstdcxx-devel_linux-64 14.3.0 h9f08a49_119 + - sysroot_linux-64 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 77667192 + timestamp: 1778268558509 +- conda: https://prefix.dev/conda-forge/linux-64/gcc_impl_linux-64-15.2.0-he0086c7_19.conda + sha256: a48400ec4b73369c1c59babe4ad35821b63a88bba0ec40a80cea5f8c53a26b83 + md5: e3be72048d3c4a78b8e27ec48ba06252 + depends: + - binutils_impl_linux-64 >=2.45 + - libgcc >=15.2.0 + - libgcc-devel_linux-64 15.2.0 hcc6f6b0_119 + - libgomp >=15.2.0 + - libsanitizer 15.2.0 h90f66d4_19 + - libstdcxx >=15.2.0 + - libstdcxx-devel_linux-64 15.2.0 hd446a21_119 + - sysroot_linux-64 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 81180457 + timestamp: 1778269124617 +- conda: https://prefix.dev/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_25.conda + sha256: 95d22db25f0b8875febe63073f809c0c64f4026cc9e6aa0cca7130de51e4d044 + md5: 0a9089d9eeeeb23313a9ce670fb89052 + depends: + - gcc_impl_linux-64 14.3.0.* + - binutils_linux-64 + - sysroot_linux-64 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - libgcc >=14 + size: 29191 + timestamp: 1779371710532 +- conda: https://prefix.dev/conda-forge/linux-64/gcc_linux-64-15.2.0-h7be306e_25.conda + sha256: 3fbe01ebb16418d9f1971a283f969dc0f0e1071119f24164f4293057c79dc58c + md5: 46ca2358101b2477cb098c4248795d12 + depends: + - gcc_impl_linux-64 15.2.0.* + - binutils_linux-64 + - sysroot_linux-64 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - libgcc >=15 + size: 29190 + timestamp: 1779371750402 +- conda: https://prefix.dev/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_19.conda + sha256: a31694c26d6a525d44f81130ebf7b9abe18771b7eaecb2cf93630c0b8b8fb936 + md5: 8b867d053ed89743eeac52c3a50f112d + depends: + - gcc_impl_linux-64 14.3.0 h235f0fe_19 + - libstdcxx-devel_linux-64 14.3.0 h9f08a49_119 + - sysroot_linux-64 + - tzdata + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 15235650 + timestamp: 1778268773535 +- conda: https://prefix.dev/conda-forge/linux-64/gxx_impl_linux-64-15.2.0-hda75c37_19.conda + sha256: 3f5288346b9fe233352443b3c2e31f1fde845e39d3e96475fc05ec2e782af158 + md5: 9d41f3899b512199af0a4bb939b83e21 + depends: + - gcc_impl_linux-64 15.2.0 he0086c7_19 + - libstdcxx-devel_linux-64 15.2.0 hd446a21_119 + - sysroot_linux-64 + - tzdata + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 16356816 + timestamp: 1778269332159 +- conda: https://prefix.dev/conda-forge/linux-64/gxx_linux-64-14.3.0-h72ca5df_25.conda + sha256: 369abc77d74a8275c734f9ca2375892b86d3163a541b1f5a2de946083a9e3ab0 + md5: 4718c7fefd927621bad46a8bcc6387d6 + depends: + - gxx_impl_linux-64 14.3.0.* + - gcc_linux-64 ==14.3.0 h50e9bb6_25 + - binutils_linux-64 + - sysroot_linux-64 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - libstdcxx >=14 + - libgcc >=14 + size: 27696 + timestamp: 1779371710532 +- conda: https://prefix.dev/conda-forge/linux-64/gxx_linux-64-15.2.0-h1b0a0b8_25.conda + sha256: 24bc169bc881759107d5ad8c4e3c4ce259ea8542ae97f2e79ebc3a7214d34b1d + md5: 77a6c6a8ad55a302e7f407d37b4c451a + depends: + - gxx_impl_linux-64 15.2.0.* + - gcc_linux-64 ==15.2.0 h7be306e_25 + - binutils_linux-64 + - sysroot_linux-64 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - libstdcxx >=15 + - libgcc >=15 + size: 27702 + timestamp: 1779371750402 +- conda: https://prefix.dev/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + run_exports: + weak: + - keyutils >=1.6.3,<2.0a0 + size: 134088 + timestamp: 1754905959823 +- conda: https://prefix.dev/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25 + md5: fb53fb07ce46a575c5d004bbc96032c2 + depends: + - __glibc >=2.17,<3.0.a0 + - keyutils >=1.6.3,<2.0a0 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - libgcc >=14 + - libstdcxx >=14 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - krb5 >=1.22.2,<1.23.0a0 + size: 1386730 + timestamp: 1769769569681 +- conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c + md5: 18335a698559cdbcd86150a48bf54ba6 + depends: + - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - binutils_impl_linux-64 2.45.1 + license: GPL-3.0-only + license_family: GPL + run_exports: {} + size: 728002 + timestamp: 1774197446916 +- conda: https://prefix.dev/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda + sha256: 75963a5dd913311f59a35dbd307592f4fa754c4808aff9c33edb430c415e38eb + md5: c3cc2864f82a944bc90a7beb4d3b0e88 + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.22.2,<1.23.0a0 + - libgcc >=14 + - libnghttp2 >=1.68.1,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.6,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + run_exports: + weak: + - libcurl >=8.20.0,<9.0a0 + size: 468706 + timestamp: 1777461492876 +- conda: https://prefix.dev/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 + md5: c277e0a4d549b03ac1e9d6cbbe3d017b + depends: + - ncurses + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + run_exports: + weak: + - libedit >=3.1.20250104,<3.2.0a0 + size: 134676 + timestamp: 1738479519902 +- conda: https://prefix.dev/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 + depends: + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD + run_exports: + weak: + - libev >=4.33,<4.34.0a0 + size: 112766 + timestamp: 1702146165126 +- conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda + sha256: 363018b25fdb5534c79783d912bd4b685a3547f4fc5996357ad548899b0ee8e7 + md5: 93764a5ca80616e9c10106cdaec92f74 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + run_exports: {} + size: 77294 + timestamp: 1779278686680 +- conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + sha256: 8e0a3b5e41272e5678499b5dfc4cddb673f9e935de01eb0767ce857001229f46 + md5: 57736f29cc2b0ec0b6c2952d3f101b6a + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_19 + - libgomp 15.2.0 he0feb66_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 1041084 + timestamp: 1778269013026 +- conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + sha256: 9dcf54adfaa5e861123c2da4f2f0451a685464ea7e5a41ad91cf67b31d658d98 + md5: 331ee9b72b9dff570d56b1302c5ab37d + depends: + - libgcc 15.2.0 he0feb66_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: + strong: + - libgcc + size: 27694 + timestamp: 1778269016987 +- conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + sha256: 5abe4ab9d93f6c9757d654f1969ae2267d4505315c1f2f8fe705fd60af084f1b + md5: faac990cb7aedc7f3a2224f2c9b0c26c + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: + strong: + - _openmp_mutex >=4.5 + size: 603817 + timestamp: 1778268942614 +- conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d + md5: b88d90cad08e6bc8ad540cb310a761fb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - xz 5.8.3.* + license: 0BSD + run_exports: + weak: + - liblzma >=5.8.3,<6.0a0 + size: 113478 + timestamp: 1775825492909 +- conda: https://prefix.dev/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + sha256: 663444d77a42f2265f54fb8b48c5450bfff4388d9c0f8253dd7855f0d993153f + md5: 2a45e7f8af083626f009645a6481f12d + depends: + - __glibc >=2.17,<3.0.a0 + - c-ares >=1.34.6,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libnghttp2 >=1.68.1,<2.0a0 + size: 663344 + timestamp: 1773854035739 +- conda: https://prefix.dev/conda-forge/linux-64/libnvptxcompiler-dev-12.9.86-ha770c72_2.conda + sha256: 1e7a7b34f8639a5feb75ba864127059e4d83edfe1a516547f0dbb9941e7b8f8b + md5: 3fd926c321c6dbf386aa14bd8b125bfb + depends: + - cuda-version >=12.9,<12.10.0a0 + - libnvptxcompiler-dev_linux-64 12.9.86 ha770c72_2 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27046 + timestamp: 1753975516342 +- conda: https://prefix.dev/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_19.conda + sha256: 8766de5423b0a510e2b1bdd1963d0554bdad2119f3e31d8fbd4189af434235ca + md5: 007796e5a595bbc7df4a5e1580d72e1a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14.3.0 + - libstdcxx >=14.3.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: + weak: + - libsanitizer 14.3.0 + size: 7947790 + timestamp: 1778268494844 +- conda: https://prefix.dev/conda-forge/linux-64/libsanitizer-15.2.0-h90f66d4_19.conda + sha256: 7a58892a52739ce4c0f7109de9e91b4353104748eb04fc6441d88e8af444ba99 + md5: 67eef12ce33f7ff99900c212d7076fc2 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=15.2.0 + - libstdcxx >=15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: + weak: + - libsanitizer 15.2.0 + size: 7930689 + timestamp: 1778269054623 +- conda: https://prefix.dev/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 + md5: eecce068c7e4eddeb169591baac20ac4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libssh2 >=1.11.1,<2.0a0 + size: 304790 + timestamp: 1745608545575 +- conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda + sha256: dff1058c76ec6b8759e41cefa2508162d00e4a5e6721aa68ec3fd10094e702dc + md5: 5794b3bdc38177caf969dabd3af08549 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_19 + constrains: + - libstdcxx-ng ==15.2.0=*_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 5852044 + timestamp: 1778269036376 +- conda: https://prefix.dev/conda-forge/linux-64/libuv-1.52.1-h280c20c_0.conda + sha256: e28e4519223f78b3163599ca89c3f2d80bfb53e907e7fc74e806e60d1efa578b + md5: 4e33d49bf4fc853855a3b00643aa5484 + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libuv >=1.52.1,<2.0a0 + size: 419935 + timestamp: 1779396012261 +- conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 + md5: d87ff7921124eccd67248aa483c23fec + depends: + - __glibc >=2.17,<3.0.a0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + run_exports: + weak: + - libzlib >=1.3.2,<2.0a0 + size: 63629 + timestamp: 1774072609062 +- conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 + md5: fc21868a1a5aacc937e7a18747acb8a5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: X11 AND BSD-3-Clause + run_exports: + weak: + - ncurses >=6.6,<7.0a0 + size: 918956 + timestamp: 1777422145199 +- conda: https://prefix.dev/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + sha256: 6f7d59dbec0a7b00bf5d103a4306e8886678b796ff2151b62452d4582b2a53fb + md5: b518e9e92493721281a60fa975bddc65 + depends: + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 186323 + timestamp: 1763688260928 +- conda: https://prefix.dev/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb + md5: da1b85b6a87e141f5140bb9924cecab0 + depends: + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + run_exports: + weak: + - openssl >=3.6.2,<4.0a0 + size: 3167099 + timestamp: 1775587756857 +- conda: https://prefix.dev/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + sha256: d5c73079c1dd2c2a313c3bfd81c73dbd066b7eb08d213778c8bff520091ae894 + md5: c1c9b02933fdb2cfb791d936c20e887e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + run_exports: + weak: + - rhash >=1.4.6,<2.0a0 + size: 193775 + timestamp: 1748644872902 +- conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - zstd >=1.5.7,<1.6.0a0 + size: 601375 + timestamp: 1764777111296 +- conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.5.20-h4c7d964_0.conda + sha256: 86981d764e4ea1883409d30447ff9da46127426d31a63df08315aaded768e652 + md5: c9b86eece2f944541b86441c94117ab3 + depends: + - __win + license: ISC + run_exports: {} + size: 130182 + timestamp: 1779289939595 +- conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b + md5: 489b8e97e666c93f68fdb35c3c9b957f + depends: + - __unix + license: ISC + run_exports: {} + size: 129868 + timestamp: 1779289852439 +- conda: https://prefix.dev/conda-forge/noarch/compiler-rt22_osx-64-22.1.7-hcf80936_0.conda + sha256: 87c48a861f8c06c2be4f8ad7e7b774e2c6d4891e617dc6461d9c670bae17b790 + md5: 9829c9c1cd2b57757ccb80aa1f5ab019 + constrains: + - compiler-rt >=9.0.1 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 10910520 + timestamp: 1780458666064 +- conda: https://prefix.dev/conda-forge/noarch/compiler-rt22_osx-arm64-22.1.7-h7e67a1e_0.conda + sha256: f3d32eba79cd7815b20277c5a0dc0b265d7f5ca0eabad9daa6fd68be87fb8af7 + md5: 08a65a1a0cf1ca2053c7179e534b685e + constrains: + - compiler-rt >=9.0.1 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 10727649 + timestamp: 1780457616663 +- conda: https://prefix.dev/conda-forge/noarch/compiler-rt_osx-64-22.1.7-h694c41f_0.conda + sha256: a5118bf285946d0a04e0d5bf989b729340d72b317a6b115d6c41e8dfe959081e + md5: c6e2bd3d209f0bf87ad5bc3a8046fef4 + depends: + - compiler-rt22_osx-64 22.1.7 hcf80936_0 + constrains: + - clang 22.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 16809 + timestamp: 1780458741409 +- conda: https://prefix.dev/conda-forge/noarch/compiler-rt_osx-arm64-22.1.7-hce30654_0.conda + sha256: fc9f7f6322088f2efc014dac83219cd00e42583dc6502c7314c98183b6554c3d + md5: c49b5fb0d1b3d9a4c6e2dff11fdf51fd + depends: + - compiler-rt22_osx-arm64 22.1.7 h7e67a1e_0 + constrains: + - clang 22.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 16797 + timestamp: 1780457650249 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cccl_linux-64-12.9.27-ha770c72_0.conda + sha256: 2ee3b9564ca326226e5cda41d11b251482df8e7c757e333d28ec75213c75d126 + md5: 87ff6381e33b76e5b9b179a2cdd005ec + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 1150650 + timestamp: 1746189825236 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cccl_win-64-12.9.27-h57928b3_0.conda + sha256: 681eb1d9afd596e04329a82b04734c0e37c6ecb94b3380f3a378d61983e2a8cc + md5: 8f897dca7111f3bb4ded97ba6947b186 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 1139649 + timestamp: 1746189858434 +- conda: https://prefix.dev/conda-forge/noarch/cuda-crt-dev_linux-64-12.9.86-ha770c72_2.conda + sha256: e6257534c4b4b6b8a1192f84191c34906ab9968c92680fa09f639e7846a87304 + md5: 79d280de61e18010df5997daea4743df + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 94239 + timestamp: 1753975242354 +- conda: https://prefix.dev/conda-forge/noarch/cuda-crt-dev_win-64-12.9.86-h57928b3_2.conda + sha256: 2fccde18cafec3cdb6697f37c576567ac623dc69531e2a81bbc83d8a86a82d1f + md5: 569c55bd368307e48191a2ed54c64428 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 95452 + timestamp: 1753975640812 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda + sha256: ffe86ed0144315b276f18020d836c8ef05bf971054cf7c3eb167af92494080d5 + md5: 86e40eb67d83f1a58bdafdd44e5a77c6 + depends: + - cuda-cccl_linux-64 + - cuda-cudart-static_linux-64 + - cuda-cudart_linux-64 + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: + weak: + - cuda-cudart >=12.9.79,<13.0a0 + size: 389140 + timestamp: 1749218427266 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-dev_win-64-12.9.79-he0c23c2_0.conda + sha256: e022d36a333420130faf6473c49f8dab54bf976cf320577ffb06db0a0797b734 + md5: 3c3e2f6b5455783fd332a072d632ea78 + depends: + - cuda-cccl_win-64 + - cuda-cudart-static_win-64 + - cuda-cudart_win-64 + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: + weak: + - cuda-cudart >=12.9.79,<13.0a0 + size: 1190184 + timestamp: 1749218971019 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-static_linux-64-12.9.79-h3f2d84a_0.conda + sha256: d435f8a19b59b52ce460ee3a6bfd877288a0d1d645119a6ba60f1c3627dc5032 + md5: b87bf315d81218dd63eb46cc1eaef775 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 1148889 + timestamp: 1749218381225 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cudart-static_win-64-12.9.79-he0c23c2_0.conda + sha256: 6a3410cd7ce07955cb705801055ef129ebee1cd6390c6fe9e5f607b67c3dba36 + md5: 0dd152a1493d90356037604a865f050f + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 354611 + timestamp: 1749218544740 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cudart_linux-64-12.9.79-h3f2d84a_0.conda + sha256: 6cde0ace2b995b49d0db2eefb7bc30bf00ffc06bb98ef7113632dec8f8907475 + md5: 64508631775fbbf9eca83c84b1df0cae + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 197249 + timestamp: 1749218394213 +- conda: https://prefix.dev/conda-forge/noarch/cuda-cudart_win-64-12.9.79-he0c23c2_0.conda + sha256: 6a89a53cdbcfafa0bb55abee1b58492c6a9a28e688abe04f48f0d01649c5f3e4 + md5: 71c9c2ab52226f990f268164381d8494 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 23260 + timestamp: 1749218569458 +- conda: https://prefix.dev/conda-forge/noarch/cuda-driver-dev_linux-64-12.9.79-h3f2d84a_0.conda + sha256: a15574d966e73135a79d5e6570c87e13accdb44bd432449b5deea71644ad442c + md5: d411828daa36ac84eab210ba3bbe5a64 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 37714 + timestamp: 1749218405324 +- conda: https://prefix.dev/conda-forge/noarch/cuda-nvcc-dev_linux-64-12.9.86-he91c749_2.conda + sha256: a1672a34439a72869de9e011e935d41b62fc8dfb1a2700e85ed8a7a129b79981 + md5: 19d4e090217f0ea89d30bedb7461c048 + depends: + - cuda-crt-dev_linux-64 12.9.86 ha770c72_2 + - cuda-nvvm-dev_linux-64 12.9.86 ha770c72_2 + - cuda-version >=12.9,<12.10.0a0 + - libgcc >=6 + - libnvptxcompiler-dev_linux-64 12.9.86 ha770c72_2 + constrains: + - gcc_impl_linux-64 >=6,<15.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 28121 + timestamp: 1753975535813 +- conda: https://prefix.dev/conda-forge/noarch/cuda-nvcc-dev_win-64-12.9.86-h36c15f3_2.conda + sha256: e50255fe30f60135414e8b657c4ffdb12938af06463c959280eceb7166f69eb5 + md5: 20c8a059c5175ab804e7fc94213eb464 + depends: + - cuda-crt-dev_win-64 12.9.86 h57928b3_2 + - cuda-nvvm-dev_win-64 12.9.86 h57928b3_2 + - cuda-version >=12.9,<12.10.0a0 + - libnvptxcompiler-dev_win-64 12.9.86 h57928b3_2 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 23452957 + timestamp: 1753976361068 +- conda: https://prefix.dev/conda-forge/noarch/cuda-nvvm-dev_linux-64-12.9.86-ha770c72_2.conda + sha256: 522722dcaffd133e0c7500c69dc70e21ac34d6762dcbaabfe847439f944028f0 + md5: 7b386291414c7eea113d25ac28a33772 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27096 + timestamp: 1753975261562 +- conda: https://prefix.dev/conda-forge/noarch/cuda-nvvm-dev_win-64-12.9.86-h57928b3_2.conda + sha256: 455dbf0ec81efdbd40c0387d82c77689721f6d34b6e7694ca0d51bad9392eddc + md5: 23f7e70c03eabd2139b5e659c8e188b4 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27284 + timestamp: 1753975714790 +- conda: https://prefix.dev/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda + sha256: 5f5f428031933f117ff9f7fcc650e6ea1b3fef5936cf84aa24af79167513b656 + md5: b6d5d7f1c171cbd228ea06b556cfa859 + constrains: + - cudatoolkit 12.9|12.9.* + - __cuda >=12 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 21578 + timestamp: 1746134436166 +- conda: https://prefix.dev/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda + sha256: 41557eeadf641de6aeae49486cef30d02a6912d8da98585d687894afd65b356a + md5: 86d9cba083cd041bfbf242a01a7a1999 + constrains: + - sysroot_linux-64 ==2.28 + license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later + license_family: GPL + run_exports: {} + size: 1278712 + timestamp: 1765578681495 +- conda: https://prefix.dev/conda-forge/noarch/libcxx-headers-22.1.7-h707e725_0.conda + sha256: 06368b93aa7936d52854e8ee05845736f225c960d93cfd17ec8062ec3d2b55ed + md5: b0952b7a26c0f00cb78b9dc04f99dec7 + depends: + - __unix + constrains: + - libcxx-devel 22.1.7 + - clangxx >=19 + - gxx_osx-64 >=14 + - gxx_linux-64 >=14 + - gxx_osx-arm64 >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 1149765 + timestamp: 1780441705384 +- conda: https://prefix.dev/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_119.conda + sha256: e1815bb11d5abe886979e95889d84310d83d078d36a3567ca67cbf57a3876d88 + md5: 7d517e32d656a8880d98c0e4fc8ddc2c + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 3091520 + timestamp: 1778268364856 +- conda: https://prefix.dev/conda-forge/noarch/libgcc-devel_linux-64-15.2.0-hcc6f6b0_119.conda + sha256: 38a557eba305468ac1f90ac85e50d8defd76141cb0b8a43b2fc1aca71dd5d5f2 + md5: 683fcb168e1df9a21fa80d5aa2d9330b + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 3095909 + timestamp: 1778268932148 +- conda: https://prefix.dev/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda + sha256: 17952c32eac197a59c119fdf3fb6f08c6a29c225a80bae141ac904ad212b87dd + md5: a66a909acf08924aced622903832a937 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 14422867 + timestamp: 1753975387297 +- conda: https://prefix.dev/conda-forge/noarch/libnvptxcompiler-dev_win-64-12.9.86-h57928b3_2.conda + sha256: 9858bc91d01ab6d3a21039f37c8e22e3cb59542b7d308098b10bbe2b12be0aaa + md5: 77baf6d1c6916a86ab99ce4e83282e4f + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 31818844 + timestamp: 1753976049670 +- conda: https://prefix.dev/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_119.conda + sha256: 1b4263aa5d8c8c659e8e38b66868f42867347e0c8941513ee77269afc00a5186 + md5: d1a866495b9654ccfef5392b8541dc58 + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 20199810 + timestamp: 1778268389428 +- conda: https://prefix.dev/conda-forge/noarch/libstdcxx-devel_linux-64-15.2.0-hd446a21_119.conda + sha256: a2385f3611d5cd25378f9cf2367183320731709c067ddd08d43330d3170f15b8 + md5: bcfe7eae40158c3e355d2f9d3ed41230 + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + run_exports: {} + size: 20765069 + timestamp: 1778268963689 +- conda: https://prefix.dev/conda-forge/noarch/sdkroot_env_osx-64-26.0-h62b880e_7.conda + sha256: 7e7e2556978bc9bd9628c6e39138c684082320014d708fbca0c9050df98c0968 + md5: 68a978f77c0ba6ca10ce55e188a21857 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 4948 + timestamp: 1771434185960 +- conda: https://prefix.dev/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda + sha256: fabfe031ede99898cb2b0b805f6c0d64fcc24ecdb444de3a83002d8135bf4804 + md5: 5f0ebbfea12d8e5bddff157e271fdb2f + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 4971 + timestamp: 1771434195389 +- conda: https://prefix.dev/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda + sha256: c47299fe37aebb0fcf674b3be588e67e4afb86225be4b0d452c7eb75c086b851 + md5: 13dc3adbc692664cd3beabd216434749 + depends: + - __glibc >=2.28 + - kernel-headers_linux-64 4.18.0 he073ed8_9 + - tzdata + license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later + license_family: GPL + run_exports: + strong: + - __glibc >=2.28,<3.0.a0 + size: 24008591 + timestamp: 1765578833462 +- conda: https://prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 + license: LicenseRef-Public-Domain + run_exports: {} + size: 119135 + timestamp: 1767016325805 +- conda: https://prefix.dev/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda + sha256: b72270395326dc56de9bd6ca82f63791b3c8c9e2b98e25242a9869a4ca821895 + md5: f622897afff347b715d046178ad745a5 + depends: + - __win + license: MIT + license_family: MIT + run_exports: {} + size: 238764 + timestamp: 1745560912727 +- conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + sha256: 9f242f13537ef1ce195f93f0cc162965d6cc79da578568d6d8e50f70dd025c42 + md5: 4173ac3b19ec0a4f400b4f782910368b + depends: + - __osx >=10.13 + license: bzip2-1.0.6 + license_family: BSD + run_exports: + weak: + - bzip2 >=1.0.8,<2.0a0 + size: 133427 + timestamp: 1771350680709 +- conda: https://prefix.dev/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + sha256: 2f5bc0292d595399df0d168355b4e9820affc8036792d6984bd751fdda2bcaea + md5: fc9a153c57c9f070bebaa7eef30a8f17 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + run_exports: + weak: + - c-ares >=1.34.6,<2.0a0 + size: 186122 + timestamp: 1765215100384 +- conda: https://prefix.dev/conda-forge/osx-64/cctools_impl_osx-64-1030.6.3-llvm22_1_h8fe25a2_4.conda + sha256: 9e003c254b6c1880e6c8f2d777b20d837db2b7aff161454d857693692fd862dd + md5: 5d0b3b0b085354afc3b53c424e40121b + depends: + - __osx >=11.0 + - ld64_osx-64 >=956.6,<956.7.0a0 + - libcxx + - libllvm22 >=22.1.0,<22.2.0a0 + - libzlib >=1.3.1,<2.0a0 + - llvm-tools 22.1.* + - sigtool-codesign + constrains: + - clang 22.1.* + - cctools 1030.6.3.* + - ld64 956.6.* + license: APSL-2.0 + license_family: Other + run_exports: {} + size: 744001 + timestamp: 1772019049683 +- conda: https://prefix.dev/conda-forge/osx-64/cctools_osx-64-1030.6.3-llvm22_1_h0a1bb1c_4.conda + sha256: e0eefd2d7b4c8434b1b97ddf51780601e4ea5c964bb053775213868412367bbe + md5: d97b4a7d3a90d1cd45ff42ee353efadc + depends: + - cctools_impl_osx-64 1030.6.3 llvm22_1_h8fe25a2_4 + - ld64_osx-64 956.6 llvm22_1_h163eae7_4 + constrains: + - cctools 1030.6.3.* + license: APSL-2.0 + license_family: Other + run_exports: {} + size: 23441 + timestamp: 1772019105060 +- conda: https://prefix.dev/conda-forge/osx-64/clang-22-22.1.7-default_h3b8fe2e_1.conda + sha256: 8acd160b174fe02c61efd926b574d0bce11fc800ab1b8882817461f7940b2561 + md5: a0c754cdc84949d979bc15462df8c0ee + depends: + - __osx >=11.0 + - compiler-rt22 22.1.7.* + - libclang-cpp22.1 22.1.7 default_h9399c5b_1 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 826158 + timestamp: 1780524355900 +- conda: https://prefix.dev/conda-forge/osx-64/clang-scan-deps-22.1.7-default_h9399c5b_1.conda + sha256: aa12e6e62ac9845a9cc342c94f36970edb95350f53db67465ba2372221931bad + md5: 6f587e560f651de770491081a8ee3f03 + depends: + - __osx >=11.0 + - libclang-cpp22.1 >=22.1.7,<22.2.0a0 + - libclang13 >=22.1.7 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 110985 + timestamp: 1780524880282 +- conda: https://prefix.dev/conda-forge/osx-64/clang_impl_osx-64-22.1.7-default_hb18168d_1.conda + sha256: f9a91571fc4c63030e79a8e7aad11a0a42e451f3fc624bb893a7189141a2ffad + md5: cded0f2d26fa6d3163451cb64840d3ee + depends: + - cctools_impl_osx-64 + - clang-22 22.1.7 default_h3b8fe2e_1 + - compiler-rt 22.1.7.* + - compiler-rt_osx-64 + - ld64_osx-64 * llvm22_1_* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 29139 + timestamp: 1780524488866 +- conda: https://prefix.dev/conda-forge/osx-64/clang_osx-64-22.1.7-hb0d1528_32.conda + sha256: 719d2bda314068a6446fde8673a931764e43dec2f8017b66d51232fd1898aeec + md5: 443550581ad436305c85b7b11ec7d908 + depends: + - cctools_osx-64 + - clang_impl_osx-64 22.1.7.* + - sdkroot_env_osx-64 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 21209 + timestamp: 1780546451340 +- conda: https://prefix.dev/conda-forge/osx-64/clangxx_impl_osx-64-22.1.7-default_hb18168d_1.conda + sha256: 8429fdd3216fe5625045413b71134ac5d253714bfff78c5fffa6d609fd37c08c + md5: add2be2d94e8e2bc1a015134e2ffbc32 + depends: + - clang-22 22.1.7 default_h3b8fe2e_1 + - clang-scan-deps 22.1.7 default_h9399c5b_1 + - clang_impl_osx-64 22.1.7 default_hb18168d_1 + - libcxx-devel 22.1.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 29064 + timestamp: 1780524906511 +- conda: https://prefix.dev/conda-forge/osx-64/clangxx_osx-64-22.1.7-hb0d1528_32.conda + sha256: 23e6caad7a9677d517119467ee74214aa553876230f0c7b20be9396fd032ec57 + md5: 7e37c3a1cc4224ed4861ee310b8daae9 + depends: + - cctools_osx-64 + - clang_osx-64 22.1.7 hb0d1528_32 + - clangxx_impl_osx-64 22.1.7.* + - sdkroot_env_osx-64 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - libcxx >=22 + size: 20033 + timestamp: 1780546460416 +- conda: https://prefix.dev/conda-forge/osx-64/cmake-4.3.3-h2426fb6_0.conda + sha256: be84ff61332b844c24c5996f48b85be5600bf30715ce9d21090f7ea964f65f38 + md5: 4349fad6b55a5ed7b572f750678eba79 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.20.0,<9.0a0 + - libcxx >=19 + - libexpat >=2.8.1,<3.0a0 + - liblzma >=5.8.3,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 19487980 + timestamp: 1779399784343 +- conda: https://prefix.dev/conda-forge/osx-64/compiler-rt-22.1.7-h694c41f_0.conda + sha256: 057879f1f517b25a2394639fcedfc04005f6bbf63ab003182bc479e641db2b2c + md5: d3834d21abeff2613f6c806ff41a3059 + depends: + - compiler-rt22 22.1.7 h1637cdf_0 + - libcompiler-rt 22.1.7 h1637cdf_0 + constrains: + - clang 22.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 16675 + timestamp: 1780458743280 +- conda: https://prefix.dev/conda-forge/osx-64/compiler-rt22-22.1.7-h1637cdf_0.conda + sha256: f67af723c48fa4c789d1b3cdcde618d7479622fd410cb51f9457f0b70dc8c13d + md5: 1366301c61cad16bcdbf00c9f43576cf + depends: + - __osx >=11.0 + - compiler-rt22_osx-64 22.1.7.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 99264 + timestamp: 1780458739013 +- conda: https://prefix.dev/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda + sha256: df009385e8262c234c0dae9016540b86dad3d299f0d9366d08e327e8e7731634 + md5: e66e2c52d2fdddcf314ad750fb4ebb4a + depends: + - __osx >=10.13 + - libcxx >=19 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - krb5 >=1.22.2,<1.23.0a0 + size: 1193620 + timestamp: 1769770267475 +- conda: https://prefix.dev/conda-forge/osx-64/ld64_osx-64-956.6-llvm22_1_h163eae7_4.conda + sha256: e49272192003e0e30edd6877197db3c220bb374a78d5b255d18c7a029cd33c1e + md5: 9e6646598daf11bd8ebc60d690162ebd + depends: + - __osx >=11.0 + - libcxx + - libllvm22 >=22.1.0,<22.2.0a0 + - sigtool-codesign + - tapi >=1600.0.11.8,<1601.0a0 + constrains: + - clang 22.1.* + - cctools 1030.6.3.* + - cctools_impl_osx-64 1030.6.3.* + - ld64 956.6.* + license: APSL-2.0 + license_family: Other + run_exports: {} + size: 1110951 + timestamp: 1772018988810 +- conda: https://prefix.dev/conda-forge/osx-64/libclang-cpp22.1-22.1.7-default_h9399c5b_1.conda + sha256: f354e26f811a31427ff4cc4695a6773187bb2ac9ad9197eebf41da470e637968 + md5: 135131fca92856cfe4e32af9ffbfc9c2 + depends: + - __osx >=11.0 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang-cpp22.1 >=22.1.7,<22.2.0a0 + size: 15007643 + timestamp: 1780524215578 +- conda: https://prefix.dev/conda-forge/osx-64/libclang13-22.1.7-default_h2429e1b_1.conda + sha256: a9c032f78b73c702948230c3ba8afed31f54213316bf5beb767303500973b585 + md5: 366d0c7b1675b6af6bad3ec17be9fe2a + depends: + - __osx >=11.0 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang13 >=22.1.7 + size: 9464895 + timestamp: 1780524651031 +- conda: https://prefix.dev/conda-forge/osx-64/libcompiler-rt-22.1.7-h1637cdf_0.conda + sha256: d0ef06b0c7d1312e572f3726b867f81e22eed158e6255b66e58448ede7647b49 + md5: 45d588315fef679cd57cf06ccbc1a6ab + depends: + - __osx >=11.0 + constrains: + - compiler-rt >=9.0.1 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: + weak: + - libcompiler-rt >=22.1.7 + size: 1374021 + timestamp: 1780458717254 +- conda: https://prefix.dev/conda-forge/osx-64/libcurl-8.20.0-h8f0b9e4_0.conda + sha256: 5d3d8a82ca43347e96f1d79048921f3a7c25e32514bc7feb53ed2a040dcca54d + md5: 4a0085ccf90dc514f0fc0909a874045e + depends: + - __osx >=11.0 + - krb5 >=1.22.2,<1.23.0a0 + - libnghttp2 >=1.68.1,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.6,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + run_exports: + weak: + - libcurl >=8.20.0,<9.0a0 + size: 419676 + timestamp: 1777462238769 +- conda: https://prefix.dev/conda-forge/osx-64/libcxx-22.1.7-h19cb2f5_0.conda + sha256: c03c298355dea54b729ed6c5f1e6dbd0e2426906039eba8aa2ba1254d005b7d8 + md5: 423373b842c3861da6cfa8c8915798ce + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 564939 + timestamp: 1780442565078 +- conda: https://prefix.dev/conda-forge/osx-64/libcxx-devel-22.1.7-h7c275be_0.conda + sha256: 0edb65123ffe6cd42a600c00a2cb5788159e684fd8c8722597a4dd11ccc1a974 + md5: a33b3177fcd572fb864e074bb317c44f + depends: + - libcxx >=22.1.7 + - libcxx-headers >=22.1.7,<22.1.8.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 22337 + timestamp: 1780442600081 +- conda: https://prefix.dev/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + sha256: 6cc49785940a99e6a6b8c6edbb15f44c2dd6c789d9c283e5ee7bdfedd50b4cd6 + md5: 1f4ed31220402fcddc083b4bff406868 + depends: + - ncurses + - __osx >=10.13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + run_exports: + weak: + - libedit >=3.1.20250104,<3.2.0a0 + size: 115563 + timestamp: 1738479554273 +- conda: https://prefix.dev/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + sha256: 0d238488564a7992942aa165ff994eca540f687753b4f0998b29b4e4d030ff43 + md5: 899db79329439820b7e8f8de41bca902 + license: BSD-2-Clause + license_family: BSD + run_exports: + weak: + - libev >=4.33,<4.34.0a0 + size: 106663 + timestamp: 1702146352558 +- conda: https://prefix.dev/conda-forge/osx-64/libexpat-2.8.1-hcc62823_0.conda + sha256: 460afe7ba0882e6d2fcc0ad1568dce27025110ec09c2b9ce9e3b49d61e52ce6b + md5: f95dc08366f2a452005062b5bcceac51 + depends: + - __osx >=11.0 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + run_exports: {} + size: 75654 + timestamp: 1779279058576 +- conda: https://prefix.dev/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + sha256: a1c8cecdf9966921e13f0ae921309a1f415dfbd2b791f2117cf7e8f5e61a48b6 + md5: 210a85a1119f97ea7887188d176db135 + depends: + - __osx >=10.13 + license: LGPL-2.1-only + run_exports: + weak: + - libiconv >=1.18,<2.0a0 + size: 737846 + timestamp: 1754908900138 +- conda: https://prefix.dev/conda-forge/osx-64/libllvm22-22.1.7-hab754da_0.conda + sha256: 9ef76e7c6a078cbead8a462af85cfae4f8fe2a9480ec0ee483f00332703a02ca + md5: c198bc1edfa11159777da98e194d06f3 + depends: + - __osx >=11.0 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.2,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libllvm22 >=22.1.7,<22.2.0a0 + size: 31842884 + timestamp: 1780447725513 +- conda: https://prefix.dev/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda + sha256: d9e2006051529aec5578c6efeb13bb6a7200a014b2d5a77a579e83a8049d5f3c + md5: becdfbfe7049fa248e52aa37a9df09e2 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.3.* + license: 0BSD + run_exports: + weak: + - liblzma >=5.8.3,<6.0a0 + size: 105724 + timestamp: 1775826029494 +- conda: https://prefix.dev/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda + sha256: 899551e16aac9dfb85bfc2fd98b655f4d1b7fea45720ec04ccb93d95b4d24798 + md5: dba4c95e2fe24adcae4b77ebf33559ae + depends: + - __osx >=11.0 + - c-ares >=1.34.6,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libnghttp2 >=1.68.1,<2.0a0 + size: 606749 + timestamp: 1773854765508 +- conda: https://prefix.dev/conda-forge/osx-64/libsigtool-0.1.3-hc0f2934_0.conda + sha256: f87b743d5ab11c1a8ddd800dd9357fc0fabe47686068232ddc1d1eed0d7321ec + md5: 3576aba85ce5e9ab15aa0ea376ab864b + depends: + - __osx >=10.13 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + run_exports: {} + size: 38085 + timestamp: 1767044977731 +- conda: https://prefix.dev/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda + sha256: 00654ba9e5f73aa1f75c1f69db34a19029e970a4aeb0fa8615934d8e9c369c3c + md5: a6cb15db1c2dc4d3a5f6cf3772e09e81 + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libssh2 >=1.11.1,<2.0a0 + size: 284216 + timestamp: 1745608575796 +- conda: https://prefix.dev/conda-forge/osx-64/libuv-1.52.1-ha3d0635_0.conda + sha256: a77c3832a82b26afe8da3f4bbacca58a943cc62f2a5680547913650527a51299 + md5: 703303067839cd1da659528a84b3c0cc + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + run_exports: + weak: + - libuv >=1.52.1,<2.0a0 + size: 128150 + timestamp: 1779396112490 +- conda: https://prefix.dev/conda-forge/osx-64/libxml2-16-2.15.3-h0d7f165_0.conda + sha256: daa69a1dd887b2dbac44327bc5af73a4d41fa63bc6dc609782fdda9aec187895 + md5: 5eb194ed01ed3f5a64b6fcec1b399d96 + depends: + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - icu <0.0a0 + - libxml2 2.15.3 + license: MIT + license_family: MIT + run_exports: {} + size: 495267 + timestamp: 1776377547505 +- conda: https://prefix.dev/conda-forge/osx-64/libxml2-2.15.3-h0712280_0.conda + sha256: caf6e73fa53c3dec3227ea67de231b0f7009544252684e816c6f2f414aeb55c9 + md5: 81ac54c8b2eb51fceb94eb0817b93cf3 + depends: + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libxml2-16 2.15.3 h0d7f165_0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libxml2 + - libxml2-16 >=2.15.3 + size: 40803 + timestamp: 1776377589058 +- conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + sha256: 4c6da089952b2d70150c74234679d6f7ac04f4a98f9432dec724968f912691e7 + md5: 30439ff30578e504ee5e0b390afc8c65 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + run_exports: + weak: + - libzlib >=1.3.2,<2.0a0 + size: 59000 + timestamp: 1774073052242 +- conda: https://prefix.dev/conda-forge/osx-64/llvm-tools-22-22.1.7-hc181bea_0.conda + sha256: 86158dd6e99018e83c4ecd0d504511efd284d242d891723b6fc7edab1fd41b44 + md5: 7b43a01695fe09c7786a99907312c588 + depends: + - __osx >=11.0 + - libcxx >=19 + - libllvm22 22.1.7 hab754da_0 + - libzlib >=1.3.2,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 18996311 + timestamp: 1780447964134 +- conda: https://prefix.dev/conda-forge/osx-64/llvm-tools-22.1.7-h1637cdf_0.conda + sha256: 432f04a68a18e487f4339d89bf8cea1054850fb92d0e3397605c219382892666 + md5: 40a7058aac858d574e37265a03b49777 + depends: + - __osx >=11.0 + - libllvm22 22.1.7 hab754da_0 + - llvm-tools-22 22.1.7 hc181bea_0 + constrains: + - llvm 22.1.7 + - clang-tools 22.1.7 + - clang 22.1.7 + - llvmdev 22.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 52128 + timestamp: 1780448062183 +- conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda + sha256: f5f7e006ff4271305ab4cc08eedd855c67a571793c3d18aff73f645f088a8cae + md5: 31b8740cf1b2588d4e61c81191004061 + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + run_exports: + weak: + - ncurses >=6.6,<7.0a0 + size: 831711 + timestamp: 1777423052277 +- conda: https://prefix.dev/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda + sha256: 1646832e3c2389595569ab9a6234c119a4dedf6f4e55532a8bf07edab7f8037d + md5: afda563484aa0017278866707807a335 + depends: + - libcxx >=19 + - __osx >=10.13 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 178071 + timestamp: 1763688235442 +- conda: https://prefix.dev/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + sha256: 334fd49ea31b99114f5afb1ec44555dc8c90640648302a4f8f838ee345d1ec50 + md5: 5cf0ece4375c73d7a5765e83565a69c7 + depends: + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + run_exports: + weak: + - openssl >=3.6.2,<4.0a0 + size: 2776564 + timestamp: 1775589970694 +- conda: https://prefix.dev/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda + sha256: 65c946fc5a9bb71772a7ac9bad64ff08ac07f7d5311306c2dcc1647157b96706 + md5: d0fcaaeff83dd4b6fb035c2f36df198b + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + run_exports: + weak: + - rhash >=1.4.6,<2.0a0 + size: 185180 + timestamp: 1748644989546 +- conda: https://prefix.dev/conda-forge/osx-64/sigtool-codesign-0.1.3-hc0f2934_0.conda + sha256: b89d89d0b62e0a84093205607d071932cca228d4d6982a5b073eec7e765b146d + md5: 1261fc730f1d8af7eeea8a0024b23493 + depends: + - __osx >=10.13 + - libsigtool 0.1.3 hc0f2934_0 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + run_exports: {} + size: 123083 + timestamp: 1767045007433 +- conda: https://prefix.dev/conda-forge/osx-64/tapi-1600.0.11.8-h8d8e812_2.conda + sha256: 0e814730160c8e214eadd7905e3659d8f52af86fd37d85fd287060748948a2b8 + md5: 524528dee57e42d77b1af677137de5a5 + depends: + - libcxx >=19.0.0.a0 + - __osx >=10.13 + - ncurses >=6.5,<7.0a0 + license: NCSA + run_exports: {} + size: 213790 + timestamp: 1775657389876 +- conda: https://prefix.dev/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f + md5: 727109b184d680772e3122f40136d5ca + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - zstd >=1.5.7,<1.6.0a0 + size: 528148 + timestamp: 1764777156963 +- conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df + md5: 620b85a3f45526a8bc4d23fd78fc22f0 + depends: + - __osx >=11.0 + license: bzip2-1.0.6 + license_family: BSD + run_exports: + weak: + - bzip2 >=1.0.8,<2.0a0 + size: 124834 + timestamp: 1771350416561 +- conda: https://prefix.dev/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + run_exports: + weak: + - c-ares >=1.34.6,<2.0a0 + size: 180327 + timestamp: 1765215064054 +- conda: https://prefix.dev/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm22_1_hb5e89dc_4.conda + sha256: 97075a1afeac8a7a4dca258ac10efb70638e3c734cbf5a6328ca1e0718e09c41 + md5: 97768bb89683757d7e535f9b7dcba39d + depends: + - __osx >=11.0 + - ld64_osx-arm64 >=956.6,<956.7.0a0 + - libcxx + - libllvm22 >=22.1.0,<22.2.0a0 + - libzlib >=1.3.1,<2.0a0 + - llvm-tools 22.1.* + - sigtool-codesign + constrains: + - clang 22.1.* + - ld64 956.6.* + - cctools 1030.6.3.* + license: APSL-2.0 + license_family: Other + run_exports: {} + size: 749166 + timestamp: 1772019681419 +- conda: https://prefix.dev/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm22_1_hbe26303_4.conda + sha256: c90c927dd77afb7d8115a3777b567d9ab84169ab797436d79789d75d0bd1a399 + md5: a08c9f61e81b5d4a0a653495545ec2b8 + depends: + - cctools_impl_osx-arm64 1030.6.3 llvm22_1_hb5e89dc_4 + - ld64_osx-arm64 956.6 llvm22_1_h692d5aa_4 + constrains: + - cctools 1030.6.3.* + license: APSL-2.0 + license_family: Other + run_exports: {} + size: 23468 + timestamp: 1772019757885 +- conda: https://prefix.dev/conda-forge/osx-arm64/clang-22-22.1.7-default_hd632d02_1.conda + sha256: 3a438c7a27c86ef14a41c991b8688ef53efe92ad1db8ae930f27fce410ca843a + md5: 36f28e96e3bff9566e44cc625b87408c + depends: + - __osx >=11.0 + - compiler-rt22 22.1.7.* + - libclang-cpp22.1 22.1.7 default_h8e162e0_1 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 830975 + timestamp: 1780519560746 +- conda: https://prefix.dev/conda-forge/osx-arm64/clang-scan-deps-22.1.7-default_h8e162e0_1.conda + sha256: e74079f18114767f34cf04bdae1fc682298de8cb18ea1257a40b2b4353e8f444 + md5: 8f7f50694d61c2575ff4c3b5fc670f11 + depends: + - __osx >=11.0 + - libclang-cpp22.1 >=22.1.7,<22.2.0a0 + - libclang13 >=22.1.7 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 103797 + timestamp: 1780519799318 +- conda: https://prefix.dev/conda-forge/osx-arm64/clang_impl_osx-arm64-22.1.7-default_h17d1ed9_1.conda + sha256: 09a6fa56849653389f4db79e548832dda874fa9255740a292adec0941a6b8902 + md5: 87567b36faebd1d3423321f5122096ae + depends: + - cctools_impl_osx-arm64 + - clang-22 22.1.7 default_hd632d02_1 + - compiler-rt 22.1.7.* + - compiler-rt_osx-arm64 + - ld64_osx-arm64 * llvm22_1_* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 29007 + timestamp: 1780519625415 +- conda: https://prefix.dev/conda-forge/osx-arm64/clang_osx-arm64-22.1.7-hf119d2b_32.conda + sha256: a14407fdd92a35b3410796b20f209abbe53f59ea6417c66bf900730a1efdf203 + md5: 75afaa2f7151ace4f1fff9b676db4d2e + depends: + - cctools_osx-arm64 + - clang_impl_osx-arm64 22.1.7.* + - sdkroot_env_osx-arm64 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 21218 + timestamp: 1780546185093 +- conda: https://prefix.dev/conda-forge/osx-arm64/clangxx_impl_osx-arm64-22.1.7-default_h17d1ed9_1.conda + sha256: 67decf053bc8af5988df69da7fe72ea6347969695eb34866e483514a03f2535e + md5: b102716463b3dfb518abcede39b8d44a + depends: + - clang-22 22.1.7 default_hd632d02_1 + - clang-scan-deps 22.1.7 default_h8e162e0_1 + - clang_impl_osx-arm64 22.1.7 default_h17d1ed9_1 + - libcxx-devel 22.1.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 29025 + timestamp: 1780519815159 +- conda: https://prefix.dev/conda-forge/osx-arm64/clangxx_osx-arm64-22.1.7-hf119d2b_32.conda + sha256: 2da93e46edee5bafeeab737cbeaad6670c699c423caae09ccad81afa31332a4f + md5: ddeb6549d832fae2d6a2cd6a297f17bf + depends: + - cctools_osx-arm64 + - clang_osx-arm64 22.1.7 hf119d2b_32 + - clangxx_impl_osx-arm64 22.1.7.* + - sdkroot_env_osx-arm64 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - libcxx >=22 + size: 20064 + timestamp: 1780546187683 +- conda: https://prefix.dev/conda-forge/osx-arm64/cmake-4.3.3-h8cb302d_0.conda + sha256: 09eab0e2876eeee3f619223e151b788e157771b7150038ee07fa768e8aff8e9e + md5: 7a6a2812529d5c8fa77c2653e303ba4f + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.20.0,<9.0a0 + - libcxx >=19 + - libexpat >=2.8.1,<3.0a0 + - liblzma >=5.8.3,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 18285327 + timestamp: 1779399044060 +- conda: https://prefix.dev/conda-forge/osx-arm64/compiler-rt-22.1.7-hce30654_0.conda + sha256: 721b702d79bf70de4e938e552dbae794ff60590ceb4594bd5dadcaf77fa90c8b + md5: c5bf9cc793f5cab214f90c5c0e1851e6 + depends: + - compiler-rt22 22.1.7 hd34ed20_0 + - libcompiler-rt 22.1.7 hd34ed20_0 + constrains: + - clang 22.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 16641 + timestamp: 1780457650764 +- conda: https://prefix.dev/conda-forge/osx-arm64/compiler-rt22-22.1.7-hd34ed20_0.conda + sha256: cfe6a196223f735b49b093586359615e059d9944b3cf049101a20ce135a94300 + md5: 3893c0e24c5f19efb9138762f0eb693c + depends: + - __osx >=11.0 + - compiler-rt22_osx-arm64 22.1.7.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: {} + size: 98795 + timestamp: 1780457649475 +- conda: https://prefix.dev/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed + md5: e446e1822f4da8e5080a9de93474184d + depends: + - __osx >=11.0 + - libcxx >=19 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - krb5 >=1.22.2,<1.23.0a0 + size: 1160828 + timestamp: 1769770119811 +- conda: https://prefix.dev/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm22_1_h692d5aa_4.conda + sha256: e4ae2ef85672c094aa3467d466f932ccdc1dda9bd4adac64f4252cc796149091 + md5: 4c2255bf859bff6c52ed38960e3bc963 + depends: + - __osx >=11.0 + - libcxx + - libllvm22 >=22.1.0,<22.2.0a0 + - sigtool-codesign + - tapi >=1600.0.11.8,<1601.0a0 + constrains: + - clang 22.1.* + - ld64 956.6.* + - cctools_impl_osx-arm64 1030.6.3.* + - cctools 1030.6.3.* + license: APSL-2.0 + license_family: Other + run_exports: {} + size: 1038027 + timestamp: 1772019602406 +- conda: https://prefix.dev/conda-forge/osx-arm64/libclang-cpp22.1-22.1.7-default_h8e162e0_1.conda + sha256: 27fe54bb8da8a80793bbd9346324cfbc9609cee498b79d6ae8cbd89e09c197be + md5: 08dd791ea92568bdca26bb174b2c0e3a + depends: + - __osx >=11.0 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang-cpp22.1 >=22.1.7,<22.2.0a0 + size: 14193041 + timestamp: 1780519486860 +- conda: https://prefix.dev/conda-forge/osx-arm64/libclang13-22.1.7-default_h6dd9417_1.conda + sha256: ec991f3050b3b43eeee6fc8697f5a25306a38f53d7cfdf80ab4e2587d21032b3 + md5: 3c8a80bf352e08e0d656b0f60a0a2980 + depends: + - __osx >=11.0 + - libcxx >=22.1.7 + - libllvm22 >=22.1.7,<22.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libclang13 >=22.1.7 + size: 8937899 + timestamp: 1780519686958 +- conda: https://prefix.dev/conda-forge/osx-arm64/libcompiler-rt-22.1.7-hd34ed20_0.conda + sha256: 35f6b1f2a1e61e043eb17aab49cccf65234d7cb137f26ed87ea7163f6937ab6b + md5: f5766b2bf9c3630b9bef99319629531d + depends: + - __osx >=11.0 + constrains: + - compiler-rt >=9.0.1 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + run_exports: + weak: + - libcompiler-rt >=22.1.7 + size: 1373087 + timestamp: 1780457641235 +- conda: https://prefix.dev/conda-forge/osx-arm64/libcurl-8.20.0-hd5a2499_0.conda + sha256: 38c0bc634b61e542776e97cfd15d5d41edd304d4e47c333004d2d622439b2381 + md5: 2f57b7d0c6adda88957586b7afd78438 + depends: + - __osx >=11.0 + - krb5 >=1.22.2,<1.23.0a0 + - libnghttp2 >=1.68.1,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.6,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + run_exports: + weak: + - libcurl >=8.20.0,<9.0a0 + size: 400568 + timestamp: 1777462251987 +- conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-22.1.7-h55c6f16_0.conda + sha256: cceb668dc1b71f054b1036dd83eca2e02c0c3a4b2ba3ad28c74a982d819597a3 + md5: 0325fbe13eb6dd39234eb305ac1b3cb8 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 568252 + timestamp: 1780441702930 +- conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-devel-22.1.7-h6dc3340_0.conda + sha256: 65eb55a59ba4f5a63d54c91ade942f0cd17a40c1390a390d3b46aec5e3dffbdb + md5: 3b3d6232b366a7d93956320b1b26c871 + depends: + - libcxx >=22.1.7 + - libcxx-headers >=22.1.7,<22.1.8.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 22195 + timestamp: 1780441714190 +- conda: https://prefix.dev/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 + md5: 44083d2d2c2025afca315c7a172eab2b + depends: + - ncurses + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + run_exports: + weak: + - libedit >=3.1.20250104,<3.2.0a0 + size: 107691 + timestamp: 1738479560845 +- conda: https://prefix.dev/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + run_exports: + weak: + - libev >=4.33,<4.34.0a0 + size: 107458 + timestamp: 1702146414478 +- conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_0.conda + sha256: 3133fb6bfa871288b92c8b8752696686a841bf4ffe035aa3038033c9e15b738e + md5: ef22e9ab1dc7c2f334252f565f90b3b8 + depends: + - __osx >=11.0 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + run_exports: {} + size: 69110 + timestamp: 1779278728511 +- conda: https://prefix.dev/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03 + md5: 4d5a7445f0b25b6a3ddbb56e790f5251 + depends: + - __osx >=11.0 + license: LGPL-2.1-only + run_exports: + weak: + - libiconv >=1.18,<2.0a0 + size: 750379 + timestamp: 1754909073836 +- conda: https://prefix.dev/conda-forge/osx-arm64/libllvm22-22.1.7-h89af1be_0.conda + sha256: 533929d04a94ee43431c6f7f0916b0f5a387f6b02b5339f06301bbfa9e180c84 + md5: 0525fa45bcc945c301ee8f583a442ce1 + depends: + - __osx >=11.0 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.2,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: + weak: + - libllvm22 >=22.1.7,<22.2.0a0 + size: 30014727 + timestamp: 1780441538232 +- conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + sha256: 34878d87275c298f1a732c6806349125cebbf340d24c6c23727268184bba051e + md5: b1fd823b5ae54fbec272cea0811bd8a9 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.3.* + license: 0BSD + run_exports: + weak: + - liblzma >=5.8.3,<6.0a0 + size: 92472 + timestamp: 1775825802659 +- conda: https://prefix.dev/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + sha256: 2bc7bc3978066f2c274ebcbf711850cc9ab92e023e433b9631958a098d11e10a + md5: 6ea18834adbc3b33df9bd9fb45eaf95b + depends: + - __osx >=11.0 + - c-ares >=1.34.6,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libnghttp2 >=1.68.1,<2.0a0 + size: 576526 + timestamp: 1773854624224 +- conda: https://prefix.dev/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda + sha256: 421f7bd7caaa945d9cd5d374cc3f01e75637ca7372a32d5e7695c825a48a30d1 + md5: c08557d00807785decafb932b5be7ef5 + depends: + - __osx >=11.0 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + run_exports: {} + size: 36416 + timestamp: 1767045062496 +- conda: https://prefix.dev/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a + md5: b68e8f66b94b44aaa8de4583d3d4cc40 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libssh2 >=1.11.1,<2.0a0 + size: 279193 + timestamp: 1745608793272 +- conda: https://prefix.dev/conda-forge/osx-arm64/libuv-1.52.1-h1a92334_0.conda + sha256: e23176af832f637693ebbb9bbe7d29c0f4cba662dabd001081d2aa6fc9f7f661 + md5: fa9fef7d9f33724b7c3899c883c25a3e + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + run_exports: + weak: + - libuv >=1.52.1,<2.0a0 + size: 122732 + timestamp: 1779396113397 +- conda: https://prefix.dev/conda-forge/osx-arm64/libxml2-16-2.15.3-h6967ea9_0.conda + sha256: 43895a7517c055b8893531290f9dc48bd751eb04be04f14bbce3b6c71b052be6 + md5: 6c8292c2ee808aeef2406083beaa6da7 + depends: + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - libxml2 2.15.3 + - icu <0.0a0 + license: MIT + license_family: MIT + run_exports: {} + size: 465820 + timestamp: 1776377317454 +- conda: https://prefix.dev/conda-forge/osx-arm64/libxml2-2.15.3-heed7d32_0.conda + sha256: 4d9c117b2dd222cf891710d5f6a570ebb275479979843a1477ac54ed50907b40 + md5: 0c1fdc80534d8f25fd74722aba81f044 + depends: + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libxml2-16 2.15.3 h6967ea9_0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + run_exports: + weak: + - libxml2 + - libxml2-16 >=2.15.3 + size: 41663 + timestamp: 1776377341241 +- conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + sha256: 361415a698514b19a852f5d1123c5da746d4642139904156ddfca7c922d23a05 + md5: bc5a5721b6439f2f62a84f2548136082 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + run_exports: + weak: + - libzlib >=1.3.2,<2.0a0 + size: 47759 + timestamp: 1774072956767 +- conda: https://prefix.dev/conda-forge/osx-arm64/llvm-tools-22-22.1.7-hb545844_0.conda + sha256: fd44ba14755380db3d89b75485c2e9a9982fefe54e7853d9a91a250948b2c48c + md5: 14e37880dc53c9da027752c005ddb7ec + depends: + - __osx >=11.0 + - libcxx >=19 + - libllvm22 22.1.7 h89af1be_0 + - libzlib >=1.3.2,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 17845007 + timestamp: 1780441650670 +- conda: https://prefix.dev/conda-forge/osx-arm64/llvm-tools-22.1.7-hd34ed20_0.conda + sha256: eafdac4500c69bed1e5964efc8f6a024a4a70f57a91e5c5e099bc9ed5ff4695b + md5: b0eff8fdd52342dc666a05ba33acf8f8 + depends: + - __osx >=11.0 + - libllvm22 22.1.7 h89af1be_0 + - llvm-tools-22 22.1.7 hb545844_0 + constrains: + - clang-tools 22.1.7 + - llvmdev 22.1.7 + - clang 22.1.7 + - llvm 22.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 52222 + timestamp: 1780441714363 +- conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + sha256: 4ea6c620b87bd1d42bb2ccc2c87cd2483fa2d7f9e905b14c223f11ff3f4c455d + md5: 343d10ed5b44030a2f67193905aea159 + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + run_exports: + weak: + - ncurses >=6.6,<7.0a0 + size: 805509 + timestamp: 1777423252320 +- conda: https://prefix.dev/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + sha256: 18d33c17b28d4771fc0b91b7b963c9ce31aca0a9af7dc8e9ee7c974bb207192c + md5: 175809cc57b2c67f27a0f238bd7f069d + depends: + - __osx >=11.0 + - libcxx >=19 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 164450 + timestamp: 1763688228613 +- conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + sha256: c91bf510c130a1ea1b6ff023e28bac0ccaef869446acd805e2016f69ebdc49ea + md5: 25dcccd4f80f1638428613e0d7c9b4e1 + depends: + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + run_exports: + weak: + - openssl >=3.6.2,<4.0a0 + size: 3106008 + timestamp: 1775587972483 +- conda: https://prefix.dev/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + sha256: f4957c05f4fbcd99577de8838ca4b5b1ae4b400a44be647a0159c14f85b9bfc0 + md5: 029e812c8ae4e0d4cf6ff4f7d8dc9366 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + run_exports: + weak: + - rhash >=1.4.6,<2.0a0 + size: 185448 + timestamp: 1748645057503 +- conda: https://prefix.dev/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda + sha256: f3d006e2441f110160a684744d90921bbedbffa247d7599d7e76b5cd048116dc + md5: ade77ad7513177297b1d75e351e136ce + depends: + - __osx >=11.0 + - libsigtool 0.1.3 h98dc951_0 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + run_exports: {} + size: 114331 + timestamp: 1767045086274 +- conda: https://prefix.dev/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_2.conda + sha256: de6893e53664e769c1b1c4103a666d436e3d307c0eb6a09a164e749d116e80f7 + md5: 555070ad1e18b72de36e9ee7ed3236b3 + depends: + - libcxx >=19.0.0.a0 + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: NCSA + run_exports: {} + size: 200192 + timestamp: 1775657222120 +- conda: https://prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - zstd >=1.5.7,<1.6.0a0 + size: 433413 + timestamp: 1764777166076 +- conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 + md5: 4cb8e6b48f67de0b018719cdf1136306 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: bzip2-1.0.6 + license_family: BSD + run_exports: + weak: + - bzip2 >=1.0.8,<2.0a0 + size: 56115 + timestamp: 1771350256444 +- conda: https://prefix.dev/conda-forge/win-64/cmake-4.3.3-hdcbee5b_0.conda + sha256: c2a97bb9166930d4072a3113317e21cde0d685c74b95a73627b8e2bddaa3f75d + md5: 941d20cd011964387402776ff2b9e32a + depends: + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.20.0,<9.0a0 + - libexpat >=2.8.1,<3.0a0 + - liblzma >=5.8.3,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 16394712 + timestamp: 1779399232130 +- conda: https://prefix.dev/conda-forge/win-64/cuda-crt-tools-12.9.86-h57928b3_2.conda + sha256: fb2283a55820eeff84c861b469cfee6a9d0ac9aebe02e82aae480a60068a7659 + md5: d0057a8511cb12745675db18ccbec8f2 + depends: + - cuda-version >=12.9,<12.10.0a0 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 29604 + timestamp: 1753975679251 +- conda: https://prefix.dev/conda-forge/win-64/cuda-cudart-12.9.79-he0c23c2_0.conda + sha256: a30cd9adf3a70d069d4d87c5728ec16778b77071629612ca5d8513cd92d89c09 + md5: 0a243d4f000a0d2f51dd94ee9132b234 + depends: + - cuda-cudart_win-64 12.9.79 he0c23c2_0 + - cuda-version >=12.9,<12.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 170799 + timestamp: 1749218946117 +- conda: https://prefix.dev/conda-forge/win-64/cuda-cudart-dev-12.9.79-he0c23c2_0.conda + sha256: 1ee68f0ffd37889f0fc438d4da7124054b124632e1c3bc15950b9851b002473e + md5: e5bb074108bc2501f8374e80748aa181 + depends: + - cuda-cudart 12.9.79 he0c23c2_0 + - cuda-cudart-dev_win-64 12.9.79 he0c23c2_0 + - cuda-cudart-static 12.9.79 he0c23c2_0 + - cuda-version >=12.9,<12.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: + weak: + - cuda-cudart >=12.9.79,<13.0a0 + size: 23222 + timestamp: 1749219022963 +- conda: https://prefix.dev/conda-forge/win-64/cuda-cudart-static-12.9.79-he0c23c2_0.conda + sha256: 02d3ff9ec59c7f59132ffe9398746ad9422a75706e7cad19acc6c30a5c0fc763 + md5: 718879691b8119c893f587f46c734fca + depends: + - cuda-cudart-static_win-64 12.9.79 he0c23c2_0 + - cuda-version >=12.9,<12.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 23249 + timestamp: 1749218998822 +- conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc-12.9.86-h8f04d04_6.conda + sha256: c8ae18d52a596dd1b2c210dab7c75893b74aac25783c787fc89e6052c9bfeabb + md5: e9b16eaf091bd261c36c239e99cca554 + depends: + - cuda-nvcc_win-64 12.9.86.* + - vs2019_win-64 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 25977 + timestamp: 1771619505004 +- conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc-impl-12.9.86-h53cbb54_2.conda + sha256: d52c7b77b7d4f707efb3b76f93beb1c2b97883db6605818c1727935df9babe5d + md5: 17181de579b111f1cbad7af2b45aed0e + depends: + - cuda-cudart >=12.9.79,<13.0a0 + - cuda-cudart-dev + - cuda-nvcc-dev_win-64 12.9.86 h36c15f3_2 + - cuda-nvcc-tools 12.9.86 he0c23c2_2 + - cuda-nvvm-impl 12.9.86 h2466b09_2 + - cuda-version >=12.9,<12.10.0a0 + - libnvptxcompiler-dev 12.9.86 h57928b3_2 + constrains: + - vc >=14.2 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27684 + timestamp: 1753976469818 +- conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc-tools-12.9.86-he0c23c2_2.conda + sha256: e28baff7cbee6bbc30797adfe09f497c9ac2b69deb7f5152fc7e238c2f37e42b + md5: b018676d60a0f1e51a120382db5221fc + depends: + - cuda-crt-tools 12.9.86 h57928b3_2 + - cuda-nvvm-tools 12.9.86 h2466b09_2 + - cuda-version >=12.9,<12.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27361 + timestamp: 1753976245101 +- conda: https://prefix.dev/conda-forge/win-64/cuda-nvcc_win-64-12.9.86-hd70436c_6.conda + sha256: f78ba6f9f461384d79e6496d91645e54b6f42e7bab9fb6858427afe17d916338 + md5: 47c00e8ebf2a716447fc04cec54d91a7 + depends: + - cuda-cudart-dev_win-64 12.9.* + - cuda-nvcc-dev_win-64 12.9.86.* + - cuda-nvcc-impl 12.9.86.* + - cuda-nvcc-tools 12.9.86.* + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: + strong: + - cuda-version >=12.9,<13 + size: 27274 + timestamp: 1771619504292 +- conda: https://prefix.dev/conda-forge/win-64/cuda-nvvm-impl-12.9.86-h2466b09_2.conda + sha256: 7b995ea653816b129bae6e4ee92898824a39fe82227472537bf75ac6ece7e955 + md5: d8cea7bc32045bde718d0b1ceb595445 + depends: + - cuda-version >=12.9,<12.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 31168 + timestamp: 1753975780038 +- conda: https://prefix.dev/conda-forge/win-64/cuda-nvvm-tools-12.9.86-h2466b09_2.conda + sha256: 5692a559206420f77e376a598329db966da762ad574866f9cc80a447d26ac49c + md5: 25e269101d3eb39715a48998bc04289e + depends: + - cuda-version >=12.9,<12.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 40286977 + timestamp: 1753975898550 +- conda: https://prefix.dev/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + sha256: eb60f1ad8b597bcf95dee11bc11fe71a8325bc1204cf51d2bb1f2120ffd77761 + md5: 4432f52dc0c8eb6a7a6abc00a037d93c + depends: + - openssl >=3.5.5,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + run_exports: + weak: + - krb5 >=1.22.2,<1.23.0a0 + size: 751055 + timestamp: 1769769688841 +- conda: https://prefix.dev/conda-forge/win-64/libcurl-8.20.0-h8206538_0.conda + sha256: f4ce5aa835a698532feaa368e804365a7e45a9edebe006a8e1c80505d893c24e + md5: 7bee27a8f0a295117ccb864f30d2d87e + depends: + - krb5 >=1.22.2,<1.23.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: curl + license_family: MIT + run_exports: + weak: + - libcurl >=8.20.0,<9.0a0 + size: 393114 + timestamp: 1777461635732 +- conda: https://prefix.dev/conda-forge/win-64/libexpat-2.8.1-hac47afa_0.conda + sha256: a65e518c20d1482182bc0f1f6dd5d992f25ca44c3b32307be39ae8310db8f060 + md5: 23eb9474a16d4b9f6f27429989e82002 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + run_exports: {} + size: 71280 + timestamp: 1779278786150 +- conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + sha256: d636d1a25234063642f9c531a7bb58d84c1c496411280a36ea000bd122f078f1 + md5: 8f83619ab1588b98dd99c90b0bfc5c6d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.3.* + license: 0BSD + run_exports: + weak: + - liblzma >=5.8.3,<6.0a0 + size: 106486 + timestamp: 1775825663227 +- conda: https://prefix.dev/conda-forge/win-64/libnvptxcompiler-dev-12.9.86-h57928b3_2.conda + sha256: b05ab0cb8c66535a9cb27cf229752c42dab1fc4bda46c050514c42ad0a74b12c + md5: ed841728d5a36ce8269c6f875c001236 + depends: + - cuda-version >=12.9,<12.10.0a0 + - libnvptxcompiler-dev_win-64 12.9.86 h57928b3_2 + license: LicenseRef-NVIDIA-End-User-License-Agreement + run_exports: {} + size: 27359 + timestamp: 1753976279054 +- conda: https://prefix.dev/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + sha256: cbdf93898f2e27cefca5f3fe46519335d1fab25c4ea2a11b11502ff63e602c09 + md5: 9dce2f112bfd3400f4f432b3d0ac07b2 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libssh2 >=1.11.1,<2.0a0 + size: 292785 + timestamp: 1745608759342 +- conda: https://prefix.dev/conda-forge/win-64/libuv-1.52.1-h6a83c73_0.conda + sha256: ca55710ece8736785ffa0fad4d45402dd40992a81a045d69eda5d40bc1a288f9 + md5: 741d96e586ac833409e5d27cdae08d15 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + run_exports: + weak: + - libuv >=1.52.1,<2.0a0 + size: 331213 + timestamp: 1779396042250 +- conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + sha256: 88609816e0cc7452bac637aaf65783e5edf4fee8a9f8e22bdc3a75882c536061 + md5: dbabbd6234dea34040e631f87676292f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + run_exports: + weak: + - libzlib >=1.3.2,<2.0a0 + size: 58347 + timestamp: 1774072851498 +- conda: https://prefix.dev/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + sha256: e41a945c34a5f0bd2109b73a65486cd93023fa0a9bcba3ef98f9a3da40ba1180 + md5: 7ecb9f2f112c66f959d2bb7dbdb89b67 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: Apache-2.0 + license_family: APACHE + run_exports: {} + size: 309417 + timestamp: 1763688227932 +- conda: https://prefix.dev/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + sha256: feb5815125c60f2be4a411e532db1ed1cd2d7261a6a43c54cb6ae90724e2e154 + md5: 05c7d624cff49dbd8db1ad5ba537a8a3 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + run_exports: + weak: + - openssl >=3.6.2,<4.0a0 + size: 9410183 + timestamp: 1775589779763 +- conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 + constrains: + - vc14_runtime >=14.29.30037 + - vs2015_runtime >=14.29.30037 + license: LicenseRef-MicrosoftWindowsSDK10 + run_exports: {} + size: 694692 + timestamp: 1756385147981 +- conda: https://prefix.dev/conda-forge/win-64/vc-14.5-h1b7c187_38.conda + sha256: 61b68e5a4fc71a17f8d64b12e013a2f971ad980bd08e9c389d5e68efe1a67de0 + md5: 774568633f3b26d7a4a6dd4f9ea6d3e1 + depends: + - vc14_runtime >=14.51.36231 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + run_exports: {} + size: 20187 + timestamp: 1780005880049 +- conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_38.conda + sha256: 957c7c65583c7107a5e76f39756c6361fcb7b0dc101ac7c0aea86e7ca09fe49c + md5: 2cdcd8ea1010920911bb2eacb4c61227 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.51.36231 h1b9f54f_38 + constrains: + - vs2015_runtime 14.51.36231.* *_38 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + run_exports: {} + size: 740997 + timestamp: 1780005875753 +- conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_38.conda + sha256: c645fdc1f0f47718431d973386e946754a10200e7ba2c32032560913a970cacd + md5: 63ee70d69d7540e821940dac5d4d9ba2 + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.51.36231.* *_38 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + run_exports: + strong: + - vcomp14 >=14.51.36231 + size: 123561 + timestamp: 1780005858779 +- conda: https://prefix.dev/conda-forge/win-64/vs2019_win-64-19.29.30139-h7dcff83_38.conda + sha256: d882d36d11f4ec2c2f148484c3a43c6121bc7e6829ec0c2940305a440aecacc0 + md5: ff50a2973017ef550e7178a76db45abd + depends: + - vswhere + constrains: + - vs_win-64 2019.11 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - ucrt >=10.0.20348.0 + size: 24189 + timestamp: 1780005891796 +- conda: https://prefix.dev/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_38.conda + sha256: d602239c40b42411268dc15f0325d4c67c6e6b51b6f31d4455935f07cd170111 + md5: 2d59c2ac7e4c06c9d60731d10cd6254a + depends: + - vswhere + constrains: + - vs_win-64 2022.14 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + run_exports: + strong: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + size: 24145 + timestamp: 1780005884976 +- conda: https://prefix.dev/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - zstd >=1.5.7,<1.6.0a0 + size: 388453 + timestamp: 1764777142545 +- conda_source: cuda_probe[139d67dc] @ . + variants: + target_platform: linux-64 + depends: + - cuda-version 12.* + - cuda-nvcc 12.* + - libstdcxx >=15 + - libgcc >=15 + build_packages: + - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://prefix.dev/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda + - conda: https://prefix.dev/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda + - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://prefix.dev/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/cmake-4.3.3-hc85cc9f_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/gcc_impl_linux-64-15.2.0-he0086c7_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/gcc_linux-64-15.2.0-h7be306e_25.conda + - conda: https://prefix.dev/conda-forge/linux-64/gxx_impl_linux-64-15.2.0-hda75c37_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/gxx_linux-64-15.2.0-h1b0a0b8_25.conda + - conda: https://prefix.dev/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://prefix.dev/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libsanitizer-15.2.0-h90f66d4_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libuv-1.52.1-h280c20c_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda + - conda: https://prefix.dev/conda-forge/noarch/libgcc-devel_linux-64-15.2.0-hcc6f6b0_119.conda + - conda: https://prefix.dev/conda-forge/noarch/libstdcxx-devel_linux-64-15.2.0-hd446a21_119.conda + - conda: https://prefix.dev/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda + - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + host_packages: + - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda +- conda_source: cuda_probe[239c2f87] @ . + variants: + cxx_compiler: vs2022 + target_platform: win-64 + depends: + - cuda-version 12.* + - cuda-nvcc 12.* + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + build_packages: + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.5.20-h4c7d964_0.conda + - conda: https://prefix.dev/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda + - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://prefix.dev/conda-forge/win-64/cmake-4.3.3-hdcbee5b_0.conda + - conda: https://prefix.dev/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libcurl-8.20.0-h8206538_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libexpat-2.8.1-hac47afa_0.conda + - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libuv-1.52.1-h6a83c73_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://prefix.dev/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + - conda: https://prefix.dev/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda + - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://prefix.dev/conda-forge/win-64/vc-14.5-h1b7c187_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_38.conda + - conda: https://prefix.dev/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + host_packages: + - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://prefix.dev/conda-forge/win-64/vc-14.5-h1b7c187_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_38.conda + - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_38.conda +- conda_source: cuda_probe[b008fffd] @ . + variants: + target_platform: osx-arm64 + depends: + - libcxx >=22 + build_packages: + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/noarch/compiler-rt22_osx-arm64-22.1.7-h7e67a1e_0.conda + - conda: https://prefix.dev/conda-forge/noarch/compiler-rt_osx-arm64-22.1.7-hce30654_0.conda + - conda: https://prefix.dev/conda-forge/noarch/libcxx-headers-22.1.7-h707e725_0.conda + - conda: https://prefix.dev/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm22_1_hb5e89dc_4.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm22_1_hbe26303_4.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/clang-22-22.1.7-default_hd632d02_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/clang-scan-deps-22.1.7-default_h8e162e0_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/clang_impl_osx-arm64-22.1.7-default_h17d1ed9_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/clang_osx-arm64-22.1.7-hf119d2b_32.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/clangxx_impl_osx-arm64-22.1.7-default_h17d1ed9_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/clangxx_osx-arm64-22.1.7-hf119d2b_32.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/cmake-4.3.3-h8cb302d_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/compiler-rt-22.1.7-hce30654_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/compiler-rt22-22.1.7-hd34ed20_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm22_1_h692d5aa_4.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libclang-cpp22.1-22.1.7-default_h8e162e0_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libclang13-22.1.7-default_h6dd9417_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcompiler-rt-22.1.7-hd34ed20_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcurl-8.20.0-hd5a2499_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-22.1.7-h55c6f16_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-devel-22.1.7-h6dc3340_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libllvm22-22.1.7-h89af1be_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libuv-1.52.1-h1a92334_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libxml2-16-2.15.3-h6967ea9_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libxml2-2.15.3-heed7d32_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-tools-22-22.1.7-hb545844_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-tools-22.1.7-hd34ed20_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + host_packages: + - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-22.1.7-h55c6f16_0.conda +- conda_source: cuda_probe[d2e722fe] @ . + variants: + target_platform: osx-64 + depends: + - libcxx >=22 + build_packages: + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/noarch/compiler-rt22_osx-64-22.1.7-hcf80936_0.conda + - conda: https://prefix.dev/conda-forge/noarch/compiler-rt_osx-64-22.1.7-h694c41f_0.conda + - conda: https://prefix.dev/conda-forge/noarch/libcxx-headers-22.1.7-h707e725_0.conda + - conda: https://prefix.dev/conda-forge/noarch/sdkroot_env_osx-64-26.0-h62b880e_7.conda + - conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + - conda: https://prefix.dev/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/cctools_impl_osx-64-1030.6.3-llvm22_1_h8fe25a2_4.conda + - conda: https://prefix.dev/conda-forge/osx-64/cctools_osx-64-1030.6.3-llvm22_1_h0a1bb1c_4.conda + - conda: https://prefix.dev/conda-forge/osx-64/clang-22-22.1.7-default_h3b8fe2e_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/clang-scan-deps-22.1.7-default_h9399c5b_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/clang_impl_osx-64-22.1.7-default_hb18168d_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/clang_osx-64-22.1.7-hb0d1528_32.conda + - conda: https://prefix.dev/conda-forge/osx-64/clangxx_impl_osx-64-22.1.7-default_hb18168d_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/clangxx_osx-64-22.1.7-hb0d1528_32.conda + - conda: https://prefix.dev/conda-forge/osx-64/cmake-4.3.3-h2426fb6_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/compiler-rt-22.1.7-h694c41f_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/compiler-rt22-22.1.7-h1637cdf_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/ld64_osx-64-956.6-llvm22_1_h163eae7_4.conda + - conda: https://prefix.dev/conda-forge/osx-64/libclang-cpp22.1-22.1.7-default_h9399c5b_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/libclang13-22.1.7-default_h2429e1b_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcompiler-rt-22.1.7-h1637cdf_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcurl-8.20.0-h8f0b9e4_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcxx-22.1.7-h19cb2f5_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcxx-devel-22.1.7-h7c275be_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://prefix.dev/conda-forge/osx-64/libexpat-2.8.1-hcc62823_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + - conda: https://prefix.dev/conda-forge/osx-64/libllvm22-22.1.7-hab754da_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libsigtool-0.1.3-hc0f2934_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libuv-1.52.1-ha3d0635_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libxml2-16-2.15.3-h0d7f165_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libxml2-2.15.3-h0712280_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://prefix.dev/conda-forge/osx-64/llvm-tools-22-22.1.7-hc181bea_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/llvm-tools-22.1.7-h1637cdf_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/sigtool-codesign-0.1.3-hc0f2934_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/tapi-1600.0.11.8-h8d8e812_2.conda + - conda: https://prefix.dev/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + host_packages: + - conda: https://prefix.dev/conda-forge/osx-64/libcxx-22.1.7-h19cb2f5_0.conda diff --git a/examples/pixi-build/conditional-dependencies/pixi.toml b/examples/pixi-build/conditional-dependencies/pixi.toml new file mode 100644 index 0000000000..50a585c698 --- /dev/null +++ b/examples/pixi-build/conditional-dependencies/pixi.toml @@ -0,0 +1,33 @@ +[workspace] +channels = [ + "https://prefix.dev/pixi-build-backends", + "https://prefix.dev/conda-forge", +] +platforms = ["linux-64", "win-64", "osx-64", "osx-arm64"] +preview = ["pixi-build"] + +# Depend on ourselves: this invokes the build backend to compile the C++ code +# and drops the `cuda_probe` executable into the environment. +[dependencies] +cuda_probe = { path = "." } + +[tasks] +start = { cmd = "cuda_probe", description = "Run the executable built by the [package] section" } + +[package] +description = "A C++ executable that demonstrates if(...) conditional dependencies" +name = "cuda_probe" +version = "0.1.0" + +[package.build.backend] +channels = [ + "https://prefix.dev/pixi-build-backends", + "https://prefix.dev/conda-forge", +] +name = "pixi-build-cmake" +version = "0.3.*" + +# --- Conditional dependencies: the feature this example shows off --------- +[package.run-dependencies."if(linux or win)"] +cuda-nvcc = "12.*" +cuda-version = "12.*" diff --git a/examples/pixi-build/conditional-dependencies/src/main.cc b/examples/pixi-build/conditional-dependencies/src/main.cc new file mode 100644 index 0000000000..80da0e1305 --- /dev/null +++ b/examples/pixi-build/conditional-dependencies/src/main.cc @@ -0,0 +1,35 @@ +#include + +#if defined(__clang__) +# define COMPILER "Clang " __clang_version__ +#elif defined(__GNUC__) +# define COMPILER "GCC " __VERSION__ +#elif defined(_MSC_VER) +# define COMPILER "MSVC" +#else +# define COMPILER "an unknown compiler" +#endif + +#ifdef HAS_CUDA +# include +#endif + +int main() { + std::printf("cuda_probe built with %s\n", COMPILER); + +#ifdef HAS_CUDA + int devices = 0; + cudaError_t err = cudaGetDeviceCount(&devices); + if (err == cudaSuccess) { + std::printf("CUDA %s runtime linked, %d device(s) visible\n", + CUDA_VERSION_STRING, devices); + } else { + std::printf("CUDA %s runtime linked, but no devices (%s)\n", + CUDA_VERSION_STRING, cudaGetErrorString(err)); + } +#else + std::printf("Built without CUDA support (CPU-only)\n"); +#endif + + return 0; +} diff --git a/schema/examples/invalid/package_target_removed.toml b/schema/examples/invalid/package_target_removed.toml new file mode 100644 index 0000000000..20df59edca --- /dev/null +++ b/schema/examples/invalid/package_target_removed.toml @@ -0,0 +1,19 @@ +#:schema ./../../schema.json +[project] +channels = ["conda-forge"] +name = "project" +platforms = ["linux-64"] +preview = ["pixi-build"] + +[package] +name = "project" +version = "0.1.0" + +[package.build.backend] +name = "pixi-build-python" +version = "*" + +# The `[package.target.*]` syntax has been removed from the schema in favor of +# `[package.
."if(...)"]` conditional dependency tables. +[package.target.linux-64.host-dependencies] +foo = "*" diff --git a/schema/examples/valid/full.toml b/schema/examples/valid/full.toml index 46e32c6aab..604c9aaf6d 100644 --- a/schema/examples/valid/full.toml +++ b/schema/examples/valid/full.toml @@ -98,13 +98,13 @@ test1 = "*" [package.run-dependencies] test1 = "*" -[package.target.osx-64.host-dependencies] +[package.host-dependencies."if(host_platform == 'osx-64')"] package1 = { version = ">=1.2.3", build = "py34_0" } pytorch-cpu = { version = "~=1.1", channel = "pytorch" } test = "*" test1 = "*" -[package.target.linux-64.run-dependencies] +[package.run-dependencies."if(host_platform == 'linux-64')"] test = "*" [tasks] diff --git a/schema/model.py b/schema/model.py index 868eeb33ef..4282562f6a 100644 --- a/schema/model.py +++ b/schema/model.py @@ -593,6 +593,21 @@ class PyPIVersion(_PyPIRequirement): InheritableDependencies = dict[CondaPackageName, InheritableMatchSpec] | None ExtraDependencies = dict[ExtraName, dict[CondaPackageName, MatchSpec]] | None +# Package dependency tables additionally accept conditional sub-tables keyed by +# `if()`, whose value is a nested dependency map. The expression is +# passed through to rattler-build. Package names cannot contain `(`, so the two +# forms never collide. +ConditionalInheritableDependencies = ( + dict[ + CondaPackageName, + InheritableMatchSpec | dict[CondaPackageName, InheritableMatchSpec], + ] + | None +) +ConditionalExtraDependencies = ( + dict[ExtraName, dict[CondaPackageName, MatchSpec | dict[CondaPackageName, MatchSpec]]] | None +) + ################ # Task section # @@ -1026,21 +1041,15 @@ class Package(StrictBaseModel): build: Build = Field(..., description="The build configuration of the package") - host_dependencies: InheritableDependencies = HostDependenciesField - build_dependencies: InheritableDependencies = BuildDependenciesField - run_dependencies: InheritableDependencies = RunDependenciesField - extra_dependencies: ExtraDependencies = Field( + host_dependencies: ConditionalInheritableDependencies = HostDependenciesField + build_dependencies: ConditionalInheritableDependencies = BuildDependenciesField + run_dependencies: ConditionalInheritableDependencies = RunDependenciesField + extra_dependencies: ConditionalExtraDependencies = Field( None, description="Extra groups that can be requested through MatchSpec extras. Each group uses the same conda package specification syntax as run-dependencies.", examples=[{"test": {"pytest": ">=8", "hypothesis": "*"}}], ) - run_constraints: InheritableDependencies = RunConstraintsField - - target: dict[TargetName, PackageTarget] | None = Field( - None, - description="Machine-specific aspects of the package", - examples=[{"linux": {"host-dependencies": {"python": "3.8"}}}], - ) + run_constraints: ConditionalInheritableDependencies = RunConstraintsField class BuildTarget(StrictBaseModel): @@ -1135,18 +1144,6 @@ class BuildBackend(BinaryMatchspecTable): ) -class PackageTarget(StrictBaseModel): - run_dependencies: InheritableDependencies = RunDependenciesField - run_constraints: InheritableDependencies = RunConstraintsField - host_dependencies: InheritableDependencies = HostDependenciesField - build_dependencies: InheritableDependencies = BuildDependenciesField - extra_dependencies: ExtraDependencies = Field( - None, - description="Extra groups for this target. Same shape as the top-level `extra-dependencies`, but scoped to the matching platform selector.", - examples=[{"test": {"pytest": ">=8"}}], - ) - - ####################### # The Manifest itself # ####################### diff --git a/schema/pixi_build_api.json b/schema/pixi_build_api.json index b92c985771..e7bd4b4e73 100644 --- a/schema/pixi_build_api.json +++ b/schema/pixi_build_api.json @@ -127,7 +127,7 @@ }, "$defs": { "Targets": { - "description": "A collect of targets including a default target.", + "description": "A collect of targets including a default target.\n\nPlatform-specific dependencies are carried exclusively as conditional\n`if()` entries; the frontend lowers the deprecated\n`[package.target.]` tables to the equivalent expression before\nsending the project model.", "type": "object", "properties": { "defaultTarget": { @@ -140,8 +140,8 @@ } ] }, - "targets": { - "description": "We use an [`OrderMap`] to preserve the order in which the items where\ndefined in the manifest.", + "conditional": { + "description": "Conditional `if()` dependencies. The expression is passed\nthrough to rattler-build, which evaluates it; pixi does not. Keyed by the\nbare inner expression without the `if(...)` wrapper.", "type": [ "object", "null" diff --git a/schema/pyproject/partial-pixi.json b/schema/pyproject/partial-pixi.json index b2a487ecf2..f3c2b1b7c2 100644 --- a/schema/pyproject/partial-pixi.json +++ b/schema/pyproject/partial-pixi.json @@ -1431,6 +1431,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1480,6 +1497,23 @@ }, { "$ref": "#/$defs/MatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/MatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1523,6 +1557,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1613,6 +1664,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1632,6 +1700,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1639,26 +1724,6 @@ "minLength": 1 } }, - "target": { - "title": "Target", - "description": "Machine-specific aspects of the package", - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/PackageTarget" - }, - "propertyNames": { - "minLength": 1 - }, - "examples": [ - { - "linux": { - "host-dependencies": { - "python": "3.8" - } - } - } - ] - }, "version": { "title": "Version", "description": "The version of the project; we advise use of [SemVer](https://semver.org). Can be a string or { workspace = true } to inherit from workspace", @@ -1680,125 +1745,6 @@ } } }, - "PackageTarget": { - "title": "PackageTarget", - "type": "object", - "additionalProperties": false, - "properties": { - "build-dependencies": { - "title": "Build-Dependencies", - "description": "The build `conda` dependencies, used in the build process. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - }, - "extra-dependencies": { - "title": "Extra-Dependencies", - "description": "Extra groups for this target. Same shape as the top-level `extra-dependencies`, but scoped to the matching platform selector.", - "type": "object", - "patternProperties": { - "^[a-z0-9._+-]{1,64}$": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/MatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - } - }, - "examples": [ - { - "test": { - "pytest": ">=8" - } - } - ] - }, - "host-dependencies": { - "title": "Host-Dependencies", - "description": "The host `conda` dependencies, used in the build process. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - }, - "examples": [ - { - "python": ">=3.8" - } - ] - }, - "run-constraints": { - "title": "Run-Constraints", - "description": "The `conda` run-time version constraints. These constrain the versions of packages that may be installed in the run environment without explicitly requiring them. If the package is installed as a dependency of another package, it must satisfy these constraints. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - }, - "run-dependencies": { - "title": "Run-Dependencies", - "description": "The `conda` dependencies required at runtime. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - } - } - }, "Platform": { "title": "Platform", "description": "A supported operating system and processor architecture pair.", diff --git a/schema/pyproject/schema.json b/schema/pyproject/schema.json index d105b79001..4fc68bf1a3 100644 --- a/schema/pyproject/schema.json +++ b/schema/pyproject/schema.json @@ -1174,6 +1174,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1223,6 +1240,23 @@ }, { "$ref": "#/$defs/MatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/MatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1266,6 +1300,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1356,6 +1407,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1375,6 +1443,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1382,26 +1467,6 @@ "minLength": 1 } }, - "target": { - "title": "Target", - "description": "Machine-specific aspects of the package", - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/PackageTarget" - }, - "propertyNames": { - "minLength": 1 - }, - "examples": [ - { - "linux": { - "host-dependencies": { - "python": "3.8" - } - } - } - ] - }, "version": { "title": "Version", "description": "The version of the project; we advise use of [SemVer](https://semver.org). Can be a string or { workspace = true } to inherit from workspace", @@ -1423,125 +1488,6 @@ } } }, - "PackageTarget": { - "title": "PackageTarget", - "type": "object", - "additionalProperties": false, - "properties": { - "build-dependencies": { - "title": "Build-Dependencies", - "description": "The build `conda` dependencies, used in the build process. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - }, - "extra-dependencies": { - "title": "Extra-Dependencies", - "description": "Extra groups for this target. Same shape as the top-level `extra-dependencies`, but scoped to the matching platform selector.", - "type": "object", - "patternProperties": { - "^[a-z0-9._+-]{1,64}$": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/MatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - } - }, - "examples": [ - { - "test": { - "pytest": ">=8" - } - } - ] - }, - "host-dependencies": { - "title": "Host-Dependencies", - "description": "The host `conda` dependencies, used in the build process. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - }, - "examples": [ - { - "python": ">=3.8" - } - ] - }, - "run-constraints": { - "title": "Run-Constraints", - "description": "The `conda` run-time version constraints. These constrain the versions of packages that may be installed in the run environment without explicitly requiring them. If the package is installed as a dependency of another package, it must satisfy these constraints. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - }, - "run-dependencies": { - "title": "Run-Dependencies", - "description": "The `conda` dependencies required at runtime. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - } - } - }, "Platform": { "title": "Platform", "description": "A supported operating system and processor architecture pair.", diff --git a/schema/schema.json b/schema/schema.json index 07fe92b5c6..ae1ce6e22f 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -1455,6 +1455,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1504,6 +1521,23 @@ }, { "$ref": "#/$defs/MatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/MatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1547,6 +1581,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1637,6 +1688,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1656,6 +1724,23 @@ }, { "$ref": "#/$defs/InheritableMatchspecTable" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/$defs/InheritableMatchspecTable" + } + ] + }, + "propertyNames": { + "minLength": 1 + } } ] }, @@ -1663,26 +1748,6 @@ "minLength": 1 } }, - "target": { - "title": "Target", - "description": "Machine-specific aspects of the package", - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/PackageTarget" - }, - "propertyNames": { - "minLength": 1 - }, - "examples": [ - { - "linux": { - "host-dependencies": { - "python": "3.8" - } - } - } - ] - }, "version": { "title": "Version", "description": "The version of the project; we advise use of [SemVer](https://semver.org). Can be a string or { workspace = true } to inherit from workspace", @@ -1704,125 +1769,6 @@ } } }, - "PackageTarget": { - "title": "PackageTarget", - "type": "object", - "additionalProperties": false, - "properties": { - "build-dependencies": { - "title": "Build-Dependencies", - "description": "The build `conda` dependencies, used in the build process. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - }, - "extra-dependencies": { - "title": "Extra-Dependencies", - "description": "Extra groups for this target. Same shape as the top-level `extra-dependencies`, but scoped to the matching platform selector.", - "type": "object", - "patternProperties": { - "^[a-z0-9._+-]{1,64}$": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/MatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - } - }, - "examples": [ - { - "test": { - "pytest": ">=8" - } - } - ] - }, - "host-dependencies": { - "title": "Host-Dependencies", - "description": "The host `conda` dependencies, used in the build process. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - }, - "examples": [ - { - "python": ">=3.8" - } - ] - }, - "run-constraints": { - "title": "Run-Constraints", - "description": "The `conda` run-time version constraints. These constrain the versions of packages that may be installed in the run environment without explicitly requiring them. If the package is installed as a dependency of another package, it must satisfy these constraints. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - }, - "run-dependencies": { - "title": "Run-Dependencies", - "description": "The `conda` dependencies required at runtime. See https://pixi.sh/latest/build/dependency_types/ for more information.", - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "$ref": "#/$defs/InheritableMatchspecTable" - } - ] - }, - "propertyNames": { - "minLength": 1 - } - } - } - }, "Platform": { "title": "Platform", "description": "A supported operating system and processor architecture pair.", diff --git a/tests/data/channels/channels/target_specific_channel_1/linux-64/cmake-0.1.0-hb0f4dca_0.conda b/tests/data/channels/channels/target_specific_channel_1/linux-64/cmake-0.1.0-hb0f4dca_0.conda new file mode 100644 index 0000000000..a7ee6ac665 Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/linux-64/cmake-0.1.0-hb0f4dca_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/linux-64/ninja-0.1.0-hb0f4dca_0.conda b/tests/data/channels/channels/target_specific_channel_1/linux-64/ninja-0.1.0-hb0f4dca_0.conda new file mode 100644 index 0000000000..beb70bfc12 Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/linux-64/ninja-0.1.0-hb0f4dca_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/linux-64/package-unix-0.1.0-hb0f4dca_0.conda b/tests/data/channels/channels/target_specific_channel_1/linux-64/package-unix-0.1.0-hb0f4dca_0.conda index 54e26156c2..5ffca7f9ee 100644 Binary files a/tests/data/channels/channels/target_specific_channel_1/linux-64/package-unix-0.1.0-hb0f4dca_0.conda and b/tests/data/channels/channels/target_specific_channel_1/linux-64/package-unix-0.1.0-hb0f4dca_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/linux-64/repodata.json b/tests/data/channels/channels/target_specific_channel_1/linux-64/repodata.json index e186071b18..ac97246e3c 100644 --- a/tests/data/channels/channels/target_specific_channel_1/linux-64/repodata.json +++ b/tests/data/channels/channels/target_specific_channel_1/linux-64/repodata.json @@ -1 +1 @@ -{"info":{"subdir":"linux-64"},"packages":{},"packages.conda":{"package-unix-0.1.0-hb0f4dca_0.conda":{"arch":"x86_64","build":"hb0f4dca_0","build_number":0,"depends":[],"md5":"32135791eee47172a507dc3d92d79835","name":"package-unix","platform":"linux","sha256":"4c01bfa7a94415e4a2f47b97def7f713a93de7c6cb6348f9c78ac4e83084e1ec","size":1203,"subdir":"linux-64","timestamp":1768224547599,"version":"0.1.0"}},"repodata_version":2} \ No newline at end of file +{"info":{"subdir":"linux-64"},"packages":{},"packages.conda":{"cmake-0.1.0-hb0f4dca_0.conda":{"arch":"x86_64","build":"hb0f4dca_0","build_number":0,"depends":[],"md5":"9622edd42962746758ae14c08759c869","name":"cmake","platform":"linux","sha256":"8bc1769ae477354af46f68443f7d9da47c3f0628a0db2719dc05ad9808e3557e","size":975,"subdir":"linux-64","timestamp":1781164263648,"version":"0.1.0"},"ninja-0.1.0-hb0f4dca_0.conda":{"arch":"x86_64","build":"hb0f4dca_0","build_number":0,"depends":[],"md5":"4a825c99fd2fbc0b10fe0ecca0011d2b","name":"ninja","platform":"linux","sha256":"9a5319d174ce4950dba2dfdc9bb39dfbc65489214ef5b0e431afe4926cccc1ea","size":974,"subdir":"linux-64","timestamp":1781164263648,"version":"0.1.0"},"package-unix-0.1.0-hb0f4dca_0.conda":{"arch":"x86_64","build":"hb0f4dca_0","build_number":0,"depends":[],"md5":"deac6720ea988f39f33d25172f72225c","name":"package-unix","platform":"linux","sha256":"fd8f937427e09736d11839bc34d0cb9165893a5c6d7c81180a12371200dd3c94","size":1202,"subdir":"linux-64","timestamp":1781164263648,"version":"0.1.0"}},"repodata_version":2} diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-64/cmake-0.1.0-h0dc7051_0.conda b/tests/data/channels/channels/target_specific_channel_1/osx-64/cmake-0.1.0-h0dc7051_0.conda new file mode 100644 index 0000000000..63133cb1f3 Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/osx-64/cmake-0.1.0-h0dc7051_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-64/ninja-0.1.0-h0dc7051_0.conda b/tests/data/channels/channels/target_specific_channel_1/osx-64/ninja-0.1.0-h0dc7051_0.conda new file mode 100644 index 0000000000..13869c2c5a Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/osx-64/ninja-0.1.0-h0dc7051_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-64/package-unix-0.1.0-h0dc7051_0.conda b/tests/data/channels/channels/target_specific_channel_1/osx-64/package-unix-0.1.0-h0dc7051_0.conda index 5fa25d1823..d524b6eeff 100644 Binary files a/tests/data/channels/channels/target_specific_channel_1/osx-64/package-unix-0.1.0-h0dc7051_0.conda and b/tests/data/channels/channels/target_specific_channel_1/osx-64/package-unix-0.1.0-h0dc7051_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-64/repodata.json b/tests/data/channels/channels/target_specific_channel_1/osx-64/repodata.json index f8784c71d4..373f4b083c 100644 --- a/tests/data/channels/channels/target_specific_channel_1/osx-64/repodata.json +++ b/tests/data/channels/channels/target_specific_channel_1/osx-64/repodata.json @@ -1 +1 @@ -{"info":{"subdir":"osx-64"},"packages":{},"packages.conda":{"package-unix-0.1.0-h0dc7051_0.conda":{"arch":"x86_64","build":"h0dc7051_0","build_number":0,"depends":[],"md5":"40bf64eca4a43d2e609eaafa6814852b","name":"package-unix","platform":"osx","sha256":"87782adf1f3575de06a6a117c9fc14b2e798f67aef35201f1b9ed57ee1f760d6","size":1201,"subdir":"osx-64","timestamp":1768224548582,"version":"0.1.0"}},"repodata_version":2} \ No newline at end of file +{"info":{"subdir":"osx-64"},"packages":{},"packages.conda":{"cmake-0.1.0-h0dc7051_0.conda":{"arch":"x86_64","build":"h0dc7051_0","build_number":0,"depends":[],"md5":"de7c027f1ff12d2ea273578fa82522b2","name":"cmake","platform":"osx","sha256":"0fc4f2c79b30eda376c6a6fffce923b3051db3bae8b5a01bb133fa7a932dd22e","size":974,"subdir":"osx-64","timestamp":1781164264107,"version":"0.1.0"},"ninja-0.1.0-h0dc7051_0.conda":{"arch":"x86_64","build":"h0dc7051_0","build_number":0,"depends":[],"md5":"09a5d3c17629e64a21573cc9eb55c008","name":"ninja","platform":"osx","sha256":"e07cc310c1fa39b5d7d29c50a253a4b6bb0c2efaa8f61687cbbbacd2da727523","size":972,"subdir":"osx-64","timestamp":1781164264107,"version":"0.1.0"},"package-unix-0.1.0-h0dc7051_0.conda":{"arch":"x86_64","build":"h0dc7051_0","build_number":0,"depends":[],"md5":"ed6cb01c22c669b28d640d0d2a33f47d","name":"package-unix","platform":"osx","sha256":"7e096b2e287a3ace94d671ed6c230262fecb793642a8299e8f77ff28f033a3f8","size":1201,"subdir":"osx-64","timestamp":1781164264107,"version":"0.1.0"}},"repodata_version":2} diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-arm64/cmake-0.1.0-h60d57d3_0.conda b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/cmake-0.1.0-h60d57d3_0.conda new file mode 100644 index 0000000000..6b5a229496 Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/cmake-0.1.0-h60d57d3_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-arm64/ninja-0.1.0-h60d57d3_0.conda b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/ninja-0.1.0-h60d57d3_0.conda new file mode 100644 index 0000000000..ebfc9e06fd Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/ninja-0.1.0-h60d57d3_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-arm64/package-unix-0.1.0-h60d57d3_0.conda b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/package-unix-0.1.0-h60d57d3_0.conda index e5d6ae07b7..175eda5c03 100644 Binary files a/tests/data/channels/channels/target_specific_channel_1/osx-arm64/package-unix-0.1.0-h60d57d3_0.conda and b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/package-unix-0.1.0-h60d57d3_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/osx-arm64/repodata.json b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/repodata.json index 78a1cbcd77..92cbd75d59 100644 --- a/tests/data/channels/channels/target_specific_channel_1/osx-arm64/repodata.json +++ b/tests/data/channels/channels/target_specific_channel_1/osx-arm64/repodata.json @@ -1 +1 @@ -{"info":{"subdir":"osx-arm64"},"packages":{},"packages.conda":{"package-unix-0.1.0-h60d57d3_0.conda":{"arch":"arm64","build":"h60d57d3_0","build_number":0,"depends":[],"md5":"3f9ca67b29f4179aa347b30fad6b9b26","name":"package-unix","platform":"osx","sha256":"5ba2a8515ccaca4592a34fd5b1d74f046ba072d173938969867ad054d256982c","size":1201,"subdir":"osx-arm64","timestamp":1768224548088,"version":"0.1.0"}},"repodata_version":2} \ No newline at end of file +{"info":{"subdir":"osx-arm64"},"packages":{},"packages.conda":{"cmake-0.1.0-h60d57d3_0.conda":{"arch":"arm64","build":"h60d57d3_0","build_number":0,"depends":[],"md5":"001f6cfc4b5b4f95ad7906c23c18d049","name":"cmake","platform":"osx","sha256":"78aa04be756ee62a3c25a387b86f054f1bdd01cb09dc83ed9ccda5377282b47b","size":974,"subdir":"osx-arm64","timestamp":1781164263856,"version":"0.1.0"},"ninja-0.1.0-h60d57d3_0.conda":{"arch":"arm64","build":"h60d57d3_0","build_number":0,"depends":[],"md5":"930f6139ba282db9eb2bfef6cc26414e","name":"ninja","platform":"osx","sha256":"0185a351568d6fd3d7e81c300534ba0843929562cbadbd3ea38d551f9797eb90","size":972,"subdir":"osx-arm64","timestamp":1781164263856,"version":"0.1.0"},"package-unix-0.1.0-h60d57d3_0.conda":{"arch":"arm64","build":"h60d57d3_0","build_number":0,"depends":[],"md5":"8b257161a4a81925d7677d69fd8ace5a","name":"package-unix","platform":"osx","sha256":"1635e8f1aa537fafe75f78246147be2dcecb403baee1c9ba970c71997a5c7a83","size":1200,"subdir":"osx-arm64","timestamp":1781164263856,"version":"0.1.0"}},"repodata_version":2} diff --git a/tests/data/channels/channels/target_specific_channel_1/rattler-build-log.txt b/tests/data/channels/channels/target_specific_channel_1/rattler-build-log.txt index 8b4e17c75a..8b9ec42cb1 100644 --- a/tests/data/channels/channels/target_specific_channel_1/rattler-build-log.txt +++ b/tests/data/channels/channels/target_specific_channel_1/rattler-build-log.txt @@ -1,4 +1,12 @@ -{"work_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1768224547/work","build_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1768224547","host_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1768224547/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_","build_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1768224547/build_env","recipe_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} -{"work_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224547/work","build_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224547","host_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224547/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224547/build_env","recipe_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} -{"work_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548/work","build_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548","host_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548/build_env","recipe_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} -{"work_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548/work","build_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548","host_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1768224548/build_env","recipe_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/testing_ground/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-windows_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placeh","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placeh","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164263/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164264/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164264","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164264/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placeh","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_package-unix_1781164264/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164264/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164264","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164264/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_cmake_1781164264/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} +{"work_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164264/work","build_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164264","host_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164264/host_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla","build_prefix":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/bld/rattler-build_ninja_1781164264/build_env","recipe_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes","recipe_path":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/recipes/target_specific_channel_1.yaml","output_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1","cache_dir":"/var/home/julian/Projekte/github.com/prefix-dev/pixi/tests/data/channels/channels/target_specific_channel_1/build_cache"} diff --git a/tests/data/channels/channels/target_specific_channel_1/win-64/cmake-0.1.0-h9490d1a_0.conda b/tests/data/channels/channels/target_specific_channel_1/win-64/cmake-0.1.0-h9490d1a_0.conda new file mode 100644 index 0000000000..1cf2b774c0 Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/win-64/cmake-0.1.0-h9490d1a_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/win-64/ninja-0.1.0-h9490d1a_0.conda b/tests/data/channels/channels/target_specific_channel_1/win-64/ninja-0.1.0-h9490d1a_0.conda new file mode 100644 index 0000000000..d50bb7c93f Binary files /dev/null and b/tests/data/channels/channels/target_specific_channel_1/win-64/ninja-0.1.0-h9490d1a_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/win-64/package-windows-0.1.0-h9490d1a_0.conda b/tests/data/channels/channels/target_specific_channel_1/win-64/package-windows-0.1.0-h9490d1a_0.conda index 523247427c..75b0d8a693 100644 Binary files a/tests/data/channels/channels/target_specific_channel_1/win-64/package-windows-0.1.0-h9490d1a_0.conda and b/tests/data/channels/channels/target_specific_channel_1/win-64/package-windows-0.1.0-h9490d1a_0.conda differ diff --git a/tests/data/channels/channels/target_specific_channel_1/win-64/repodata.json b/tests/data/channels/channels/target_specific_channel_1/win-64/repodata.json index d62d1e80d3..05aa458779 100644 --- a/tests/data/channels/channels/target_specific_channel_1/win-64/repodata.json +++ b/tests/data/channels/channels/target_specific_channel_1/win-64/repodata.json @@ -1 +1 @@ -{"info":{"subdir":"win-64"},"packages":{},"packages.conda":{"package-windows-0.1.0-h9490d1a_0.conda":{"arch":"x86_64","build":"h9490d1a_0","build_number":0,"depends":[],"md5":"cb1891c3f1bf05c1517b5f299b9ac9d2","name":"package-windows","platform":"win","sha256":"8ff6b961fedff5066790d0776a456fee58f2530030d1dfaedb13923f90b320c2","size":1219,"subdir":"win-64","timestamp":1768224547076,"version":"0.1.0"}},"repodata_version":2} \ No newline at end of file +{"info":{"subdir":"win-64"},"packages":{},"packages.conda":{"cmake-0.1.0-h9490d1a_0.conda":{"arch":"x86_64","build":"h9490d1a_0","build_number":0,"depends":[],"md5":"5ae92a5d2e30aa0920f0ffedcab297cc","name":"cmake","platform":"win","sha256":"8ddfba839e49265dbbcc25716e5fb080644cba029b5b679953a1bba721020e9a","size":976,"subdir":"win-64","timestamp":1781164263474,"version":"0.1.0"},"ninja-0.1.0-h9490d1a_0.conda":{"arch":"x86_64","build":"h9490d1a_0","build_number":0,"depends":[],"md5":"322f681f835df535f98fe2b98511e654","name":"ninja","platform":"win","sha256":"cc39a47b4560bbbfc3db9b0b131f75cda2167238f14f92634da4af7e6d8c6ff8","size":974,"subdir":"win-64","timestamp":1781164263474,"version":"0.1.0"},"package-windows-0.1.0-h9490d1a_0.conda":{"arch":"x86_64","build":"h9490d1a_0","build_number":0,"depends":[],"md5":"120bd74dae1c0cfc9b5bed9f353ce837","name":"package-windows","platform":"win","sha256":"bc0bce46371b156a0c9e984ece4122921ec6e340e380eef3060e4debc2331e10","size":1220,"subdir":"win-64","timestamp":1781164263474,"version":"0.1.0"}},"repodata_version":2} diff --git a/tests/data/channels/recipes/target_specific_channel_1.yaml b/tests/data/channels/recipes/target_specific_channel_1.yaml index 31bcf93014..48f08b8bdd 100644 --- a/tests/data/channels/recipes/target_specific_channel_1.yaml +++ b/tests/data/channels/recipes/target_specific_channel_1.yaml @@ -21,3 +21,21 @@ outputs: - mkdir -p $PREFIX/bin - echo "@echo off" > $PREFIX/bin/package.bat - echo "echo windows" >> $PREFIX/bin/package.bat + + # Stubs for the build tools that pixi-build-cmake injects into the build + # environment, so workspaces can be locked without conda-forge access. + - package: + name: cmake + version: 0.1.0 + + build: + script: + - echo stub + + - package: + name: ninja + version: 0.1.0 + + build: + script: + - echo stub diff --git a/tests/data/pixi-build/rattler-build-backend/smokey2/pixi.toml b/tests/data/pixi-build/rattler-build-backend/smokey2/pixi.toml index 8235351bc5..db963d9060 100644 --- a/tests/data/pixi-build/rattler-build-backend/smokey2/pixi.toml +++ b/tests/data/pixi-build/rattler-build-backend/smokey2/pixi.toml @@ -21,5 +21,5 @@ name = "pixi-build-rattler-build" version = "*" # No deps for default target, but dep for linux64 target -[package.target.linux-64.host-dependencies] +[package.host-dependencies."if(host_platform == 'linux-64')"] hatchling = "*" diff --git a/tests/data/pixi-build/target-specific/pixi.toml b/tests/data/pixi-build/target-specific/pixi.toml index 1c6422d105..a5064b9181 100644 --- a/tests/data/pixi-build/target-specific/pixi.toml +++ b/tests/data/pixi-build/target-specific/pixi.toml @@ -19,8 +19,8 @@ version = "*" hatchling = "*" # Add packages that would be unavailable for the wrong target -[package.target.unix.host-dependencies] +[package.host-dependencies."if(unix)"] package-unix = "*" -[package.target.win-64.host-dependencies] +[package.host-dependencies."if(host_platform == 'win-64')"] package-windows = "*" diff --git a/tests/integration_python/pixi_build/test_conditional_dependencies.py b/tests/integration_python/pixi_build/test_conditional_dependencies.py new file mode 100644 index 0000000000..91270a0a1a --- /dev/null +++ b/tests/integration_python/pixi_build/test_conditional_dependencies.py @@ -0,0 +1,148 @@ +"""Tests for `if(...)` conditional package dependencies in the `[package]` section.""" + +from pathlib import Path +from typing import Any + +import tomli_w +from rattler.lock import LockFile + +from .common import ExitCode, verify_cli_command + +# The platforms covered by target_specific_channel_1. The channel only ships +# `package-unix` for the unix platforms and `package-windows` for win-64, so a +# conditional dependency that leaks to the wrong platform fails the solve. +PLATFORMS = ["linux-64", "osx-64", "osx-arm64", "win-64"] +UNIX_PLATFORMS = ["linux-64", "osx-64", "osx-arm64"] + +PACKAGE_NAME = "conditional-deps" + + +def write_workspace( + workspace_dir: Path, + channel: str, + run_dependencies: dict[str, Any], + platforms: list[str] = PLATFORMS, + build_variants: dict[str, list[str]] | None = None, +) -> Path: + """Write a workspace manifest with a source package using `pixi-build-cmake`.""" + manifest: dict[str, Any] = { + "workspace": { + # The channel also contains stub `cmake` and `ninja` packages for + # the build environment of the backend, locking stays offline. + "channels": [channel], + "platforms": platforms, + "preview": ["pixi-build"], + }, + "dependencies": {PACKAGE_NAME: {"path": "."}}, + "package": { + "name": PACKAGE_NAME, + "version": "1.0.0", + "build": { + "backend": {"name": "pixi-build-cmake", "version": "*"}, + # No compilers keeps the build environment small. + "config": {"compilers": []}, + }, + "run-dependencies": run_dependencies, + }, + } + if build_variants is not None: + manifest["workspace"]["build-variants"] = build_variants + manifest_path = workspace_dir.joinpath("pixi.toml") + manifest_path.write_text(tomli_w.dumps(manifest)) + return manifest_path + + +def locked_package_names(workspace_dir: Path) -> dict[str, set[str]]: + """Map each platform in the default environment to its locked package names.""" + lock = LockFile.from_path(workspace_dir.joinpath("pixi.lock")) + environment = lock.default_environment() + assert environment is not None + return { + str(platform): {package.name for package in packages} + for platform, packages in environment.packages_by_platform().items() + } + + +def test_simple_conditional_dependency( + pixi: Path, tmp_pixi_workspace: Path, target_specific_channel_1: str +) -> None: + """A platform family condition only adds the dependency on matching platforms.""" + manifest_path = write_workspace( + tmp_pixi_workspace, + target_specific_channel_1, + { + "if(unix)": {"package-unix": "*"}, + "if(win)": {"package-windows": "*"}, + }, + ) + + verify_cli_command([pixi, "lock", "--manifest-path", manifest_path]) + + packages = locked_package_names(tmp_pixi_workspace) + for platform in UNIX_PLATFORMS: + assert "package-unix" in packages[platform] + assert "package-windows" not in packages[platform] + assert "package-windows" in packages["win-64"] + assert "package-unix" not in packages["win-64"] + + +def test_complex_conditional_expression( + pixi: Path, tmp_pixi_workspace: Path, target_specific_channel_1: str +) -> None: + """Boolean operators and platform comparisons evaluate per platform.""" + manifest_path = write_workspace( + tmp_pixi_workspace, + target_specific_channel_1, + {"if(unix and not (host_platform == 'osx-arm64'))": {"package-unix": "*"}}, + ) + + verify_cli_command([pixi, "lock", "--manifest-path", manifest_path]) + + packages = locked_package_names(tmp_pixi_workspace) + assert "package-unix" in packages["linux-64"] + assert "package-unix" in packages["osx-64"] + assert "package-unix" not in packages["osx-arm64"] + assert "package-unix" not in packages["win-64"] + + +def test_variant_conditional_expression( + pixi: Path, tmp_pixi_workspace: Path, target_specific_channel_1: str +) -> None: + """`match()` conditions evaluate against the configured build variants.""" + manifest_path = write_workspace( + tmp_pixi_workspace, + target_specific_channel_1, + { + "if(match(python, '>=3.10'))": {"package-unix": "*"}, + # `package-windows` does not exist on linux-64, so the solve would + # fail loudly if this condition were wrongly applied. + "if(match(python, '<3.10'))": {"package-windows": "*"}, + }, + platforms=["linux-64"], + build_variants={"python": ["3.12"]}, + ) + + verify_cli_command([pixi, "lock", "--manifest-path", manifest_path]) + + packages = locked_package_names(tmp_pixi_workspace) + assert "package-unix" in packages["linux-64"] + assert "package-windows" not in packages["linux-64"] + + +def test_invalid_conditional_expression( + pixi: Path, tmp_pixi_workspace: Path, target_specific_channel_1: str +) -> None: + """An expression that does not parse fails the lock with a helpful error.""" + manifest_path = write_workspace( + tmp_pixi_workspace, + target_specific_channel_1, + {"if(host_platform ==)": {"package-unix": "*"}}, + # A single fixed platform keeps the error output deterministic. + platforms=["linux-64"], + ) + + verify_cli_command( + [pixi, "lock", "--manifest-path", manifest_path], + expected_exit_code=ExitCode.FAILURE, + stderr_contains="invalid selector expression `host_platform ==`", + )