Developer Resources
July 2, 2026 · View on GitHub
This document aims to guide users with recommended and advanced workflows to build and use Holoscan SDK. This is generally not the simplest way to use the SDK, so make sure to review the project README before getting started.
Warning
Disclaimer: we only recommend building the SDK from source if you are a developer of the SDK, or need to build the SDK with debug symbols or other options not used as part of the published packages.
- If you want to write your own operator or application, you can use the SDK as a dependency (and contribute to HoloHub).
- If you need to make other modifications to the SDK, file a feature or bug request.
- Refer to the Holoscan SDK User Guide installation instructions for guidance on installing Holoscan SDK from published packages.
Table of Contents
Building the SDK from source
Prerequisites
- Prerequisites for each supported platform are documented in the user guide.
- To build and run the SDK in a containerized environment (recommended) you'll need:
- the NVIDIA Container Toolkit v1.12.2+
- Docker, including the buildx plugin (
docker-buildx-plugin)
(Recommended) Using the run script
Call ./run build within the repository to build the build container and the CMake project.
-
If you encounter errors during the CMake build, you can execute
./run clear_cacheto remove cache/build/install folders -
Execute
./run build --helpfor more information -
Execute
./run build --dryrunto see the commands that will be executed -
That command can be broken-up in more granular commands also:
./run check_system_deps # ensure the system is properly configured for building ./run build_image # create the build Docker container ./run build # run the CMake configuration, build, and install steps
Call the ./run launch command to start and enter the build container.
- You can run from the
installorbuildtree by passing the working directory as an argument (ex:./run launch install) - Execute
./run launch --helpfor more information - Execute
./run launch --dryrunto see the commands that will be executed - Execute
./run launch --run-cmd "..."to execute a bash command directly in the container
Run the examples inside the container by running their respective commands listed within each directory README file.
Cross-compilation
While the Dockerfile to build the SDK does not currently support true cross-compilation, you can compile the Holoscan SDK for the developer kits (arm64) from a x86_64 host using an emulation environment.
- Install qemu
- Clear your build cache:
./run clear_cache - Rebuild for
linux/arm64using--arch|-aorHOLOSCAN_BUILD_ARCH:./run build --arch arm64HOLOSCAN_BUILD_ARCH=arm64 ./run build
You can then copy the install folder generated by CMake to a developer kit with a configured environment or within a container to use for running and developing applications.
(Advanced) Docker + CMake
The run script mentioned above is helpful to understand how Docker and CMake are configured and run, as commands will be printed when running it or using --dryrun.
We recommend looking at those commands if you want to use Docker and CMake manually, and reading the comments inside the script for details about each parameter (specifically the build() and launch() methods).
(Advanced) Local environment + CMake
Warning
Disclaimer: this method of building the SDK is not actively tested or maintained. Instructions below might go out of date.
Software Requirements
To build the Holoscan SDK on a local environment, refer to the list of dependencies installed in the top-level Dockerfile.
For CMake to find these dependencies, install them in default system paths, or pass CMAKE_PREFIX_PATH, CMAKE_LIBRARY_PATH, and/or CMAKE_INCLUDE_PATH during configuration.
Build example
# Configure
cmake -S $source_dir -B $build_dir \
-G Ninja \
-D CMAKE_BUILD_TYPE=Release \
-D CUDAToolkit_ROOT:PATH="/usr/local/cuda"
# Build
cmake --build $build_dir -j
# Install
cmake --install $build_dir --prefix $install_dir
The commands to run the examples are then the same as in the dockerized environment, and can be found in the respective source directory READMEs.
Build Variants and Configuration
The SDK can be built with different configurations to match various deployment targets:
CUDA Versions: 12, 13 (default in examples)
export CUDA_MAJOR=13 # or 12
./run build
Architectures: x86_64 (default), aarch64
./run build --arch aarch64
# or
export HOLOSCAN_BUILD_ARCH=aarch64
./run build
GPU Types: dgpu (default), igpu (aarch64 only)
./run build --gpu igpu # for aarch64 only
# or
export HOLOSCAN_BUILD_GPU_TYPE=igpu
./run build
Build Types: Release (default), Debug, RelWithDebInfo
./run build --type debug
# or
export CMAKE_BUILD_TYPE=Debug
./run build
Build directories follow the pattern: build-cu<version>-<arch>[-<gpu>]
Install directories follow the pattern: install-cu<version>-<arch>[-<gpu>]
Utilities
Some utilities are available in the scripts folder, others closer to the built process are listed below:
Testing
Existing tests are using GTest for C++ and pytest for Python, and can be found under tests and python/tests respectively. The Holoscan SDK uses CTest as a framework to build and execute these tests.
Test Types and Categories
The SDK includes several types of tests:
-
Core HSDK Tests: Unit, integration, and system tests for the SDK core functionality
- Located in
tests/directory - C++ tests using GTest
- Python tests using pytest
- Located in
-
Example Tests: Validation that SDK examples build and run correctly
- Tests examples from the installation tree
- Ensures examples work with the installed SDK
Test Execution Methods
You can run tests using the ./run script:
# Run all tests
./run test
# Run specific test by name (regex supported)
./run test --name <test_name>
# Run with verbose output
./run test --verbose
# Run with additional CTest options
./run test --options "-R <test_regex> --output-on-failure"
Tip
Run run test --help to see additional options.
Test Environment
When using the ./run test command, tests run inside containers, which ensures:
- Consistent environment regardless of host system
- Access to GPU via NVIDIA Container Toolkit
- Isolation from host system dependencies
The ./run script manages the container environment automatically. For advanced scenarios, tests can also be run directly on the host system (outside containers), but this requires manual setup and configuration.
Test Configuration
Test configuration is controlled through:
- Environment variables:
HOLOSCAN_INPUT_PATH: Path to test dataHOLOSCAN_TESTS_DATA_PATH: Path to test-specific dataPYTHONPATH: Python module search path
- Test data: Required test data should be available in
data/andtests/data/directories
Reproducing Test Failures
When a test fails (especially from CI), you can reproduce it locally:
-
Identify the test: From CI logs or CDash, note the exact test name
-
Match the build configuration:
export CUDA_MAJOR=13 # or 12, match CI export ARCH=x86_64 # or aarch64, match CI export GPU=dgpu # or igpu, match CI -
Run the specific test:
# Using run script ./run test --name <test_name> --verbose # Or with additional CTest options ./run test --options "-R <test_name> --verbose --output-on-failure" -
Debug in interactive container (from build tree):
./run launch build-cu13-x86_64 # Inside container: cd build-cu13-x86_64 ctest -R <test_name> --verbose --output-on-failureNote: The container is automatically managed by the
./runscript. -
Run tests from install tree (for examples):
# Launch container with install tree mounted ./run launch install-cu13-x86_64 # Inside container: # Option 1: Use the run_example_tests script (builds and tests all examples) /workspace/holoscan-sdk/install-cu13-x86_64/examples/testing/run_example_tests # Option 2: Build and test examples manually cd /workspace/holoscan-sdk/install-cu13-x86_64/examples cmake -S . -B ../examples-build cmake --build ../examples-build -j ctest --test-dir ../examples-build -R <test_name> --verbose # Option 3: Test a specific example from its directory cd /workspace/holoscan-sdk/install-cu13-x86_64/examples/<example_name>/cpp # or python # Build and run the example test -
Check test artifacts: For visual tests (e.g., Holoviz), check for:
*_fail.png: Actual output that failed*_ref.png: Expected reference image
Linting
Linting is implemented with pre-commit. Hooks (Ruff, cpplint, cmakelint, codespell, copyright, clang-format, markdownlint, and standard file checks) are listed in .pre-commit-config.yaml at the git repository root; pre-commit downloads and caches each hook’s tools the first time they run.
From the build container (or any environment where you run ./run), use:
./run lint # runs pre-commit run --all-files from the repository root
./run lint automatically resolves pre-commit: it prefers uvx when available (runs in an isolated environment without polluting your Python install), falls back to an existing pre-commit on PATH, or pip-installs it as a last resort. It then resolves the git top-level, checks for .pre-commit-config.yaml there, and runs all hooks on every tracked file. That matches a full CI-style pass. For faster, commit-oriented runs on staged files only, install hooks with pre-commit install and use plain git commit, or run pre-commit run from the repository root (see Pre-commit hooks).
Tip
For hook-specific options and filtering, see pre-commit run --help and .pre-commit-config.yaml.
Pre-commit hooks
Contributors should enable pre-commit so checks run automatically on git commit. Use the git repository root (the directory that contains .pre-commit-config.yaml).
Setup (on the host or in a shell where you commit — not only inside Docker):
# Option A: using uvx (recommended -- isolated, no pip pollution)
# Install uv first if needed: https://docs.astral.sh/uv/getting-started/installation/
uvx pre-commit install
# Option B: using pip
python3 -m pip install pre-commit
pre-commit install
Run manually (same as ./run lint for a full-tree run):
# Option A: using uvx
uvx pre-commit run --all-files
# Option B: using pip-installed pre-commit
pre-commit run --all-files
Run a single hook by id (see the config file), for example:
pre-commit run ruff-check --all-files
pre-commit run clang-format --all-files
What the hooks cover:
| Area | Hooks / notes |
|---|---|
| Repository hygiene | trailing-whitespace, end-of-file-fixer, check-yaml, check-json, check-added-large-files (standard pre-commit-hooks) |
| NVIDIA SPDX headers | check-copyright — runs scripts/check_copyright.py |
| Whitespace | remove-tabs — tabs replaced with spaces in C++, CMake, Dockerfile, Markdown, Python, and shell sources (third-party trees excluded in config) |
| Python | ruff-check (with --fix) and ruff-format — rules in .ruff.toml |
| Spelling | codespell — may rewrite files (--write-changes); settings in .codespell.toml ([tool.codespell]); lines can be ignored with // codespell-ignore or # codespell-ignore |
| C/C++/CUDA style | cpplint and clang-format (clang-format version pinned in the mirror repo; binary must be available for that hook) |
| CMake | cmakelint |
| Markdown | markdownlint — paths and config file are set in .pre-commit-config.yaml (alongside .markdownlint.yaml in this tree) |
check-copyright: Implemented by scripts/check_copyright.py. On git commit, pre-commit passes only staged paths. For pre-commit run --all-files, the script receives a wide file list and intersects it with changes since a default baseline (origin/main / main or origin/release/latest / release/latest, chosen from your current branch). Set HOLOSCAN_COPYRIGHT_BASE_REF or pass --intersect-since-ref REF to that script to pin the baseline. Run python3 scripts/check_copyright.py --help for all options.
Relationship to ./run lint: They run the same hooks from the same config. ./run lint always executes pre-commit run --all-files at the git root (entire tree). After pre-commit install, git commit runs hooks on staged files only. Several hooks apply auto-fixes (for example Ruff and codespell); review git diff after a full-tree run.
Building the User Guide
The source of the user guide hosted at https://docs.nvidia.com/holoscan/sdk-user-guide is located in docs. From the holoscan-sdk repository root, build and validate with Fern:
python3 public/docs/scripts/build_holoscan_docs.py
python3 public/docs/scripts/build_holoscan_docs.py --preview
See docs/README.md for authoring and publishing details.
VSCode
Visual Studio Code (or Cursor) can be utilized to develop the Holoscan SDK. The .devcontainer folder holds the configuration for setting up a development container with all necessary tools and libraries installed.
The ./run script contains vscode and vscode_remote commands for launching Visual Studio Code or Cursor in a container or from a remote machine, respectively.
- To launch an IDE in a dev container, use
./run vscode(-j <# of workers>or--parallel <# of workers>can be used to specify the number of parallel jobs to run during the build process). The command automatically detects and launches Cursor if available, otherwise defaults to VSCode. For more information, refer to the instructions from./run vscode -h. - To attach to an existing dev container from a remote machine, use
./run vscode_remote. For more information, refer to the instructions from./run vscode_remote -h.
Once the IDE is launched, the development container will be built and the recommended extensions will be installed automatically, along with CMake being configured.
IDE Selection Options
The ./run vscode command supports multiple IDE options:
- Automatic Detection: Cursor is launched if available, otherwise VSCode is used
- Manual Selection: Use
--ide <ide_name>to specify the IDE (vscode, vscode-insiders, cursor) - Quick Options: Use
--codeor--cursorfor direct IDE selection - Custom Binary: Use
--cmd <path>to specify a custom IDE binary
Examples:
./run vscode # Auto-detect (Cursor if available, otherwise VSCode)
./run vscode --code # Force VSCode
./run vscode --cursor # Force Cursor
./run vscode --ide cursor # Specify Cursor explicitly
./run vscode --cursor --cmd /path/to/cursor_binary # Use custom Cursor binary
Configuring CMake in the Development Container
For manual configuration of CMake, open the command palette (Ctrl + Shift + P) and run the CMake: Configure command.
Building the Source Code in the Development Container
The source code in the development container can be built by either pressing Ctrl + Shift + B or executing Tasks: Run Build Task from the command palette (Ctrl + Shift + P).
Debugging the Source Code in the Development Container
To debug the source code in the development container, open the Run and Debug view (Ctrl + Shift + D), select a debug configuration from the dropdown list, and press F5 to initiate debugging.