Tools and scripts reference
EPICS-env builds the Experimental Physics and Industrial Control System (EPICS)
base and modules with make. The tools/ and scripts/ directories hold the
programs around that build: checks of the installed tree, dependency and pin
surveys, process variable (PV) helpers, and scripts that set up a shell for an
installed tree. You run each Bash tool with bash. This command prints the
usage of one tool:
bash tools/check_env.bash --help
audit_module_deps.bash without --top and check_deps.bash without an
installed tree argument read make variables in the current directory; run them
from the repository top. gen_dep_graph.bash, prep-vendors.bash,
update-release.bash, and verify_fix_build.bash locate the checkout from
their own path.
Programs in the tools directory
Placeholders in the Interface column:
<installed_tree>is the installed tree for one host, the value ofmake print-INSTALL_LOCATION_EPICS.<repo>is the top directory of an EPICS-env checkout.<name>after--moduleis the lower-case module name, such asasyn.<pv_list>is a file with one PV name per line.
| Tool | Purpose | Interface | Exit status | Called by |
|---|---|---|---|---|
audit_module_deps.bash | Compares each module’s declared dependencies (<module>_DEPS) with the dependencies found in its source tree: configure/RELEASE.local, Makefiles, .dbd, database, startup, and C or C++ source files | --top <repo>, --module <name>, --format text or json, --platform <name>, --strict, --help | 0 report printed with no strict failure; 1 argument error or no module matched; 2 with --strict when an undeclared-observed or unknown finding exists | audit.module-deps, check.module-deps, and every OS workflow: through github.check on Debian 12, Debian 13, and Rocky 8, and directly on Rocky 10 and both Ubuntu workflows |
check_deps.bash | Scans each canonical installed executable once and scans the shared libraries of base, modules, and vendor/lib. It reports each file that has a run-time search path (RPATH) entry, each absolute RPATH or run-time library search path (RUNPATH) entry outside system library directories, and each shared library that needs a tree library without $ORIGIN in its RPATH or RUNPATH | -v or --verbose, --report-only, then an optional <installed_tree>; without a positional argument the tool reads INSTALL_LOCATION_EPICS from make in the current directory | 0 no finding, or any finding with --report-only; 1 unknown option; 2 any finding without --report-only, invalid installed-tree input, unresolved executable path, or readelf not found | audit.deps (with --report-only), check.deps, every operating system (OS) workflow, and prep-vendors.bash check-deps |
check_env.bash | Sources the installed setEpicsEnv.bash in a shell started with env -i, and reports each LD_LIBRARY_PATH entry that contains a pvxs/bundle path component | --epics <installed_tree> (required), --strict, --require-run, --help | 0 no finding, a finding without --strict, or check skipped; 1 argument error; 2 with --strict when a finding exists; 3 with --require-run when the script is absent, EPICS_MODULES or EPICS_HOST_ARCH stays empty, or LD_LIBRARY_PATH stays empty | audit.env, check.env (with --strict --require-run), and every OS workflow |
gen_dep_graph.bash | Writes a Graphviz image of the module dependency graph from the <module>_DEPS lines, labeled with the commit and its date; needs the dot command | -f <file> (default configure/CONFIG_MODS_DEPS), -o <file> (default epics_deps.png; the extension sets the image format), -v, -h | 0 image written or help; 1 rendering error, missing input file or Graphviz, or unknown option; 2 a missing option value, with a diagnostic | No target or workflow |
prep-vendors.bash | Clones uldaq-env and open62541-env into ${HOME}/.vendor_temp_folder, builds and installs both into <installed_tree>/vendor, and builds EPICS-env against them | One command: init, prep-uldaq, prep-open62541, prep-vendors, epics-env, epics-build <make_target>, show-env, check-deps followed by check_deps.bash options, all, OS, or help | 0 success or help; 1 unknown command, missing argument, backup failure, refused replacement, or EOF at confirmation; otherwise the status of the failed step | No target or workflow |
pv_snapshot.bash | Captures PV values with caget into a snapshot file, and compares two snapshots PV by PV as SAME, WITHIN, DIFF, MISSING, or DISCONN | capture -l <pv_list> -o <snapshot> [-w <seconds>]; compare [-t <tolerance>] <before> <after>; --help | 0 no difference beyond the tolerance; 1 a DIFF, MISSING, or DISCONN PV; 2 usage or run-time errors, including a missing option value with a diagnostic | No target or workflow; verify_fix_build.bash names it in the manual steps it prints |
pvs_gets.bash | Reads every PV of a list, sorted, with caget or pvget, once or in a loop | -l <pv_list> (required), -f <regex>, -r <field>, -w <seconds>, -c, -n, -7 | 0 run finished; 1 usage error or no -l; 2 the selected client is missing or not executable, in single and watch modes; -w runs until interrupted when the client is available | No target or workflow |
revert_patch.bash | Classifies a whole patch, reverses a confirmed applied patch, and skips a confirmed unapplied patch | [--no-backup-if-mismatch] [--prerequisites] <source> <patch> [<ordered_patches>...]; the ordered list includes the selected patch | 0 reversed or confirmed unapplied; 2 invalid or unresolved inputs; otherwise a failed command status | Every active patch.*.revert target |
tc32-expansion-query.cpp | C++ source, built separately, of a program that reports whether a measComp TC-32 or E-TC32 has the EXP-32 expansion attached, through the installed uldaq library | One argument: the unique ID that the input/output controller (IOC) passes to the measComp driver | 0 query succeeded; 2 usage; 3 no device or more than one device matches; 4 a uldaq call failed | No target or workflow |
update-release.bash | Surveys every module pin in configure/RELEASE against its remote: tag pins against the latest release tag, commit pins against the branch head | [-v] check, [-v] update, or help; reads GITHUB_TOKEN when set | check: 0 survey complete, 1 a module unreachable or without a repository URL, 2 a module has no release tag; update: 0 run finished or choice 4 taken, 1 configure/RELEASE not found; help: 0; usage error: 2 | No target or workflow |
verify_fix_build.bash | Builds a fixed module copy and a consumer IOC copy against the installed tree named by EPICS_BASE, then checks their RPATH or RUNPATH entries, their resolved libraries, and that nothing under the tree was written | <module_dir> <ioc_dir>, after setEpicsEnv.bash of the tree is sourced; --help | 0 all checks passed; 1 a precondition, build, or check failed, or a dependency confirmation was refused or had no terminal; 2 wrong argument count | No target or workflow |
Behavior details of the tools
-
audit_module_deps.bashreads the module list, each<module>_DEPS, and theAUDIT_*token lists throughmake print-<VARIABLE>in the directory that--topnames.--platformdefaults to the output ofuname -s. -
check_deps.bashlooks only inbin/linux-x86_64andlib/linux-x86_64underbaseand each module, and invendor/lib. An RPATH or RUNPATH entry that starts with/usr/lib, such as/usr/lib64or/usr/lib/x86_64-linux-gnu, prints a note and does not count as a finding. -
check_deps.bashresolves executable paths withrealpath -eand removes duplicate canonical paths before callingreadelf. Empty or non-directory tree paths and failed make lookups exit 2 with guidance to setINSTALL_LOCATION_EPICSor pass a valid<installed_tree>, including with--report-only. -
revert_patch.bashruns noninteractive GNU patch dry-runs before changing sources. For supported single-file, single-hunk patches, it checks that changed lines match the uniquely named static C function in the hunk header. Conflicting, partial, missing-input, and unresolved states fail with the source and patch identified. Both directions remaining valid is unresolved. -
Revert suppresses mismatch backups by default;
--no-backup-if-mismatchaccepts the same behavior explicitly. Existing target backups are preserved. -
Revert classification can copy real patch-owned source files into a private workspace. With
--prerequisites, it supplies context from earlier patches there. For supported static C functions, a private patch adjusts only hunk search positions; GNU patch must match the contents inside the named function. Classification leaves the original source and shipped patches unchanged. Successful classification removes that workspace; failure retains it and prints its path. Fixed module targets pass no prerequisite list. -
pvs_gets.bashtreats-fas a regular expression.-rappends.<field>to each PV name.-7reads withpvgetinstead ofcaget.-csetsEPICS_CA_ADDR_LISTto the host’s Internet Protocol version 4 (IPv4) address andEPICS_CA_AUTO_ADDR_LISTtoYES, or toNOtogether with-n. -
update-release.bash updateoffers four choices for each module whose pin differs from the latest release tag or branch head: keep the pin (the default), take the latest, enter a value, or exit. Choice 4 removesconfigure/RELEASE.newand exits 0 without writingconfigure/RELEASE. -
After the last module,
update-release.bash updateshows the difference and asks before it writesconfigure/RELEASE. It copies the replaced file toconfigure/RELEASE.bak. -
verify_fix_build.bashneedsconfigure/MODULESGEN.mkin the checkout that holds it. It writesconfigure/RELEASE.localandconfigure/CONFIG_SITE.localin both copies. It keepsmodule-build.log,ioc-build.log, and the empty marker file.startedin the parent directory of<module_dir>. It writes.startedbefore the builds and fails when a file under the installed tree changes after that point. -
When the module dependencies of the checkout differ from those of the installed module,
verify_fix_build.bashprints the difference and asks for confirmation on/dev/tty. Without a terminal, or on any answer other thanyorY, it exits 1. -
tc32-expansion-query.cpphas no make target. From the repository top, these commands build it against the uldaq library of an installed tree:VENDOR=<installed_tree>/vendor g++ -c -I"${VENDOR}/include" tools/tc32-expansion-query.cpp g++ -o tc32-expansion-query tc32-expansion-query.o -L"${VENDOR}/lib" -Wl,-rpath,"${VENDOR}/lib" -luldaq<installed_tree>is the installed tree, as in the table above. The second command compiles the source, and the third links the program in the current directory. The-Wl,-rpathoption records the vendor library directory in the program as its RUNPATH, so it findslibuldaq.soat run time. The program andtc32-expansion-query.ostay in the repository top, and Git does not ignore them. -
prep-vendors.bash initempties${HOME}/.vendor_temp_folderand writesconfigure/CONFIG_SITE.local. Vendor preparation writes that file in each vendor checkout.epics-envandepics-buildrewriteconfigure/RELEASE.localwith vendor paths and use the Network Time Protocol (NTP) default,time.google.com, fromCONFIG_BASE. -
Before replacing an existing local configuration,
prep-vendors.bashasks for confirmation when stdin is a terminal. It proceeds automatically when stdin is not a terminal. Both modes preserve a byte-identical backup as<file>.bak.<YYYYMMDDTHHMMSSZ>, using UTC and a numeric suffix on collision. Earlier backups remain unchanged. Backup failure, refusal, or EOF preserves the original and stops the invocation with status 1 before later build steps. -
The vendor builds use
conf.rocky10on Rocky 10,conf.rocky8on Rocky 8, Red Hat Enterprise Linux (RHEL), CentOS, and Fedora, andconfelsewhere.allrunsinit,prep-vendors, andepics-envwithout a version argument.
Shell scripts in the scripts directory
| Script | Use | Effect | Installed |
|---|---|---|---|
setEpicsEnv.bash | Sourced as [<fallback_arch>] [disable] | Resolves its tree and architecture before replacing known environment paths, then exports EPICS_PATH, EPICS_BASE, EPICS_MODULES, and EPICS_HOST_ARCH. Prepends modules/pmac/bin/<arch>, modules/pvxs/bin/<arch>, and base/bin/<arch> to PATH, and base/lib/<arch> to LD_LIBRARY_PATH. Returns 0 on success, 2 for invalid arguments, or 1 when tree or architecture resolution fails | Yes: install.base copies it to the top of the installed tree with mode 0644 |
resetEpicsEnv.bash | Sourced | Removes known base, pvxs, pmac, and legacy extension executable entries and the base library entry, then unsets EPICS_PATH, EPICS_BASE, EPICS_HOST_ARCH, EPICS_MODULES, and EPICS_EXTENSIONS. Returns 0, including when base is absent or reset is repeated | Yes: install.base copies it to the top of the installed tree with mode 0644 |
selectEpicsEnv.bash | Sourced, with optional arguments <epics_top> and <base_version> | Sources <epics_top>/epics/<os_id>/<os_version>/<base_version>/setEpicsEnv.bash; <epics_top> defaults to ${HOME} and <base_version> to 7.0.4.1 | No |
build_epics.bash | Executed with bash, with an optional argument <prefix> | Writes configure/CONFIG_SITE.local with INSTALL_LOCATION:=<prefix>/epics, so INSTALL_LOCATION becomes <prefix>/epics. Runs init, patch, conf, build, install, and symlinks, and creates <prefix>/epics/R<base_version> with a copy of setEpicsEnv.bash and base and modules links. It then clones EPICS-env-support into the current directory and builds it against the installed base | No |
install_apps.bash | Executed with bash, with an optional argument <prefix> | Installs PMD 7.22.0 into <prefix>/apps/pmd; on Rocky it also builds splint and installs ShellCheck under <prefix>/apps. Writes <prefix>/setEnv, which sources <prefix>/epics/R<base_version>/setEpicsEnv.bash from build_epics.bash | No |
<prefix> defaults to /usr/local. <base_version> is an EPICS base version,
such as 7.0.10; build_epics.bash and install_apps.bash take it from
make print-PATH_NAME_EPICSVERS. <os_id> and <os_version> are the ID
and VERSION_ID values in /etc/os-release. <arch> is the value of
EPICS_HOST_ARCH. setEpicsEnv.bash takes EPICS_HOST_ARCH from
EpicsHostArch.pl under base/startup or base/lib/perl, or from
base/startup/EpicsHostArch. It uses its argument as the architecture only
when none of these files exists or perl is missing. A discovery command
failure returns 1 before replacement. The argument disable suppresses the
summary without becoming the architecture. Setup and reset are safe under
set -u, compare complete path fields, and preserve independently configured
CA settings. Select among installed versions by directly sourcing each
chosen tree’s setup script. The selector’s legacy path differs from make’s
<install_location>/<release>/<os_id>-<os_version>/<base_version> layout.
User configuration files for make
make user.conf copies the two files in configure_user/ into
${HOME}/configure, keeping a backup of any file it replaces. No EPICS-env
make file reads the copies in ${HOME}/configure.
| File | Content |
|---|---|
CONFIG_USER | VARS_EXCLUDES entries that hide shell, terminal, desktop, and tool variables from the variable listing |
RULES_USER | The variable printing targets vars, env, print-<VARIABLE>, PRINT.<VARIABLE>, ls.<VARIABLE>, tree.<VARIABLE>, and cat.<VARIABLE>, the exist target, and the defaults QUIET=@, LEVEL=2, FILTER=1, and LSOPTS="-lta" |
Build version record in site-template
make src_version writes site-template/.versions, holding the time it runs
and the EPICS-env commit, and installs that file at the top of the installed
tree. make src_clean removes site-template/.versions.