For quick testing, an x86_64 static build from the current HEAD is available here.
The nvme-cli project provides prebuilt CI containers that allow you to locally reproduce GitHub Actions builds for debugging and development. These containers mirror the environments used in the official CI workflows.
CI Containers Repository: linux-nvme/ci-containers
CI Build Workflow Reference: libnvme-build.yml
All CI containers are published as OCI/Docker images.
Example: Debian latest CI image:
docker pull ghcr.io/linux-nvme/debian:latestOr with Podman:
podman pull ghcr.io/linux-nvme/debian:latestStart an interactive shell inside the container:
docker run --rm -it \
--name nvme-cli-debug \
ghcr.io/linux-nvme/debian:latest \
bashOr with Podman:
podman run --rm -it \
--name nvme-cli-debug \
ghcr.io/linux-nvme/debian:latest \
bashYou are now logged into the same environment used by CI.
Inside the running container:
git clone https://github.com/linux-nvme/nvme-cli.git
cd nvme-cli(Optional) Check out a specific branch or pull request:
git checkout <branch-or-commit>The GitHub Actions workflow uses scripts/build.sh. To reproduce the CI build locally:
./scripts/build.shBuild artifacts remain inside the container unless a host volume is mounted.
The CI supports cross compilation using a dedicated cross-build container.
docker pull ghcr.io/linux-nvme/ubuntu-cross-s390x:latestOr with Podman:
podman pull ghcr.io/linux-nvme/ubuntu-cross-s390x:latestdocker run --rm -it \
--name nvme-cli-cross \
ghcr.io/linux-nvme/ubuntu-cross-s390x:latest \
bashOr with Podman:
podman run --rm -it \
--name nvme-cli-cross \
ghcr.io/linux-nvme/ubuntu-cross-s390x:latest \
bashgit clone https://github.com/linux-nvme/nvme-cli.git
cd nvme-cliExample: Cross-build for s390x:
./scripts/build.sh -b release -c gcc -t s390x crossThe exact supported targets depend on the toolchains installed in the container.
A named Valgrind test setup is registered in meson.build. It runs all unit
tests under valgrind --leak-check=full and treats any leak as a test failure.
Prerequisites: Valgrind must be installed (apt install valgrind or equivalent).
Build and run:
meson setup .build
meson compile -C .build
meson test -C .build --setup valgrindA dedicated log is written to .build/meson-logs/testlog-valgrind.txt.
A suppression file (valgrind.supp) is bundled in the repository and loaded
automatically. It covers three categories of known false positives:
- Shell script tests: Valgrind wraps the shell interpreter, not the C binary under test. Bash's internal allocations are suppressed.
- CPython internals: Import machinery, marshal, and tokenizer code in the Python interpreter generate reports that are not leaks in our code.
- SWIG module teardown: SWIG allocates a varlink object during module initialisation that CPython never releases at shutdown.
If the system provides /usr/lib/valgrind/python3.supp it is also loaded
automatically at configure time.
Any remaining failures after suppression are real issues in our C code.
ASan and UBSan are compiled into the binaries, so they each require a separate build directory. They detect different classes of bugs:
- ASan (
address): heap overflows, use-after-free, memory leaks. - UBSan (
undefined): signed integer overflow, misaligned pointer access, null dereference, out-of-bounds indexing, and other C undefined behaviour.
Build and run:
meson setup .build-asanubsan -Db_sanitize=address,undefined
meson compile -C .build-asanubsan
meson test -C .build-asanubsan --setup asanubsanNo wrapper binary is needed — sanitizer reports are emitted directly to stderr when a violation is detected.
The same known limitations apply as for Valgrind: Python tests and shell script
tests may produce false positives. Focus triage on the nvme-cli - * unit tests.