Module wrappers

A key feature of e3 is the module wrapper. It is named as such since it “wraps” the underlying EPICS module/extension. This allows us to apply site-specific changes to modules from any source without needing to modify that source directly. Site-specific changes include code changes in the form of patches, separate database and substitution files to enable ESS-compliant Process Variable (PV) naming structure, and custom GUIs.

The e3 environment has two different management solution, see Building and installing. The first and primary one, which uses custom tooling, relies on something we will refer to as just “e3 wrappers”, while the second one, which uses conda for package management, uses a different wrapper that we refer to as “recipes”.

e3 wrappers

The build system of e3 will build according to configuration spread between the main ${MODULE}.Makefile and other GNU Make files under ./configure.

The template structure for an e3 wrapper is as follows:

[iocuser@host:~]$ tree e3-${MODULE}
e3-${MODULE}
├── Makefile
├── README.md
├── cmds                        # example or template startup scripts
├── configure
├── docs                        # additional documentation (e.g. design docs)
├── iocsh                       # 'snippets' - common functions that are used by several IOCs
├── patch                       # ESS-specific modifications (in the shape of patch-files)
├── opi                         # example or template graphical user interfaces
├── template                    # ESS-specific database/template/substitution files
├── ${MODULE}
├── ${MODULE}.Makefile
└── tools                       # additional tools or utilities
  • configure/CONFIG_MODULE: The file that defines project name, version, and that lists dependencies.

  • configure/RELEASE: Where the build environment and installation target is defined.

  • {MODULE}.Makefile: The build project definitions; source files, includes, database files, etc.

In the above output, ${MODULE} is the name of the EPICS module(/application/library). For community modules that are version controlled with git, this would be a git submodule. For ESS-specific modules, it can be a embedded file tree (i.e. both the wrapper and the wrapped module are controlled in the same repository).

Note

We generally prefer “decoupled” modules—where the wrapper and the module are in separate repositories—as that allows for more flexibility (e.g. allowing the standard EPICS module to be made available for community usage, or for the module to be used with both conda and without).

It should be noted that non-used directories in the above structure should be removed; e.g. if there are no patch-files, patch/* should be deleted.

To create a wrapper, see How to: Create an e3 wrapper with cookiecutter and Article: Configuring your wrapper. You may also want to go through the Training.

Conda recipes

The build system of conda will create a contained build environment, and it will then copy the source code into this environment and build according to a recipe given in a meta.yaml file.

The template structure for a conda recipe is as follows:

[iocuser@host:~]$ tree ${MODULE}-recipe
.
├── LICENSE
├── README.md
├── recipe
│   ├── build.sh
│   └── meta.yaml
└── src
    └── Makefile.E3
  • meta.yaml: A file that contains all the metadata in the recipe. Only package name and package version are required.

  • build.sh: The build script for building and installing the package.

  • Makefile.E3: This is essentially just a copy of the ${MODULE}.Makefile used in the e3-wrapper, but with minor modifications.

Just as with the e3 wrapper, it is possible to add files “on top” of the source’s repository in the conda recipe. As example below we have the file structure for iocstats-recipe.

[iocuser@host:iocstats-recipe]$ tree
.
├── LICENSE
├── README.md
├── recipe
│   ├── build.sh
│   └── meta.yaml
└── src
    ├── cmds                # example, template, or test startup scripts
    │   └── iocStats.cmd
    ├── iocsh               # snippets
    │   └── iocStats.iocsh
    ├── Makefile
    └── template            # template, substitution, and database files
        ├── iocAdminSoft-ess.substitutions
        └── iocE3EnvVar-ess.template

To create a conda recipe, see How to: Create a conda recipe with cookiecutter and Article: Configuring your conda recipe. You may also want to go through the Training.