Why Use Build Variants?
Build variants solve version compatibility challenges:- Multiple Python versions - Support Python 3.11, 3.12, 3.13, etc.
- Library versions - Build against different versions of dependencies
- Testing - Verify compatibility across version ranges
- Distribution - Provide packages for various configurations
In the conda ecosystem, this functionality is called “variants.” Other build systems might call this a build matrix, build configurations, or parameterized builds.
The Problem Variants Solve
Consider a C++ package built for Python 3.12:Creating Build Variants
Complete Example
Here’s the full configuration:pixi.toml
- Disable noarch to create variant-specific builds
- Allow any Python version - resolved by variants
Multiple Variant Dimensions
You can create variants for multiple dependencies:- Python 3.11 + nanobind 2.3
- Python 3.11 + nanobind 2.4
- Python 3.12 + nanobind 2.3
- Python 3.12 + nanobind 2.4
- Python 3.13 + nanobind 2.3
- Python 3.13 + nanobind 2.4
Variant Files
For complex configurations, use external variant files:pixi.toml
variants.yaml
- Create paired variants instead of a full matrix
- Python 3.11 + nanobind 2.4
- Python 3.12 + nanobind 2.5
- Python 3.13 + nanobind 2.5
Testing Across Variants
Run Tests in All Environments
Run Tasks in All Environments
Use a loop (bash):Define Environment-Specific Tasks
Understanding Build Strings
Build strings indicate package variants:py311- Python 3.11 varianth43a39b2- Hash of build configuration_0- Build number
Noarch packages (pure Python) have the same build string across variants:
Platform vs Variant Matrix
Platforms - Different OS/architectures:Common Variant Patterns
Advanced: Conditional Variants
Use variant files for platform-specific variants:variants.yaml
Best Practices
Start with minimal variants
Start with minimal variants
Begin with essential versions:
Use version ranges in packages
Use version ranges in packages
Make packages flexible:
Test with CI/CD
Test with CI/CD
Automate variant testing:
Document required variants
Document required variants
Explain why variants exist:
Next Steps
Dependency Types
Understand how variants affect dependencies
Workspaces
Use variants in multi-package workspaces
Build Backends
Backend-specific variant support
Manifest Reference
Complete variant configuration options
Troubleshooting
Variants not creating different builds
Variants not creating different builds
Check that:
- Package has
noarch = false(or omit it) - Dependency uses
*or a range:python = "*" - Variant is actually used in dependencies
Too many builds
Too many builds
Reduce variant dimensions:
Environment resolution fails
Environment resolution fails
Ensure environment pinning matches variants: