Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Build and install verification gates

EPICS-env checks the Experimental Physics and Industrial Control System (EPICS) build at two points: before compilation, it compares module dependencies against the sources, and after installation, it inspects the installed tree. Each check is a make target in two forms. The report form prints findings and exits 0 on them, and the strict form exits with a failure code on a finding. Both forms exit with a failure code on a usage error or a missing tool. The strict form is the gate. Run the verification gates runs them, and Verification and inspection targets lists the targets.

Gates and the stage each one guards

GateReport formStageWhat it readsScript
check.module-depsaudit.module-depsAfter conf, before buildModule source treestools/audit_module_deps.bash
check.depsaudit.depsAfter installInstalled binaries and shared librariestools/check_deps.bash
check.envaudit.envAfter installInstalled setEpicsEnv.bashtools/check_env.bash

check.module-deps is static: it reads text and compiles nothing. check.deps and check.env read the installed tree, so they belong after make install. Neither aggregate github nor github.check runs them.

Static module dependency audit

check.module-deps compares, for each module, the dependencies the module declares with the dependencies its source tree shows. The declared list is the <module>_DEPS variable in configure/CONFIG_MODS_DEPS. Module set and dependencies describes that variable.

The audit reads these files in each module source tree and records every reference to another module:

SourceReferenceStrength
configure/RELEASE.local, which conf writesA macro that names a module, such as ASYNRequired
Makefile filesA database definition (.dbd) file in a DBD lineRequired
Makefile filesA library in a _LIBS lineProbable
Database definition, database, and protocol filesA referenced .dbd, database, or .proto fileRequired
Database filesA record typeProbable
Startup scripts (st.cmd, *.cmd, *.iocsh)A file that dbLoadRecords, dbLoadTemplate, or dbLoadDatabase loadsRequired
C and C++ sources and headersAn included headerProbable

The location of a file can weaken a reference to optional. A reference under a test, example, demonstration, or iocBoot directory is optional, and so is one inside a conditional block of a Makefile. Documentation directories are ignored. Build output directories are ignored too, except under a test directory, where their files count as optional. A reference to a known external library, such as ftdi, appears as external and never fails. References under os/Linux, os/posix, and os/default stay required only when the PLATFORM variable is Linux, the default on a Linux host. Only required references can produce a failing finding; probable and optional references appear in the report.

The audit reports three kinds of finding:

FindingMeaningFails the strict form
undeclared-observedA required reference names a module that <module>_DEPS does not listYes
unknownA required reference matches no module, EPICS base library, or known external libraryYes
declared-unobserved<module>_DEPS lists a module that no required reference namesNo

The audit maps several spellings to one module, such as SNCSEQ, seq, and pv to sequencer. configure/CONFIG_MODS_AUDIT holds the spellings, the EPICS base libraries and record types, and the external libraries such as ssl and z.

Because the audit reads patched sources and the RELEASE.local files that conf writes, github.check runs it after patch and conf. The feed-core and QPC patches remove source references to modules those builds do not use; the strict audit passes for both modules with or without those patches.

Installed runpath scan

check.deps inspects the Executable and Linkable Format (ELF) files of the installed tree with readelf -d. It scans the executables under base/bin/linux-x86_64 and modules/*/bin/linux-x86_64, and the shared libraries under base/lib/linux-x86_64, each module’s lib/linux-x86_64, and vendor/lib.

Executable paths are resolved to canonical paths before analysis. A versioned module directory and its unversioned link therefore contribute each executable only once to the scan and its counts.

It counts three defects:

  • An RPATH entry in any scanned file. A RUNPATH entry, the run-time library search path, belongs there instead.
  • An absolute directory in a library search path, other than a system library directory such as /usr/lib or /usr/lib/x86_64-linux-gnu.
  • A shared library whose search path lacks $ORIGIN but that needs a library found in the tree. The scan calls this a lost runpath.

A system library directory in a search path prints a note and is not a defect. Installed tree and relocation explains why these defects break relocation.

An empty installed-tree path, a path that is not a directory, or a failed make lookup of INSTALL_LOCATION_EPICS exits 2 before scanning. The diagnostic directs the caller to set INSTALL_LOCATION_EPICS or pass a valid <installed_tree>. These input errors also fail with --report-only. Run the check after make install; an existing directory alone does not prove that every required component has been installed.

Environment script library path check

check.env sources the installed setEpicsEnv.bash in a child Bash shell started with an empty environment and a PATH of /usr/bin:/bin. It then reads the LD_LIBRARY_PATH that the script produced. The empty environment keeps the caller’s own LD_LIBRARY_PATH, PATH, and EPICS_* variables out of the result.

The check reports each LD_LIBRARY_PATH entry that contains a pvxs/bundle path component. The build links the system libevent library, so that bundle directory never exists, and the dynamic loader skips a missing directory without an error. The check compares normalized entries, so doubled slashes and . segments do not hide such an entry.

Report and strict forms and their exit codes

TargetExit 0Exit 1Exit 2Exit 3
audit.module-depsAudit ranInvalid argument or no matching moduleNot usedNot used
check.module-depsNo failing findingInvalid argument or no matching moduleOne or more failing findingsNot used
audit.depsScan ranInvalid optionInvalid installed-tree input, unresolved executable path, or readelf not foundNot used
check.depsNo defectInvalid optionA defect, invalid installed-tree input, unresolved executable path, or readelf not foundNot used
audit.envCheck ran or skippedInvalid optionNot usedNot used
check.envNo findingInvalid optionOne or more findingsNo inspectable environment

check.env treats three states as no inspectable environment: no installed setEpicsEnv.bash, an empty EPICS_MODULES or EPICS_HOST_ARCH after the script runs, and an empty LD_LIBRARY_PATH. audit.env prints SKIP for the same states and exits 0.

When a script fails under a make target, make reports the script’s code in its error message, such as Error 3, and exits 2 itself.

Where continuous integration runs each gate

Every continuous integration (CI) workflow for an operating system ends with make exist, make check.env, and make check.deps, after make install. The workflows for Debian 12, Debian 13, and Rocky Linux 8 build through make github.check, so they also run check.module-deps before the build. The workflows for Rocky Linux 10, Ubuntu 24.04, and Ubuntu 26.04 run the stages one by one, with make check.module-deps immediately before make build, after patching and configuration. An audit failure stops the installation step before compilation. Supported platforms and CI lists the workflows.