Building modules¶
The ESS EPICS environment (e3) builds packages with conda-build, following
conda-forge’s global pinnings and layering ESS site constraints on top. This
page covers setting up a dedicated build environment, building a package
locally, and using the pinning file.
Important
This guide assumes you are comfortable with git, Linux command line, and basic build systems.
You must also have conda (or mamba) installed and configured per
Getting started with e3.
If you need to review these prerequisites, see the main documentation page for external resources.
Note
About this guide’s structure:
This developer documentation follows a learn-by-doing approach. We start with conda-build to set up working build environments (managing all dependencies automatically), then overview recipe structure conceptually, before diving into makefile implementation details, and finally conda recipe formulation. This flow ensures you have functional tooling before encountering the complexity of manual builds and packaging.
Setting up a build environment¶
To build EPICS modules (or any conda package), you need conda-build. You can
install this into an environment of your choice:
(base) $ conda install conda-build
Tip
We recommend using a clean environment for building, to keep build tooling and its dependencies isolated:
$ conda create --name=conda-build conda-build conda-verify
$ conda activate conda-build
Building a conda package - an example with iocStats
We would typically be able to build a conda package just by doing:
(base) $ git clone https://gitlab.esss.lu.se/e3/recipes/iocstats-recipe
(base) $ cd iocstats-recipe
(base) $ conda build recipe
Where running the above commands would resolve build (and host) requirements and download these, before it builds iocStats
itself. However, our e3 environment is built on top of conda-forge, which uses explicit dependency declarations. In particular,
iocStats’ conda recipe contains a dependency macro stdlib('c') (read more here)
which must first be processed. This leads us to the next topic: pinning files.
Note
If you still would like to run the steps above, it should still build on most platforms if you remove or comment
out the line containing stdlib('c') in ./recipe/meta.yaml.
Pinning and variants¶
Pinning aligns dependency versions across packages to ensure ABI compatibility and consistent solver outcomes.
We follow conda-forge’s global pins for compilers and core libraries (conda-forge-pinning-feedstock)
We layer ESS-specific pins via the e3 pinning repository (e3-pinning)
Note
We pin dependencies to ensure ABI (Application Binary Interface) compatibility; this means that compiled binaries link and run correctly against their dependency versions (headers, symbols, calling conventions). Pinning helps avoid silent breakage.
Download variant-config files (preferably outside your recipe repository) and pass
them on the command line using -m (--variant-config-files). To always use the latest
upstream pins, download them when you build:
(base) $ curl -fsSL -o /tmp/conda_forge_pins.yaml https://raw.githubusercontent.com/conda-forge/conda-forge-pinning-feedstock/main/recipe/conda_build_config.yaml
(base) $ curl -fsSL -o /tmp/e3_pins.yaml https://gitlab.esss.lu.se/e3/recipes/e3-pinning/-/raw/main/conda_build_config.yaml
Caution
Up-to-date pinning files are essential to avoid build failures and dependency conflicts.
Thus, if we wanted to re-build the earlier iocStats example with conda-forge and ESS pinning applied:
(base) $ conda build -m /tmp/conda_forge_pins.yaml -m /tmp/e3_pins.yaml recipe
Artifacts are written to your build folder (e.g.
~/miniforge3/conda-bld/linux-64/<name>-<version>-<build>.tar.bz2). You can install the
fresh build if you want to test it:
(conda-build) $ conda install --use-local <package-name>
Tip
Just as with other conda (or mamba) related actions, there is ample documentation available
from upstream.
Anaconda: Conda-build documentation
Conda forge: Maintainer documentation