Module build configurations¶
In the recipe’s build.sh, we invoke make to compile and install the module.
Now let’s look at what that makefile contains - the e3 build interface that tells
require how to build and install a module. This chapter demonstrates building
directly with make (with dependencies from your conda environment) to understand
the makefile in isolation, before returning to conda build in the next chapter.
Note
This guide assumes familiarity with makefiles and build systems. If you need a refresher:
GNU Make manual - comprehensive reference
Make tutorial - practical introduction
EPICS build system - EPICS-specific build concepts
require’s build interface¶
Include driver.makefile from require and declare what to build and install - as well as pass
flags to the compiler and/or linker - using make variables. The most commonly used are:
SOURCES- Source files to compile into the shared libraryHEADERS- Header files that should be installedDBDS- Database definition files to includeTEMPLATES- Database or template files that should be installedSCRIPTS- Script files that should be installed
Additional variables are documented in the build interface reference.
Tip
Quick reference for common variables is available here:
require’s build interface
The variables above handle most module build needs, but require inherits EPICS base’s complete build system.
When you need custom compiler flags, linking options, etc. beyond what these variables provide, refer to EPICS
base’s build documentation: Application Developer’s Guide: Build Facility.
A very small makefile can be as simple as:
# This row is default, and must be included in all e3 makefiles
include $(E3_REQUIRE_TOOLS)/driver.makefile
# Install database files and a "snippet" (.iocsh file)
# The $(where_am_I) variable is provided by require and will point to the module's root directory
TEMPLATES += $(wildcard $(where_am_I)/template/*.db)
SCRIPTS += $(where_am_I)/iocsh/example.iocsh
Example: Building iocStats with make¶
Below is a practical example using upstream iocStats sources, with an e3
makefile that tells require how to build and install the module.
1) Acquire iocStats’ source code¶
$ git clone https://github.com/epics-modules/iocStats.git
$ cd iocStats
Note
If we wanted to acquire additional files, or perform “pre-build” actions (patching, etc.), we would do so at this stage.
2) Acquire build tools and dependencies¶
Create a conda environment that contains epics-base, require, and a compiler:
$ conda create -n iocstats-build epics-base require gcc gxx
Caution
Which compiler to use will depend a bit on your platform, but gcc (and gxx) will work for Linux.
Activate the environment:
$ conda activate iocstats-build
3) Set up an e3 makefile¶
Create a makefile - we will name it e3.makefile since there already is a file named
Makefile in iocStats’ repository root.
# e3.makefile
include $(E3_REQUIRE_TOOLS)/driver.makefile
USR_CPPFLAGS += -DUSE_TYPED_RSET
DEVIOCSTATS := devIocStats
HEADERS += $(DEVIOCSTATS)/os/default/devIocStatsOSD.h
HEADERS += $(DEVIOCSTATS)/devIocStats.h
SOURCES += $(DEVIOCSTATS)/devIocStatsAnalog.c
SOURCES += $(DEVIOCSTATS)/devIocStatsString.c
SOURCES += $(DEVIOCSTATS)/devIocStatsWaveform.c
SOURCES += $(DEVIOCSTATS)/devIocStatsSub.c
SOURCES += $(DEVIOCSTATS)/devIocStatsTest.c
SOURCES += $(DEVIOCSTATS)/os/Linux/osdCpuUsage.c
SOURCES += $(DEVIOCSTATS)/os/Linux/osdCpuUtilization.c
SOURCES += $(DEVIOCSTATS)/os/Linux/osdFdUsage.c
SOURCES += $(DEVIOCSTATS)/os/Linux/osdMemUsage.c
SOURCES += $(DEVIOCSTATS)/os/default/osdWorkspaceUsage.c
SOURCES += $(DEVIOCSTATS)/os/default/osdClustInfo.c
SOURCES += $(DEVIOCSTATS)/os/default/osdSuspTasks.c
SOURCES += $(DEVIOCSTATS)/os/default/osdIFErrors.c
SOURCES += $(DEVIOCSTATS)/os/default/osdBootInfo.c
SOURCES += $(DEVIOCSTATS)/os/posix/osdSystemInfo.c
SOURCES += $(DEVIOCSTATS)/os/posix/osdHostInfo.c
SOURCES += $(DEVIOCSTATS)/os/posix/osdPIDInfo.c
DBDS += $(DEVIOCSTATS)/devIocStats.dbd
TEMPLATES += $(wildcard template/*.db)
TEMPLATES += $(wildcard template/*.template)
USR_DBFLAGS += -I$(where_am_I)/template
SUBS += $(wildcard template/*.substitutions)
4) Build and install¶
To build, we will need to pass some additional variables to require:
(iocstats-build) $ make -f e3.makefile MODULE=iocstats build
Show build log
Note
We have to define MODULE for require to know the name of the module in question.
This compiles the sources against EPICS base in your environment.
To install the module into the e3 layout, run the install command:
(iocstats-build) $ make -f e3.makefile MODULE=iocstats install
Show install log
Note
We’re already leveraging conda for dependency resolution - when creating the environment, it pulled down more
packages than just the three we specified. Packages like epics-base and require also set variables and modify
paths that require’s build system uses. The next chapter ties makefiles and recipes together using conda build.
5) Start an IOC and load iocStats¶
With the module installed, you can start an IOC shell and load the module:
(iocstats-build) $ iocsh -r iocstats
Show IOC log
If everything is wired correctly, the module libraries and database definitions are available, and all data files (database files, snippets, etc.) can be loaded.