13. Working with conda and e3¶
In this lesson, you’ll learn how to do the following:
Create a simple environment with epics.
Install new packages.
Create different environments for other epics versions.
Create, build and install an e3 module in a conda environment.
Create and build an e3-recipe locally.
Note
This chapter contains detailed information as to work with conda and e3. If you intend to work only with e3 environment, then this chapter can be skipped.
Quickstart¶
Conda is used to package and deploy e3 modules.
To work with e3, the only requirement is to have conda installed and configured
to use the conda-e3-virtual
channel on Artifactory. Please refer to the
conda requirements.
As explained in the user-guide, a conda environment is just a directory that contains a specific collection of conda packages that you have installed. You could have one environment with EPICS base 7 and another one with EPICS base 3. You can easily switch between environments (by activating or deactivating them). When installing packages in an environment, others are not impacted. To avoid conflicts, conda ensures that there is only one version of each package in an environment.
To create an environment with EPICS base 7 and stream, run:
[iocuser@host:~]$ conda create -y -n epics epics-base=7 stream
# --- snip snip ---
The following NEW packages will be INSTALLED:
_libgcc_mutex conda-e3-virtual/linux-64::_libgcc_mutex-0.1-conda_forge
_openmp_mutex conda-e3-virtual/linux-64::_openmp_mutex-4.5-0_gnu
asyn conda-e3-virtual/linux-64::asyn-4.43.0-h3f0f509_0
calc conda-e3-virtual/linux-64::calc-3.7.4-h0e1289a_0
epics-base conda-e3-virtual/linux-64::epics-base-7.0.7-h68659b9_2
libgcc-ng conda-e3-virtual/linux-64::libgcc-ng-9.3.0-h2828fa1_19
libgomp conda-e3-virtual/linux-64::libgomp-9.3.0-h2828fa1_19
libstdcxx-ng conda-e3-virtual/linux-64::libstdcxx-ng-9.3.0-h6de172a_19
libusb conda-e3-virtual/linux-64::libusb-1.0.22-he1b5a44_0
ncurses conda-e3-virtual/linux-64::ncurses-6.1-hf484d3e_1002
pcre conda-e3-virtual/linux-64::pcre-8.45-h9c3ff4c_0
perl conda-e3-virtual/linux-64::perl-5.26.2-h516909a_1006
readline conda-e3-virtual/linux-64::readline-8.0-hf8c457e_0
require conda-e3-virtual/linux-64::require-5.0.0-h426397f_5
sequencer conda-e3-virtual/linux-64::sequencer-2.2.9-h910a07a_1
sscan conda-e3-virtual/linux-64::sscan-2.11.5-hdc5059e_2
stream conda-e3-virtual/linux-64::stream-2.8.24-hbceeb4b_0
# --- snip snip ---
Note that conda will automatically select the latest version of epics-base
from the conda-e3-virtual channel. This selection will be made in a manner
that ensures compatibility with the rest of the packages, including,
for example, the stream
package.
As you see, it will download all the required dependencies to install the
requested packages. To start working in this environment, just activate it. The
name of the active environment will be displayed in your prompt. You can then
run iocsh
.
[iocuser@host:~]$ conda activate epics
(epics) [iocuser@host:~]$ iocsh -r stream
Warning: environment variable IOCNAME is not set.
███████╗██████╗ ██╗ ██████╗ ██████╗ ███████╗██╗ ██╗███████╗██╗ ██╗
██╔════╝╚════██╗ ██║██╔═══██╗██╔════╝ ██╔════╝██║ ██║██╔════╝██║ ██║
█████╗ █████╔╝ ██║██║ ██║██║ ███████╗███████║█████╗ ██║ ██║
██╔══╝ ╚═══██╗ ██║██║ ██║██║ ╚════██║██╔══██║██╔══╝ ██║ ██║
███████╗██████╔╝ ██║╚██████╔╝╚██████╗ ███████║██║ ██║███████╗███████╗███████╗
╚══════╝╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝
# Start at "2024-W06-feb09-0955-52-CET"
# European Spallation Source ERIC : iocsh (5.0.0-PID-90020)
#
############################################################################
## Shell and environment variables
############################################################################
# PWD = "/home/iocuser"
# USER = "iocuser"
# LOGNAME = "iocuser"
# PATH = "/home/iocuser/miniconda/envs/epics/epics/bin/linux-x86_64:/home/iocuser/miniconda/envs/epics/bin:/home/iocuser/.local/bin:/opt/conda/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin"
#
############################################################################
## EPICS variables
############################################################################
# EPICS_BASE = "/home/iocuser/miniconda/envs/epics/epics"
# EPICS_HOST_ARCH = "linux-x86_64"
# EPICS_DRIVER_PATH = "/home/iocuser/miniconda/envs/epics/modules"
# EPICS_CA_AUTO_ADDR_LIST = ""
# EPICS_CA_ADDR_LIST = "127.255.255.255 172.30.38.20"
# EPICS_PVA_AUTO_ADDR_LIST = ""
# EPICS_PVA_ADDR_LIST = ""
#
############################################################################
## e3-specific variables
############################################################################
# E3_REQUIRE_VERSION = "5.0.0"
# E3_REQUIRE_LOCATION = "/home/iocuser/miniconda/envs/epics/modules/require/5.0.0"
# E3_REQUIRE_BIN = "/home/iocuser/miniconda/envs/epics/bin"
# E3_REQUIRE_DB = "/home/iocuser/miniconda/envs/epics/modules/require/5.0.0/db"
# E3_REQUIRE_DBD = "/home/iocuser/miniconda/envs/epics/modules/require/5.0.0/dbd"
# E3_REQUIRE_INC = "/home/iocuser/miniconda/envs/epics/modules/require/5.0.0/include"
# E3_REQUIRE_LIB = "/home/iocuser/miniconda/envs/epics/modules/require/5.0.0/lib"
#
############################################################################
## IOC startup commands
############################################################################
# // Set REQUIRE_IOC for its internal PVs
epicsEnvSet REQUIRE_IOC "REQMOD:skywalker-90020"
#
# // Set E3_IOCSH_TOP for the absolute path where iocsh is executed.
epicsEnvSet E3_IOCSH_TOP "/home/iocuser"
#
# // Load require module, version 5.0.0
#
dlload /home/iocuser/miniconda/envs/epics/modules/require/5.0.0/lib/linux-x86_64/librequire.so
dbLoadDatabase /home/iocuser/miniconda/envs/epics/modules/require/5.0.0/dbd/require.dbd
require_registerRecordDeviceDriver
Loading module info records for require
#
require stream
Module stream version 2.8.24 found in /home/iocuser/miniconda/envs/epics/modules/stream/2.8.24/
Module stream depends on asyn 4.43.0
Module asyn version 4.43.0 found in /home/iocuser/miniconda/envs/epics/modules/asyn/4.43.0/
Loading library /home/iocuser/miniconda/envs/epics/modules/asyn/4.43.0/lib/linux-x86_64/libasyn.so
Loaded asyn version 4.43.0
Loading dbd file /home/iocuser/miniconda/envs/epics/modules/asyn/4.43.0/dbd/asyn.dbd
Calling function asyn_registerRecordDeviceDriver
Loading module info records for asyn
Module stream depends on calc 3.7.4
Module calc version 3.7.4 found in /home/iocuser/miniconda/envs/epics/modules/calc/3.7.4/
Module calc depends on sequencer 2.2.9
Module sequencer version 2.2.9 found in /home/iocuser/miniconda/envs/epics/modules/sequencer/2.2.9/
Loading library /home/iocuser/miniconda/envs/epics/modules/sequencer/2.2.9/lib/linux-x86_64/libsequencer.so
Loaded sequencer version 2.2.9
sequencer has no dbd file
Loading module info records for sequencer
Module calc depends on sscan 2.11.5
Module sscan version 2.11.5 found in /home/iocuser/miniconda/envs/epics/modules/sscan/2.11.5/
Module sscan depends on sequencer 2.2.9
Module sequencer version 2.2.9 already loaded
Loading library /home/iocuser/miniconda/envs/epics/modules/sscan/2.11.5/lib/linux-x86_64/libsscan.so
Loaded sscan version 2.11.5
Loading dbd file /home/iocuser/miniconda/envs/epics/modules/sscan/2.11.5/dbd/sscan.dbd
Calling function sscan_registerRecordDeviceDriver
Loading module info records for sscan
Loading library /home/iocuser/miniconda/envs/epics/modules/calc/3.7.4/lib/linux-x86_64/libcalc.so
Loaded calc version 3.7.4
Loading dbd file /home/iocuser/miniconda/envs/epics/modules/calc/3.7.4/dbd/calc.dbd
Calling function calc_registerRecordDeviceDriver
Loading module info records for calc
Loading library /home/iocuser/miniconda/envs/epics/modules/stream/2.8.24/lib/linux-x86_64/libstream.so
Loaded stream version 2.8.24
Loading dbd file /home/iocuser/miniconda/envs/epics/modules/stream/2.8.24/dbd/stream.dbd
Calling function stream_registerRecordDeviceDriver
Loading module info records for stream
# // Set the IOC Prompt String
epicsEnvSet IOCSH_PS1 "90020 > "
#
iocInit
Starting iocInit
############################################################################
## EPICS R7.0.7
## Rev. 2023-05-02T11:44+0000
## Rev. Date build date/time:
############################################################################
drvStreamInit: Warning! STREAM_PROTOCOL_PATH not set.
iocRun: All initialization complete
90020 >
Once you are in an environment you can install new packages or change the version of the installed packages. Let’s add iocstats and recsync to our epics environment:
(epics) [iocuser@host:~]$ conda install iocstats recsync
Collecting package metadata (repodata.json): done
Solving environment: done
## Package Plan ##
environment location: /home/iocuser/miniconda/envs/epics
added / updated specs:
- iocstats
- recsync
The following packages will be downloaded:
package | build
---------------------------|-----------------
iocstats-3.1.16 | h910a07a_11 94 KB conda-e3-virtual
recsync-1.5.0 | h910a07a_0 65 KB conda-e3-virtual
------------------------------------------------------------
Total: 160 KB
The following NEW packages will be INSTALLED:
iocstats conda-e3-virtual/linux-64::iocstats-3.1.16-h910a07a_11
recsync conda-e3-virtual/linux-64::recsync-1.5.0-h910a07a_0
conda list
will show you the list of installed packages in the environment:
(epics) [iocuser@host:~]$ conda list
# packages in environment at /home/iocuser/miniconda/envs/epics:
#
# Name Version Build Channel
_libgcc_mutex 0.1 conda_forge conda-e3-virtual
_openmp_mutex 4.5 0_gnu conda-e3-virtual
asyn 4.43.0 h3f0f509_0 conda-e3-virtual
calc 3.7.4 h0e1289a_0 conda-e3-virtual
epics-base 7.0.7 h68659b9_2 conda-e3-virtual
iocstats 3.1.16 h910a07a_11 conda-e3-virtual
libgcc-ng 9.3.0 h2828fa1_19 conda-e3-virtual
libgomp 9.3.0 h2828fa1_19 conda-e3-virtual
libstdcxx-ng 9.3.0 h6de172a_19 conda-e3-virtual
libusb 1.0.22 he1b5a44_0 conda-e3-virtual
ncurses 6.1 hf484d3e_1002 conda-e3-virtual
pcre 8.45 h9c3ff4c_0 conda-e3-virtual
perl 5.26.2 h516909a_1006 conda-e3-virtual
readline 8.0 hf8c457e_0 conda-e3-virtual
recsync 1.5.0 h910a07a_0 conda-e3-virtual
require 5.0.0 h426397f_5 conda-e3-virtual
sequencer 2.2.9 h910a07a_1 conda-e3-virtual
sscan 2.11.5 hdc5059e_2 conda-e3-virtual
stream 2.8.24 hbceeb4b_0 conda-e3-virtual
Let’s say you want to switch to another version of stream. You could
create a new environment or just replace the version installed in this one. You
can search for available versions by running conda search
:
(epics) [iocuser@host:~]$ conda search stream
Loading channels: done
# Name Version Build Channel
stream 2.8.10 h2feebe4_0 conda-e3-virtual
stream 2.8.10 hbaf0b60_1 conda-e3-virtual
stream 2.8.22 h74e095f_2 conda-e3-virtual
stream 2.8.22 ha977fd6_2 conda-e3-virtual
stream 2.8.24 hbceeb4b_0 conda-e3-virtual
Let’s switch to 2.8.10
(epics) [iocuser@host:~]$ conda install stream=2.8.10
Collecting package metadata (repodata.json): done
Solving environment: done
## Package Plan ##
environment location: /home/iocuser/miniconda/envs/epics
added / updated specs:
- stream=2.8.10
The following packages will be downloaded:
package | build
---------------------------|-----------------
asyn-4.41.0 | hceeaaa5_10 1.1 MB conda-e3-virtual
calc-3.7.1 | h6ca1cf9_3 365 KB conda-e3-virtual
epics-base-7.0.5.0 | h68659b9_4 28.6 MB conda-e3-virtual
iocstats-3.1.16 | h2c1926d_5 92 KB conda-e3-virtual
recsync-1.3.0.post1 | h60aecf9_1 59 KB conda-e3-virtual
require-3.1.3 | h9bea806_1 114 KB conda-e3-virtual
seq-2.2.7 | h60aecf9_1 378 KB conda-e3-virtual
sscan-2.11.2 | h44690a7_1 288 KB conda-e3-virtual
stream-2.8.10 | hbaf0b60_1 498 KB conda-e3-virtual
------------------------------------------------------------
Total: 31.5 MB
The following NEW packages will be INSTALLED:
seq conda-e3-virtual/linux-64::seq-2.2.7-h60aecf9_1
The following packages will be REMOVED:
sequencer-2.2.9-h910a07a_1
The following packages will be DOWNGRADED:
asyn 4.43.0-h3f0f509_0 --> 4.41.0-hceeaaa5_10
calc 3.7.4-h0e1289a_0 --> 3.7.1-h6ca1cf9_3
epics-base 7.0.7-h68659b9_2 --> 7.0.5.0-h68659b9_4
iocstats 3.1.16-h910a07a_11 --> 3.1.16-h2c1926d_5
recsync 1.5.0-h910a07a_0 --> 1.3.0.post1-h60aecf9_1
require 5.0.0-h426397f_5 --> 3.1.3-h9bea806_1
sscan 2.11.5-hdc5059e_2 --> 2.11.2-h44690a7_1
stream 2.8.24-hbceeb4b_0 --> 2.8.10-hbaf0b60_1
Let’s now create a separate environment with EPICS Base 3.15
. Note that this is
only as an example. EPICS Base 3 isn’t supported anymore at ESS. You should use
EPICS 7. This is to demonstrate you can work on separate environments with
different EPICS Base version.
(epics) [iocuser@host:~]$ conda create -y -n epics3 epics-base=3 iocstats
Collecting package metadata (repodata.json): done
Solving environment: done
## Package Plan ##
environment location: /home/iocuser/miniconda/envs/epics3
added / updated specs:
- epics-base=3
- iocstats
# --- snip snip ---
The following NEW packages will be INSTALLED:
_libgcc_mutex conda-e3-virtual/linux-64::_libgcc_mutex-0.1-conda_forge
_openmp_mutex conda-e3-virtual/linux-64::_openmp_mutex-4.5-0_gnu
epics-base conda-e3-virtual/linux-64::epics-base-3.15.6-h68659b9_0
iocstats conda-e3-virtual/linux-64::iocstats-3.1.15.post1-h666eb74_0
libgcc-ng conda-e3-virtual/linux-64::libgcc-ng-9.3.0-h2828fa1_19
libgomp conda-e3-virtual/linux-64::libgomp-9.3.0-h2828fa1_19
libstdcxx-ng conda-e3-virtual/linux-64::libstdcxx-ng-9.3.0-h6de172a_19
ncurses conda-e3-virtual/linux-64::ncurses-6.1-hf484d3e_1002
perl conda-e3-virtual/linux-64::perl-5.26.2-h516909a_1006
readline conda-e3-virtual/linux-64::readline-8.0-hf8c457e_0
require conda-e3-virtual/linux-64::require-3.1.0-h4714b6a_0
tclx conda-e3-virtual/linux-64::tclx-8.4.1-h628b354_2
tk conda-e3-virtual/linux-64::tk-8.6.10-hed695b0_0
zlib conda-e3-virtual/linux-64::zlib-1.2.11-h516909a_1006
Switch to this new environment:
(epics) [iocuser@host:~]$ conda deactivate
[iocuser@host:~]$ conda activate epics3
(epics3) [iocuser@host:~]$ conda list
# packages in environment at /home/iocuser/miniconda/envs/epics3:
#
# Name Version Build Channel
_libgcc_mutex 0.1 conda_forge conda-e3-virtual
_openmp_mutex 4.5 0_gnu conda-e3-virtual
epics-base 3.15.6 h68659b9_0 conda-e3-virtual
iocstats 3.1.15.post1 h666eb74_0 conda-e3-virtual
libgcc-ng 9.3.0 h2828fa1_19 conda-e3-virtual
libgomp 9.3.0 h2828fa1_19 conda-e3-virtual
libstdcxx-ng 9.3.0 h6de172a_19 conda-e3-virtual
ncurses 6.1 hf484d3e_1002 conda-e3-virtual
perl 5.26.2 h516909a_1006 conda-e3-virtual
readline 8.0 hf8c457e_0 conda-e3-virtual
require 3.1.0 h4714b6a_0 conda-e3-virtual
tclx 8.4.1 h628b354_2 conda-e3-virtual
tk 8.6.10 hed695b0_0 conda-e3-virtual
zlib 1.2.11 h516909a_1006 conda-e3-virtual
We saw earlier that you can check if a package exists using conda search
. If
the given name doesn’t exist, conda will try to find a match using wildcard:
[iocuser@host:~]$ conda search iocstat
Loading channels: done
No match found for: iocstat. Search: *iocstat*
# Name Version Build Channel
iocstats 3.1.15.post1 h0f5667f_0 conda-e3-virtual
# --- snip snip ---
iocstats 3.1.15.post1 hd2b67a6_0 conda-e3-virtual
iocstats 3.1.15.post1 he422a75_0 conda-e3-virtual
iocstats 3.1.15.post1 hf85dc0c_0 conda-e3-virtual
iocstats 3.1.16 h76d1a4d_1 conda-e3-virtual
iocstats 3.1.16 hd2b67a6_0 conda-e3-virtual
You can get more information about a package and its dependencies with the -i
flag:
[iocuser@host:~]$ conda search iocstat -i
iocstats 3.1.15.post1 h0f5667f_0
--------------------------------
file name : iocstats-3.1.15.post1-h0f5667f_0.tar.bz2
name : iocstats
version : 3.1.15.post1
build : h0f5667f_0
build number: 0
size : 82 KB
license : EPICS Open License
subdir : linux-64
url : https://artifactory.esss.lu.se/artifactory/api/conda/conda-e3-virtual/linux-64/iocstats-3.1.15.post1-h0f5667f_0.tar.bz2
md5 : d70d9f3b626b3718ef853f368a4080ee
timestamp : 2019-03-20 14:27:19 UTC
dependencies:
- epics-base >=3.15.5,<3.15.6.0a0
- libgcc-ng >=7.3.0
- libstdcxx-ng >=7.3.0
- require >=3.1.0,<3.2.0a0
# --- snip snip ---
iocstats 3.1.16 h910a07a_11
--------------------------
file name : iocstats-3.1.16-h910a07a_11.tar.bz2
name : iocstats
version : 3.1.16
build : h910a07a_11
build number: 11
size : 94 KB
license : EPICS Open License
subdir : linux-64
url : https://artifactory.esss.lu.se/artifactory/api/conda/conda-e3-virtual/linux-64/iocstats-3.1.16-h910a07a_11.tar.bz2
md5 : a541cc0b58e5da469ee55cda6ca165ba
timestamp : 2023-09-08 14:13:29 UTC
dependencies:
- epics-base >=7.0.7,<7.0.8.0a0
- libgcc-ng >=7.3.0
- libstdcxx-ng >=7.3.0
- require >=5.0.0,<5.1.0a0
You can see above that the first package was compiled with EPICS Base 3.15.5
and
the last with EPICS Base 7.0.7
.
Note that conda package names are always lowercase. When searching or
installing a package, conda is case-insensitive. Running conda install iocStats
or conda install iocstats
will perform exactly the same operation.
But when using a module with require, you should use the lowercase name:
(epics3) [iocuser@host:~]$ iocsh.bash
# --- snip snip ---
8ef3d5671aef.3038 > require iocStats
Module iocStats not available
8ef3d5671aef.3038 > require iocstats
Module iocstats version 3.1.15 found in /home/iocuser/miniconda/envs/epics3/modules/iocstats/3.1.15/
Loading library /home/iocuser/miniconda/envs/epics3/modules/iocstats/3.1.15/lib/linux-x86_64/libiocstats.so
Loaded iocstats version 3.1.15
Loading dbd file /home/iocuser/miniconda/envs/epics3/modules/iocstats/3.1.15/dbd/iocstats.dbd
Calling function iocstats_registerRecordDeviceDriver
e3 module creation¶
e3 uses require, originally
developed by PSI to
dynamically load modules at runtime. The require also includes a
driver.Makefile
that shall be used to build a module. This requires a specific {module_name}.Makefile
file that includes this driver.Makefile
.
To make it easy to create a new e3 module, we provide a cookiecutter template.
Create the e3 module¶
Use the e3-module
alias to create a new module (refer to [cookiecutter_configuration]
to create this alias). You’ll be prompted to enter some values
Press enter to keep the default.
[iocuser@host:dev]$ e3-module
You've downloaded /home/iocuser/.cookiecutters/cookiecutter-e3-module before. Is it okay to delete and re-download it? [yes]: yes
company [European Spallation Source ERIC]:
module_name [mymodule]: foo
full_name [Your name]: John Doe
email [john.doe@ess.eu]:
documentation_page [https://confluence.esss.lu.se/display/IS/Integration+by+ICS]:
Select keep_epics_base_makefiles:
1 - N
2 - Y
Choose from 1, 2 [1]: 2
This will create a new module. You can reach the same behavior generating a
template using makeBaseApp.pl
from EPICS base.
[iocuser@host:dev]$ tree foo/
foo/
├── cmds
│ └── st.cmd
├── configure
│ ├── CONFIG
│ ├── CONFIG_SITE
│ ├── Makefile
│ ├── RELEASE
│ ├── RULES
│ ├── RULES_DIRS
│ ├── RULES.ioc
│ └── RULES_TOP
├── fooApp
│ ├── Db
│ │ └── Makefile
│ ├── Makefile
│ └── src
│ ├── fooMain.cpp
│ └── Makefile
├── foo.Makefile
├── iocsh
│ └── foo.iocsh
├── LICENSE
├── Makefile
├── README.md
└── RELEASE.md
Notice the foo.Makefile
file, this is the main file used to
build and install a conda e3 module. The standard Makefile
allows you to compile the module using the default EPICS build
system if you want. It’s important to emphasize that foo.Makefile
should not be committed. To prevent commits of this file, it is
recommended to add it to the .gitignore file
.
Update the module¶
Include the necessary files in your module and ensure that you update
the foo.Makefile
file in accordance with the new changes or updates made
to your module.
Compile the module¶
To compile an e3 module in a conda environment, the following packages are required:
make
compilers
tclx
epics-base
require
Create the e3-dev
environment with those packages. If you have other
dependencies, like asyn
, install them as well.
[iocuser@host:dev]$ conda create -y -n e3-dev epics-base require compilers make tclx
Collecting package metadata (repodata.json): done
Solving environment: done
# --- snip snip ---
Activate the e3-dev
environment and compile your module.
Note that when using the make command, it is essential to specify the MODULE name.
Additionally, you have the option to specify the version; if omitted, the require
command will automatically generate the version as dev
.
[iocuser@host:dev]$ conda activate e3-dev
(e3-dev) [iocuser@host:dev]$ cd foo
(e3-dev) [iocuser@host: foo]$ make -f foo.Makefile MODULE=foo
MAKING EPICS VERSION 7.0.7
mkdir -p O.7.0.7_Common
make -f foo.Makefile T_A=linux-x86_64 build
make[1]: Entering directory '/home/iocuser/dev/foo'
mkdir -p O.7.0.7_linux-x86_64
make[2]: Entering directory '/home/iocuser/dev/foo/O.7.0.7_linux-x86_64'
/home/iocsuser/miniconda/envs/e3-dev/bin/x86_64-conda_cos6-linux-gnu-g++ -D_GNU_SOURCE -D_DEFAULT_SOURCE -DUSE_TYPED_RSET -D_X86_64_ -DUNIX -Dlinux -MD -O3 -g -Wall -mtune=generic -m64 -fPIC -I. -I../fooApp/src/ -I/home/iocsuser/miniconda/envs/e3-dev/modules/require/5.0.0/include -I/home/iocsuser/miniconda/envs/e3-dev/epics/include -I/home/iocsuser/miniconda/envs/e3-dev/epics/include/compiler/gcc -I/home/iocsuser/miniconda/envs/e3-dev/epics/include/os/Linux -I/home/iocsuser/miniconda/envs/e3-dev/include -c ../fooApp/src/fooMain.cpp
echo "char _fooLibRelease[] = \"dev\";" >> foo_version_dev.c
/home/iocsuser/miniconda/envs/e3-dev/bin/x86_64-conda_cos6-linux-gnu-gcc -D_GNU_SOURCE -D_DEFAULT_SOURCE -DUSE_TYPED_RSET -D_X86_64_ -DUNIX -Dlinux -MD -O3 -g -Wall -Werror-implicit-function-declaration -mtune=generic -m64 -fPIC -I. -I../fooApp/src/ -I/home/iocsuser/miniconda/envs/e3-dev/modules/require/5.0.0/include -I/home/iocsuser/miniconda/envs/e3-dev/epics/include -I/home/iocsuser/miniconda/envs/e3-dev/epics/include/compiler/gcc -I/home/iocsuser/miniconda/envs/e3-dev/epics/include/os/Linux -I/home/iocsuser/miniconda/envs/e3-dev/include -c foo_version_dev.c
Collecting dependencies
rm -f foo.dep.tmp
cat *.d 2>/dev/null | sed 's/ /\n/g' | sed -n 's%/home/iocsuser/miniconda/envs/e3-dev/modules/*\([^/]*\)/\([0-9]*\.[0-9]*\.[0-9]*\)/.*%\1 \2%p;s%/home/iocsuser/miniconda/envs/e3-dev/modules/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p'| grep -v "include" | sort -u > foo.dep.tmp
cat foo.dep.tmp | sort -u >> foo.dep
/home/iocsuser/miniconda/envs/e3-dev/bin/x86_64-conda_cos6-linux-gnu-g++ -o libfoo.so -shared -fPIC -Wl,-hlibfoo.so -L/home/iocsuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64 -Wl,-rpath,/home/iocsuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64 -rdynamic -m64 -Wl,--disable-new-dtags -Wl,-rpath,/home/iocsuser/miniconda/envs/e3-dev/lib -Wl,-rpath-link,/home/iocsuser/miniconda/envs/e3-dev/lib -L/home/iocsuser/miniconda/envs/e3-dev/lib -Wl,-rpath-link,/home/iocsuser/miniconda/envs/e3-dev/epics/lib/linux-x86_64 fooMain.o foo_version_dev.o -lpthread -lm -lrt -ldl -lgcc
make[2]: Leaving directory '/home/iocuser/dev/foo/O.7.0.7_linux-x86_64'
make[1]: Leaving directory '/home/iocuser/dev/foo'
If you have some database to generate, run make -f foo.Makefile MODULE=foo db_internal
.
In our case, we don’t have any template, so the command won’t do anything.
(e3-dev) [iocuser@host: foo]$ make -f foo.Makefile MODULE=foo db_internal
make: Nothing to be done for 'db_internal'.
Install the module in the current environment.
(e3-dev) [iocuser@host: foo]$ make -f foo.Makefile MODULE=foo install
MAKING EPICS VERSION 7.0.7
make -f foo.Makefile T_A=linux-x86_64 install
make[1]: Entering directory '/home/iocuser/dev/foo'
make[2]: Entering directory '/home/iocuser/dev/foo/O.7.0.7_linux-x86_64'
Collecting dependencies
rm -f foo.dep.tmp
cat *.d 2>/dev/null | sed 's/ /\n/g' | sed -n 's%/home/iocuser/miniconda/envs/e3-dev/modules/*\([^/]*\)/\([0-9]*\.[0-9]*\.[0-9]*\)/.*%\1 \2%p;s%/home/iocuser/miniconda/envs/e3-dev/modules/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p'| grep -v "include" | sort -u > foo.dep.tmp
cat foo.dep.tmp | sort -u >> foo.dep
make[2]: Leaving directory '/home/iocuser/dev/foo/O.7.0.7_linux-x86_64'
make[2]: Entering directory '/home/iocuser/dev/foo/O.7.0.7_linux-x86_64'
Collecting dependencies
rm -f foo.dep.tmp
cat *.d 2>/dev/null | sed 's/ /\n/g' | sed -n 's%/home/iocuser/miniconda/envs/e3-dev/modules/*\([^/]*\)/\([0-9]*\.[0-9]*\.[0-9]*\)/.*%\1 \2%p;s%/home/iocuser/miniconda/envs/e3-dev/modules/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p'| grep -v "include" | sort -u > foo.dep.tmp
cat foo.dep.tmp | sort -u >> foo.dep
Installing scripts ../iocsh/foo.iocsh to /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev
perl -CSD /home/iocuser/miniconda/envs/e3-dev/epics/bin/linux-x86_64/installEpics.pl -d -m755 ../iocsh/foo.iocsh /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev
mkdir /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev
Installing module library /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64/libfoo.so
perl -CSD /home/iocuser/miniconda/envs/e3-dev/epics/bin/linux-x86_64/installEpics.pl -d -m755 libfoo.so /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64
mkdir /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib
mkdir /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64
Installing module dependency file /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64/foo.dep
perl -CSD /home/iocuser/miniconda/envs/e3-dev/epics/bin/linux-x86_64/installEpics.pl -d -m644 foo.dep /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64
make[2]: Leaving directory '/home/iocuser/dev/foo/O.7.0.7_linux-x86_64'
make[1]: Leaving directory '/home/iocuser/dev/foo'
The module was installed as dev version. You can check that you can load it:
(e3-dev) [iocuser@host:foo]$ iocsh -r foo
# --- snip snip ---
require foo
Module foo version dev found in /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/
Loading library /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64/libfoo.so
Loaded foo version dev
foo has no dbd file
Loading module info records for foo
# --- snip snip ---
You can also use the cmds/st.cmd
file to test your module.
(e3-dev) [iocuser@host:foo]$ iocsh.bash cmds/st.cmd
# --- snip snip ---
iocshLoad 'cmds/st.cmd',''
# This should be a test startup script
require foo
Module foo version dev found in /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/
Loading library /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev/lib/linux-x86_64/libfoo.so
Loaded foo version dev
foo has no dbd file
Loading module info records for foo
iocshLoad("/home/iocuser/miniconda/envs/e3-dev/modules/foo/dev//foo.iocsh")
# --- snip snip ---
You can uninstall the module by running make -f foo.Makefile uninstall
.
(e3-dev) [iocuser@host:foo]$ make -f foo.Makefile MODULE=foo uninstall
rm -rf /home/iocuser/miniconda/envs/e3-dev/modules/foo/dev
During development, you can modify your code, re-compile and re-install as many times as you want:
make -f foo.Makefile MODULE=foo uninstall
make -f foo.Makefile MODULE=foo
make -f foo.Makefile MODULE=foo db_internal
make -f foo.Makefile MODULE=foo install
e3 recipe creation¶
To package a module with conda, you have to create a conda recipe.
Use the e3-recipe
alias to create a new recipe (refer to
[cookiecutter_configuration] to create this alias). You’ll be prompted to
enter some values. Press enter to keep the default.
Note
You can use your own module, as created above or earlier if you have uploaded
it to your own repository. Here we use fakemodule
as a working example.
[iocuser@host:dev]$ e3-recipe
company [European Spallation Source ERIC]:
module_name [mymodule]: fakemodule
summary [EPICS fakemodule module]:
module_home [https://gitlab.esss.lu.se/epics-modules]:
module_version [1.0.0]:
The module_home
variable shall point to the group in GitLab where your module
is stored.
This will create the following project:
[iocuser@host:dev]$ tree fakemodule-recipe/
fakemodule-recipe/
├── LICENSE
├── README.md
├── recipe
│ ├── build.sh
│ └── meta.yaml
└── src
└── fakemodule.Makefile
Update the recipe¶
Typically, you should only need to update the recipe/meta.yaml
and the
fakemodule.Makefile
files.
meta.yaml¶
The meta.yaml
file is the file that defines the recipe. It describes where to
get the source of the module and the dependencies to build and run the modules.
The file contains many hints in comments. Follow them and remove them when
you’ve finalized your recipe.
Note
The final recipe shouldn’t contain any comments!
module.Makefile¶
The module.Makefile
should have the same content of the epics-module
module.Makefile
that you used before in the build/install development stage.
Build the recipe¶
To build the recipe, run:
[iocuser@host:foo-recipe]$ conda build recipe
In case of failure, check the error message and update your meta.yaml
file.
If the build was successful, you should see something like that:
# --- snip snip ---
TEST END: /home/iocuser/miniconda/conda-bld/linux-64/foo-1.0.0-hbd7620e_0.tar.bz2
Renaming work directory, /home/iocuser/miniconda/conda-bld/foo_1591215967088/work to /home/iocuser/miniconda/conda-bld/foo_1591215967088/work_moved_foo-1.0.0-hbd7620e_0_linux-64_main_build_loop
# Automatic uploading is disabled
# If you want to upload package(s) to anaconda.org later, type:
anaconda upload /home/iocuser/miniconda/conda-bld/linux-64/foo-1.0.0-hbd7620e_0.tar.bz2
# To have conda build upload to anaconda.org automatically, use
# $ conda config --set anaconda_upload yes
anaconda_upload is not set. Not uploading wheels: []
####################################################################################
Resource usage summary:
Total time: 0:00:07.2
CPU usage: sys=0:00:00.0, user=0:00:00.0
Maximum memory usage observed: 2.4M
Total disk usage observed (not including envs): 52B
####################################################################################
Test the built package¶
You can install the package you built locally by using the -c local
argument
(to use the local channel).
[iocuser@host:foo-recipe]$ conda create -y -n test -c local foo
# --- snip snip ---
The following NEW packages will be INSTALLED:
foo home/iocuser/miniconda/conda-bld/linux-64::foo-1.0.0-hbd7620e_0
# --- snip snip ---
Activate your test environment and test your package.