Getting started
Introduction#
Next to managing workflows and environments, Pixi can also build packages. This is useful for the following reasons:
- Building and uploading a package to a conda channel
- Allowing users to directly depend on the source and build it automatically
- Managing multiple packages in a workspace
We've been working to support these use-cases with the build
feature in pixi.
The vision is to enable building of packages from source, for any language, on any platform.
Known limitations
Currently, the build
feature has a number of limitations:
- Limited set of build-backends.
- Build-backends are probably missing a lot of parameters/features.
- Recursive source dependencies are not supported. ( source dependencies that have source dependencies )
- Workspace dependencies cannot be inherited.
Setting up the Manifest#
This is an overview of the Pixi manifest using pixi-build
.
# Specifies properties for the whole workspace
[workspace]
preview = ["pixi-build"]
channels = ["https://prefix.dev/conda-forge"]
platforms = ["win-64", "linux-64", "osx-arm64", "osx-64"]
# There can be multiple packages in a workspace
# In `package` you specify properties specific to the package
[package]
name = "rich_example"
version = "0.1.0"
# Here the build system of the package is specified
# We are using `pixi-build-python` in order to build a Python package
[package.build]
backend = { name = "pixi-build-python", version = "0.1.*" }
channels = [
"https://prefix.dev/pixi-build-backends",
"https://prefix.dev/conda-forge",
]
# The Python package `rich_example` uses `hatchling` as Python build backend
[package.host-dependencies]
hatchling = "*"
# We add our package as dependency to the workspace
[dependencies]
# We can get source dependencies from a path on our file system
rich_example_by_folder = { path = "./recipe_by_folder" }
# as well as from a git repository
boost-check = { git = "https://github.com/wolfv/pixi-build-examples", branch = "main", subdirectory = "boost-check" }
# If the directory contains a `pixi.toml`, `pixi-build` will be used to build the package
rich_example = { path = "./rich_example" }
# if the directory contains a `recipe.yaml`, `rattler-build` will be used.
rich_example_by_file = { path = "./recipe_by_file/recipe.yaml" }
[package.run-dependencies]
rich = ">=13.9.4,<14"
Under the [workspace]
section, you can specify properties like the name, channels, and platforms. This is currently an alias for [project]
.
Since the build feature is still in preview, you have to add "pixi-build" to workspace.preview
.
In package
you specify properties specific to the package you want to build.
Packages are built by using build backends.
By specifying package.build-system.build-backend
and package.build-system.channels
you determine which backend is used and from which channel it will be downloaded.
There are different build backends. Pixi backends can describe how to build a conda package, for a certain language or build tool.
In this example, we are using pixi-build-python
backend in order to build a Python package.
[package.build]
backend = { name = "pixi-build-python", version = "0.1.*" }
channels = [
"https://prefix.dev/pixi-build-backends",
"https://prefix.dev/conda-forge",
]
We need to add our package rich_example
as source dependency to the workspace.
Hint
Pixi dependencies fall into two main categories: binary
and source
dependencies.
binary
dependencies are pre-built packages, while source
dependencies are source code that needs to be built.
Source dependencies can be specified either by providing a local path to the directory containing the package or a git
dependency. When using git
, you can optionally define a branch
, tag
, or rev
to pin the dependency. If none are specified, the latest commit on the default branch is used. Additionally, a subdirectory
can be specified to indicate the package’s location within the repository.
Source dependencies are defined in one of two ways:
Pixi
-based dependencies are built using the backend specified in the[package.build]
section of pixi.toml.rattler-build
-based dependencies are built using arecipe.yaml
file. You can specify the path to the folder containing the recipe file, or the path to therecipe.yaml
file itself.
# We add our package as dependency to the workspace
[dependencies]
# We can get source dependencies from a path on our file system
rich_example_by_folder = { path = "./recipe_by_folder" }
# as well as from a git repository
boost-check = { git = "https://github.com/wolfv/pixi-build-examples", branch = "main", subdirectory = "boost-check" }
# If the directory contains a `pixi.toml`, `pixi-build` will be used to build the package
rich_example = { path = "./rich_example" }
# if the directory contains a `recipe.yaml`, `rattler-build` will be used.
rich_example_by_file = { path = "./recipe_by_file/recipe.yaml" }
rich_example
uses hatchling
as Python build backend, so this needs to be mentioned in host-dependencies
.
Python PEP517 backends like hatchling
know how to build a Python package.
So hatchling
creates a Python package, and pixi-build-python
turns the Python package into a conda package.
Read up on host-dependencies in the dependency types chapter
We add rich
as a run dependency to the package. This is necessary because the package uses rich
during runtime.
You can read up on run-dependencies in the dependency types chapter
CLI Commands#
Using the preview feature you can now build packages from source.
pixi build
has been added and will build a.conda
file out of your package.- Other commands like
pixi install
andpixi run
automatically make use of the build feature when apath
,git
orurl
dependency is present.