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

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 of make print-INSTALL_LOCATION_EPICS.
  • <repo> is the top directory of an EPICS-env checkout.
  • <name> after --module is the lower-case module name, such as asyn.
  • <pv_list> is a file with one PV name per line.
ToolPurposeInterfaceExit statusCalled by
audit_module_deps.bashCompares 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, --help0 report printed with no strict failure; 1 argument error or no module matched; 2 with --strict when an undeclared-observed or unknown finding existsaudit.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.bashScans 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 directory0 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 foundaudit.deps (with --report-only), check.deps, every operating system (OS) workflow, and prep-vendors.bash check-deps
check_env.bashSources 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, --help0 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 emptyaudit.env, check.env (with --strict --require-run), and every OS workflow
gen_dep_graph.bashWrites 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, -h0 image written or help; 1 rendering error, missing input file or Graphviz, or unknown option; 2 a missing option value, with a diagnosticNo target or workflow
prep-vendors.bashClones uldaq-env and open62541-env into ${HOME}/.vendor_temp_folder, builds and installs both into <installed_tree>/vendor, and builds EPICS-env against themOne 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 help0 success or help; 1 unknown command, missing argument, backup failure, refused replacement, or EOF at confirmation; otherwise the status of the failed stepNo target or workflow
pv_snapshot.bashCaptures PV values with caget into a snapshot file, and compares two snapshots PV by PV as SAME, WITHIN, DIFF, MISSING, or DISCONNcapture -l <pv_list> -o <snapshot> [-w <seconds>]; compare [-t <tolerance>] <before> <after>; --help0 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 diagnosticNo target or workflow; verify_fix_build.bash names it in the manual steps it prints
pvs_gets.bashReads 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, -70 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 availableNo target or workflow
revert_patch.bashClassifies 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 patch0 reversed or confirmed unapplied; 2 invalid or unresolved inputs; otherwise a failed command statusEvery active patch.*.revert target
tc32-expansion-query.cppC++ 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 libraryOne argument: the unique ID that the input/output controller (IOC) passes to the measComp driver0 query succeeded; 2 usage; 3 no device or more than one device matches; 4 a uldaq call failedNo target or workflow
update-release.bashSurveys 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 setcheck: 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: 2No target or workflow
verify_fix_build.bashBuilds 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; --help0 all checks passed; 1 a precondition, build, or check failed, or a dependency confirmation was refused or had no terminal; 2 wrong argument countNo target or workflow

Behavior details of the tools

  • audit_module_deps.bash reads the module list, each <module>_DEPS, and the AUDIT_* token lists through make print-<VARIABLE> in the directory that --top names. --platform defaults to the output of uname -s.

  • check_deps.bash looks only in bin/linux-x86_64 and lib/linux-x86_64 under base and each module, and in vendor/lib. An RPATH or RUNPATH entry that starts with /usr/lib, such as /usr/lib64 or /usr/lib/x86_64-linux-gnu, prints a note and does not count as a finding.

  • check_deps.bash resolves executable paths with realpath -e and removes duplicate canonical paths before calling readelf. Empty or non-directory tree paths and failed make lookups exit 2 with guidance to set INSTALL_LOCATION_EPICS or pass a valid <installed_tree>, including with --report-only.

  • revert_patch.bash runs 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-mismatch accepts 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.bash treats -f as a regular expression. -r appends .<field> to each PV name. -7 reads with pvget instead of caget. -c sets EPICS_CA_ADDR_LIST to the host’s Internet Protocol version 4 (IPv4) address and EPICS_CA_AUTO_ADDR_LIST to YES, or to NO together with -n.

  • update-release.bash update offers 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 removes configure/RELEASE.new and exits 0 without writing configure/RELEASE.

  • After the last module, update-release.bash update shows the difference and asks before it writes configure/RELEASE. It copies the replaced file to configure/RELEASE.bak.

  • verify_fix_build.bash needs configure/MODULESGEN.mk in the checkout that holds it. It writes configure/RELEASE.local and configure/CONFIG_SITE.local in both copies. It keeps module-build.log, ioc-build.log, and the empty marker file .started in the parent directory of <module_dir>. It writes .started before 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.bash prints the difference and asks for confirmation on /dev/tty. Without a terminal, or on any answer other than y or Y, it exits 1.

  • tc32-expansion-query.cpp has 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,-rpath option records the vendor library directory in the program as its RUNPATH, so it finds libuldaq.so at run time. The program and tc32-expansion-query.o stay in the repository top, and Git does not ignore them.

  • prep-vendors.bash init empties ${HOME}/.vendor_temp_folder and writes configure/CONFIG_SITE.local. Vendor preparation writes that file in each vendor checkout. epics-env and epics-build rewrite configure/RELEASE.local with vendor paths and use the Network Time Protocol (NTP) default, time.google.com, from CONFIG_BASE.

  • Before replacing an existing local configuration, prep-vendors.bash asks 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.rocky10 on Rocky 10, conf.rocky8 on Rocky 8, Red Hat Enterprise Linux (RHEL), CentOS, and Fedora, and conf elsewhere. all runs init, prep-vendors, and epics-env without a version argument.

Shell scripts in the scripts directory

ScriptUseEffectInstalled
setEpicsEnv.bashSourced 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 failsYes: install.base copies it to the top of the installed tree with mode 0644
resetEpicsEnv.bashSourcedRemoves 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 repeatedYes: install.base copies it to the top of the installed tree with mode 0644
selectEpicsEnv.bashSourced, 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.1No
build_epics.bashExecuted 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 baseNo
install_apps.bashExecuted 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.bashNo

<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.

FileContent
CONFIG_USERVARS_EXCLUDES entries that hide shell, terminal, desktop, and tool variables from the variable listing
RULES_USERThe 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.