Development setup¶
How to get a working development environment, and what the bootstrap actually does so you can fix it when something goes sideways.
The one-liner¶
git clone https://github.com/key4hep/k4Bench.git
cd k4Bench
source setup.sh
pip install --no-build-isolation -e ".[test]" # editable install + test deps
source (not bash) matters: setup.sh exports variables and activates a venv
in your current shell.
What setup.sh does¶
Reading it top to bottom, it is idempotent and safe to re-source:
- Exports
K4BENCH_REPOto the repo root and prepends the plugin build/install dirs toLD_LIBRARY_PATH, so DDG4 can find the timing libraries at run time. - Sources the Key4hep stack at
KEY4HEP_VERSION(default2026-04-08) from CVMFS — unlessKEY4HEP_STACKis already set, in which case it's left alone. - Creates a
cvmfs-venvnamedpy-venv(downloading thecvmfs-venvhelper to~/.local/binif absent) and activates it.cvmfs-venvmakes a venv that correctly inherits the CVMFS-provided Python packages. - Installs dev tooling from
requirements.txt(codespell,pre-commit) with--no-dependencies. - Builds the timing plugins via
plugin/build.sh(idempotent — only recompiles changed sources). - Installs
pre-commithooks. - Captures the environment to
.envso Jupyter kernels can reproduce the Key4hep environment (it excludes a few huge/unsafe vars likePKG_CONFIG_PATHand Singularity/Apptainer ones).
setup.sh doesn't install k4bench itself
It installs the dev tooling, builds the plugins, and sets up the venv — but
not the k4bench package. Run the editable install separately:
--no-build-isolation reuses the Key4hep-provided build backend instead of
fetching one from PyPI.
Dependency model¶
k4Bench has an unusual dependency story because it lives inside Key4hep:
| File | Holds | Installed how |
|---|---|---|
pyproject.toml dependencies |
pandas, plotly |
provided by Key4hep; pip install --no-deps avoids shadowing them |
pyproject.toml [test] extra |
pytest-cov |
pip install ".[test]" |
requirements.txt (root) |
codespell, pre-commit |
dev tooling only |
docs/requirements.txt |
MkDocs Material, mkdocstrings, … | docs build only |
dashboard/requirements.txt |
streamlit, requests, matplotlib |
dashboard container |
The runtime deps are intentionally unpinned (pyproject.toml says so): inside
Key4hep the versions are fixed by the stack, so adding constraints would only
cause conflicts.
Versioning¶
The version is derived from Git tags by setuptools-scm (configured in
pyproject.toml). Two consequences:
- A checkout with no tags / shallow clone can't compute a version. Set
SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0(the docs and dashboard builds do this). k4bench.__version__falls back to"unknown"if the package metadata isn't installed.
Building the plugins¶
Already done by setup.sh, but to rebuild after editing a .cpp:
It runs CMake (find_package(DD4hep REQUIRED COMPONENTS DDG4 DDCore)), builds in
plugin/build/, and installs to plugin/install/lib (or lib64 on RHEL). It
recompiles only when a source is newer than its .so. The Key4hep environment
must be sourced first so DD4hep headers are found.
Pre-commit¶
Configured hooks (.pre-commit-config.yaml) include ruff (lint, line length
100, target py313) and codespell (with .codespellrc). CI does not separately
run lint, so pre-commit is your guard.
Editor / Jupyter¶
The .env file written by setup.sh lets a Jupyter kernel (or VS Code) load the
full Key4hep environment without re-sourcing CVMFS. Open
JupyterNotebooks/analysis.ipynb for a ready-made analysis session.
See also¶
- Repository layout — where things live.
- Installation — the user-facing install.