Using Holohub Operators in External Applications#
Authors: Julien Jomier (NVIDIA)
Supported platforms: x86_64, aarch64
Language: C++
Last modified: August 5, 2025
Latest version: 1.0
Minimum Holoscan SDK version: 3.5.0
Tested Holoscan SDK versions: 3.5.0
Contribution metric: Level 1 - Highly Reliable
This tutorial demonstrates how to import and use Holohub operators in your own external applications. You'll learn how to fetch specific operators from the Holohub repository and integrate them into your Holoscan-based applications.
Overview#
Holohub provides a collection of pre-built operators that you can easily integrate into your applications. This tutorial shows you how to:
- Set up a CMake project that uses Holohub operators
- Fetch specific operators using the
FetchHolohubOperator.cmake
utility - Link against the required Holohub libraries
- Use the operators in your application code
Prerequisites#
- CMake 3.18 or higher
- Holoscan SDK installed
- Git
- C++ compiler (GCC, Clang, or MSVC)
Project Structure#
your_external_app/
├── CMakeLists.txt
├── main.cpp
├── main.py (optional - for Python applications)
└── build/
└── python/
└── lib/
└── holohub/ (Python modules)
Step-by-Step Guide#
1. Create Your CMakeLists.txt#
Create a CMakeLists.txt
file in your project root. The file includes two different approaches for including the FetchHolohubOperator.cmake
utility (plus an internal-only option):
cmake_minimum_required(VERSION 3.18)
project(your_app_name)
# Find the Holoscan package
find_package(holoscan REQUIRED)
# =============================================================================
# FETCH HOLOHUB OPERATOR UTILITY - TWO APPROACHES AVAILABLE
# =============================================================================
# Choose one of the following two approaches by uncommenting the desired option:
# INTERNAL ONLY: Repository Include (for Holohub repository internal use only)
# This approach is only available when the application is within the Holohub repository structure
# For external applications, use one of the two approaches below
include(../../cmake/FetchHolohubOperator.cmake)
# APPROACH 1: Download from GitHub (for external applications with internet access)
# Pros: Independent of repository structure, automatic updates, no manual copying
# Cons: Requires internet connection, depends on GitHub availability
# Uncomment the following lines to use this approach (and comment out the internal include above):
# set(FETCH_HOLOHUB_OPERATOR_URL "https://raw.githubusercontent.com/nvidia-holoscan/holohub/refs/heads/main/cmake/FetchHolohubOperator.cmake")
# set(FETCH_HOLOHUB_OPERATOR_LOCAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/FetchHolohubOperator.cmake")
# if(NOT EXISTS ${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH})
# file(DOWNLOAD
# ${FETCH_HOLOHUB_OPERATOR_URL}
# ${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH}
# SHOW_PROGRESS
# TLS_VERIFY ON
# )
# if(NOT EXISTS ${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH})
# message(FATAL_ERROR "Failed to download FetchHolohubOperator.cmake from ${FETCH_HOLOHUB_OPERATOR_URL}")
# endif()
# endif()
# include(${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH})
# APPROACH 2: Local Copy (for offline environments or version control)
# Pros: Complete independence, no internet dependency, full version control
# Cons: Requires manual file copying, need to manually update
# Uncomment the following line to use this approach (requires FetchHolohubOperator.cmake in same directory):
# include(${CMAKE_CURRENT_SOURCE_DIR}/FetchHolohubOperator.cmake)
# Fetch the specific operator you need
fetch_holohub_operator(aja_source)
# Add your executable
add_executable(${PROJECT_NAME} main.cpp)
# Link against Holohub libraries
target_link_libraries(${PROJECT_NAME}
PRIVATE
holoscan::core
holoscan::aja
)
2. Understanding the CMakeLists.txt#
Let's break down each section:
Project Setup#
cmake_minimum_required(VERSION 3.18)
project(your_app_name)
- Sets the minimum CMake version required
- Defines your project name
Holoscan Integration#
find_package(holoscan REQUIRED)
- Locates and configures the Holoscan SDK
- Makes Holoscan targets available for linking
Operator Fetching - Two Approaches Available#
The CMakeLists.txt provides two different approaches for including the FetchHolohubOperator.cmake
utility:
Internal Only: Repository Include
include(../../cmake/FetchHolohubOperator.cmake)
- ✅ Simple and straightforward
- ✅ Always uses the latest version from the repository
- ✅ No additional files needed
- ❌ INTERNAL USE ONLY - Requires the application to be within the Holohub repository structure
- ❌ Not suitable for external applications
Approach 1: Download from GitHub
set(FETCH_HOLOHUB_OPERATOR_URL "https://raw.githubusercontent.com/nvidia-holoscan/holohub/refs/heads/main/cmake/FetchHolohubOperator.cmake")
set(FETCH_HOLOHUB_OPERATOR_LOCAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/FetchHolohubOperator.cmake")
if(NOT EXISTS ${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH})
file(DOWNLOAD
${FETCH_HOLOHUB_OPERATOR_URL}
${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH}
SHOW_PROGRESS
TLS_VERIFY ON
)
if(NOT EXISTS ${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH})
message(FATAL_ERROR "Failed to download FetchHolohubOperator.cmake from ${FETCH_HOLOHUB_OPERATOR_URL}")
endif()
endif()
include(${FETCH_HOLOHUB_OPERATOR_LOCAL_PATH})
- ✅ Completely independent of repository structure
- ✅ Works for truly external applications
- ✅ Always gets the latest version from the main branch
- ❌ Requires internet connection during build
- ❌ Depends on GitHub availability
Approach 2: Local Copy
include(${CMAKE_CURRENT_SOURCE_DIR}/FetchHolohubOperator.cmake)
- ✅ Complete independence from repository structure
- ✅ No internet dependency during build
- ✅ Full version control over the utility file
- ❌ Requires manual file copying
- ❌ Need to manually update when new versions are released
Usage:
fetch_holohub_operator(aja_source)
- Downloads the
aja_source
operator from Holohub using sparse checkout
Application Building#
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME}
PRIVATE
holoscan::core
holoscan::aja
)
- Creates your executable from
main.cpp
- Links against the required Holohub libraries
3. The FetchHolohubOperator.cmake Utility#
The FetchHolohubOperator.cmake
file provides a convenient way to fetch specific operators from the Holohub repository. It uses Git sparse checkout to download only the required operator, making the process efficient.
Function Signature#
fetch_holohub_operator(OPERATOR_NAME [PATH path] [REPO_URL url] [BRANCH branch] [DISABLE_PYTHON])
Parameters#
OPERATOR_NAME
: The name of the operator to fetchPATH
(optional): The path to the operator within the Holohub repository (defaults to OPERATOR_NAME)REPO_URL
(optional): The URL of the Holohub repository (defaults to the official Holohub repo)BRANCH
(optional): The branch to checkout (defaults to "main")DISABLE_PYTHON
(optional): Flag to disable Python bindings build (Python bindings are enabled by default)
Examples#
# Fetch the aja_source operator
fetch_holohub_operator(aja_source)
# Fetch an operator with a custom path
fetch_holohub_operator(dds_operator_base PATH dds/base)
# Fetch from a custom repository
fetch_holohub_operator(custom_operator REPO_URL "https://github.com/custom/holohub.git")
# Fetch from a specific branch
fetch_holohub_operator(custom_operator BRANCH "dev")
# Fetch an operator without Python bindings
fetch_holohub_operator(aja_source DISABLE_PYTHON)
4. Choosing the Right Approach#
When deciding which approach to use for including FetchHolohubOperator.cmake
, consider your specific requirements:
Use Repository Include (Internal Only) when:
- Your application is part of the Holohub repository
- You want to always use the latest version
- You're developing within the Holohub ecosystem
- Note: This approach is only available for internal Holohub repository use
Use Approach 1 (Download from GitHub) when:
- Your application is external to the Holohub repository
- You have reliable internet connectivity during builds
- You want automatic updates from the main branch
- You need independence from the repository structure
Use Approach 2 (Local Copy) when:
- Your application needs to work offline
- You require version stability and reproducibility
- You need complete control over the utility file
- You're building for production environments
5. Create Your Application Code#
Create a main.cpp
file that uses the fetched operator:
#include "holoscan/holoscan.hpp"
#include "aja_source.hpp"
class App : public holoscan::Application {
public:
void compose() override {
using namespace holoscan;
// Create an instance of the AJA source operator
auto aja_source = make_operator<ops::AJASourceOp>("aja");
// Add the operator to your application
add_operator(aja_source);
}
};
int main(int argc, char** argv) {
auto app = holoscan::make_application<App>();
app->run();
return 0;
}
6. Building Your Application#
# Create a build directory
mkdir build && cd build
# Configure the project
cmake ..
# Build the project
make -j$(nproc)
7. Using Python Bindings#
Many Holohub operators provide Python bindings, allowing you to use them in Python applications. Here's how to work with Python bindings:
Building with Python Bindings#
By default, Python bindings are automatically built when you fetch an operator. If you want to disable Python bindings, you can use the DISABLE_PYTHON
flag:
# Disable Python bindings for this operator
fetch_holohub_operator(aja_source DISABLE_PYTHON)
Running Python Applications#
After building your project, Python modules are typically installed in the python/lib
directory within your build directory. To run Python applications that use the Holohub operators:
# Navigate to your build directory
cd build
# Set the PYTHONPATH to include the built Python modules
export PYTHONPATH=$PYTHONPATH:$(pwd)/python/lib
# Run your Python application
python3 ../main.py
Python Example#
Create a main.py
file that uses the fetched operator:
from holoscan.core import Application
from holohub.aja_source import AJASourceOp
class App(Application):
def compose(self):
# Create an instance of the AJA source operator
aja_source = AJASourceOp(self, name="aja")
# Add the operator to your application
self.add_operator(aja_source)
def main():
app = App()
app.run()
if __name__ == "__main__":
main()
Python Bindings Location#
The Python modules are built and installed in the following structure:
build/
├── python/
│ └── lib/
│ └── holohub/
│ ├── __init__.py
│ ├── aja_source.py
│ └── ... (other operator modules)
Troubleshooting Python Bindings#
- Module not found errors: Ensure
PYTHONPATH
is set correctly - Import errors: Verify that Python bindings were built (check the
python/lib
directory) - Version compatibility: Make sure your Python version is compatible with the Holoscan SDK
Available Operators#
Holohub provides many operators that you can fetch and use. Some popular ones include:
aja_source
- AJA video captureaja_sink
- AJA video outputrealsense_camera
- Intel RealSense cameradds_operator_base
- DDS communicationtensor_rt_inference
- TensorRT inferenceformat_converter
- Format conversion utilities
To find more operators, check the Holohub operators directory.
Advanced Usage#
Fetching Multiple Operators#
You can fetch multiple operators in the same project:
# Fetch multiple operators
fetch_holohub_operator(aja_source)
fetch_holohub_operator(format_converter)
fetch_holohub_operator(tensor_rt_inference)
# Link against all required libraries
target_link_libraries(${PROJECT_NAME}
PRIVATE
holoscan::core
holoscan::aja
holoscan::format_converter
holoscan::tensor_rt_inference
)
Custom Operator Paths#
If an operator is located in a subdirectory within the Holohub repository:
fetch_holohub_operator(dds_operator_base PATH dds/base)
Using Different Branches#
To use operators from a specific branch:
fetch_holohub_operator(experimental_operator BRANCH "experimental")
Troubleshooting#
Common Issues#
- CMake can't find Holoscan
- Ensure Holoscan SDK is properly installed
-
Set
CMAKE_PREFIX_PATH
to point to your Holoscan installation -
Operator not found
- Verify the operator name exists in the Holohub repository
-
Check the correct path if the operator is in a subdirectory
-
Linking errors
- Ensure you're linking against the correct Holohub libraries
- Check that the operator dependencies are satisfied
Debug Information#
To see what's being fetched, you can enable CMake verbose output:
cmake -DCMAKE_VERBOSE_MAKEFILE=ON ..
Best Practices#
- Version Pinning: Consider using specific branches or tags for production applications
- Dependency Management: Only fetch the operators you actually need
- Error Handling: Always check if the
find_package(holoscan REQUIRED)
succeeds - Documentation: Document which operators your application depends on
Example Complete Project#
See the main.cpp
, main.py
, and CMakeLists.txt
files in this directory for complete working examples that demonstrate how to use the AJA source operator from Holohub in both C++ and Python applications.
Using Holohub CLI in External Projects#
The Holohub CLI provides convenient command-line tools for managing Holohub applications, including building, running, and testing operators and applications. You can easily integrate the CLI into your external projects to leverage these functionalities.
Adding holohubCLI_wrapper to Your Project#
To use the Holohub CLI in your external project, simply copy the holohubCLI_wrapper
script from this tutorial to the root of your project.:
# Download the CLI script to your project root
wget -O /path/to/your/project/proj_cli https://raw.githubusercontent.com/nvidia-holoscan/holohub/main/tutorials/holohub_operators_external_applications/holohubCLI_wrapper
# Make it executable
chmod +x /path/to/your/project/proj_cli
Add the following to your .gitignore
file to exclude the downloaded Holohub CLI utilities:
# Holohub CLI
utilities
cmake
.local
Project Structure with CLI#
Your project structure will look like this:
your_external_app/
├── myprojectCLI # Holohub CLI script
├── CMakeLists.txt
├── main.cpp
├── main.py (optional)
└── build/
Using the CLI#
Once you have the proj_cli
script in your project, you can use it to access various Holohub CLI commands:
# Run your application
./proj_cli run <application>
# List available commands
./proj_cli --help
Note: The first time you run the script, it will automatically download the Holohub CLI scripts locally from the Holohub repository. Therefore, an internet connection is required for the initial run.
Please refer to the Holohub CLI help command for more information.
CLI Features#
The Holohub CLI provides several useful features for external projects:
- Build Management: Automated building of C++ and Python applications
- Docker Integration: Run applications in Docker containers with proper environment setup
- Testing: Run tests and validation for your operators
- Development Tools: Various utilities for Holohub development
Environment Setup#
The CLI script automatically handles: - Setting up the correct Python path - Managing Docker options (if using Docker) - Configuring environment variables - Fetching necessary utilities from the Holohub repository
Benefits for External Projects#
Using the Holohub CLI in your external project provides:
- Consistency: Same build and run processes as Holohub applications
- Automation: Automated setup and configuration
- Docker Support: Easy containerization of your applications
- Testing: Built-in testing capabilities
- Documentation: Access to Holohub's documentation and examples