Skip to content

Module template: Install complete CMake export interface#1630

Open
tbirdso wants to merge 2 commits into
nvidia-holoscan:mainfrom
tbirdso:module-cmake-export-fixup
Open

Module template: Install complete CMake export interface#1630
tbirdso wants to merge 2 commits into
nvidia-holoscan:mainfrom
tbirdso:module-cmake-export-fixup

Conversation

@tbirdso

@tbirdso tbirdso commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Overview

Fixes module template so that new projects generate a viable C++ development package.

Previous behavior

Creating a new Holoscan Module from template and then running default "./holohub package" commands would generate an incomplete C++ development package missing libraries and CMake import rules

Updated

"./holohub package" installs binary operator libraries and CMake development files (*-config.cmake, *-targets.cmake) into the Debian package for distribution and reuse.

Result

$ ./holohub create mymod --template ./modules/template
...
$ cd path/to/holoscan-mymod
$ ./holohub package holoscan-mymod
...
CPack: - package: /workspace/mymod/holoscan-mymod_0.1.0_amd64.deb generated.

$ dpkg-deb -c ./holoscan-mymod_0.1.0_amd64.deb 
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/bin/
-rwxr-xr-x root/root       877 2026-06-25 09:15 ./opt/nvidia/holoscan/bin/mymod_pipeline
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/holoscan/
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/holoscan/mymod/
-rw-r--r-- root/root       585 2026-06-25 09:16 ./opt/nvidia/holoscan/holoscan/mymod/__init__.py
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/holoscan/mymod/mymod_op/
-rw-r--r-- root/root      2496 2026-06-25 09:16 ./opt/nvidia/holoscan/holoscan/mymod/mymod_op/__init__.py
-rw-r--r-- root/root    572920 2026-06-25 09:16 ./opt/nvidia/holoscan/holoscan/mymod/mymod_op/_mymod_op.cpython-312-x86_64-linux-gnu.so
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/include/
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/include/mymod_op/
-rw-r--r-- root/root       678 2026-06-25 09:15 ./opt/nvidia/holoscan/include/mymod_op/mymod_op.hpp
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/cmake/
drwxr-xr-x root/root         0 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/cmake/holoscan-mymod/
-rw-r--r-- root/root       526 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/cmake/holoscan-mymod/holoscan-mymodConfig.cmake
-rw-r--r-- root/root      1861 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/cmake/holoscan-mymod/holoscan-mymodConfigVersion.cmake
-rw-r--r-- root/root       867 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/cmake/holoscan-mymod/holoscan_mymod_targets-release.cmake
-rw-r--r-- root/root      4203 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/cmake/holoscan-mymod/holoscan_mymod_targets.cmake
-rw-r--r-- root/root    314884 2026-06-25 09:16 ./opt/nvidia/holoscan/lib/libmymod_op.a

Follow-up tasks

Improve CI/CD coverage to generate and exercise Debian C++ development interface from a new module.

Assisted-by: Claude:claude-opus-4.8

Summary by CodeRabbit

  • New Features

    • Improved generated project packaging so operators are exported for downstream use and can be discovered with package lookup tools.
    • Added support for including the necessary CMake packaging helper during project setup.
  • Documentation

    • Expanded template guidance to better explain how package configuration files are generated and used during exports.

Fixes module template so that new projects generate a viable C++
development package.

Previous behavior: Creating a new Holoscan Module from template and then
running default "./holohub package" commands would generate an
incomplete C++ development package missing libraries and CMake import
rules

Updated: "./holohub package" installs binary operator libraries and
CMake development files (*-config.cmake, *-targets.cmake) into the
Debian package for distribution and reuse.

Assisted-by: Claude:claude-opus-4.8
Signed-off-by: Tom Birdsong <tbirdsong@nvidia.com>
@tbirdso tbirdso requested review from a team, agirault, bhashemian and wyli June 25, 2026 13:26
@tbirdso tbirdso self-assigned this Jun 25, 2026
@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the module template so that a newly generated C++ Holoscan module produces a complete Debian development package — including the operator's static library, CMake export/config files, and headers — enabling downstream find_package(<module>) usage.

  • post_gen_project.py: Copies Config.cmake.in alongside holohub_configure_deb.cmake into the generated project's cmake/ directory so configure_package_config_file() can locate the template.
  • Operator CMakeLists.txt: Adds install(TARGETS ... EXPORT holoscan_<slug>_targets) inside the C++ conditional block, registering the library in the export set.
  • Package CMakeLists.txt: Passes EXPORT_NAME to holohub_configure_deb(), triggering install of the CMake targets file and config package.

Confidence Score: 4/5

Safe to merge for C++ module templates; Python-only module packaging will fail at CMake configure time due to referencing an unpopulated export set.

The C++ path works end-to-end as shown in the PR description. However, the package-level CMakeLists.txt unconditionally passes EXPORT_NAME to holohub_configure_deb(), which triggers install(EXPORT holoscan__targets) even when the language is Python. Because the operator install(TARGETS ... EXPORT ...) is inside a Jinja2 C++ guard, the export set is never populated for Python modules, causing CMake to abort with an unknown-export error during ./holohub package on a Python-only template project.

modules/template/{{cookiecutter.module_repo_name}}/pkg/{{cookiecutter.module_repo_name}}/CMakeLists.txt — the EXPORT_NAME argument needs a {%- if cookiecutter.language == 'cpp' %} guard to match the operator-level conditional.

Important Files Changed

Filename Overview
modules/template/hooks/post_gen_project.py Adds Config.cmake.in to the list of CMake helpers copied from the HoloHub clone into the generated project's cmake/ directory, enabling holohub_configure_deb to locate the package-config template when EXPORT_NAME is set.
modules/template/{{cookiecutter.module_repo_name}}/operators/{{cookiecutter.operator_slug}}/CMakeLists.txt Adds install(TARGETS ... EXPORT ...) inside the C++ conditional block so the operator library is registered in the export set used by the package-level CMake config generation; Python-only path is unaffected.
modules/template/{{cookiecutter.module_repo_name}}/pkg/{{cookiecutter.module_repo_name}}/CMakeLists.txt Passes EXPORT_NAME unconditionally to holohub_configure_deb(). For Python-only module templates the export set is never populated, which will cause a CMake configure error when packaging.

Comments Outside Diff (1)

  1. modules/template/{{cookiecutter.module_repo_name}}/pkg/{{cookiecutter.module_repo_name}}/CMakeLists.txt, line 8-16 (link)

    P1 EXPORT_NAME is passed unconditionally, but the matching install(TARGETS ... EXPORT ...) in the operator CMakeLists.txt is guarded by {% if cookiecutter.language == 'cpp' %}. For Python-only modules the export set is never populated, so CMake will abort at configure time with install(EXPORT "holoscan_<module>_targets") given unknown export "<name>" — blocking any packaging attempt for Python modules.

Reviews (2): Last reviewed commit: "Merge branch 'main' into module-cmake-ex..." | Re-trigger Greptile

@bhashemian bhashemian left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from a potential issue (commented inline), it looks good to me! Thanks

VENDOR "{% if cookiecutter.affiliation %}{{ cookiecutter.affiliation }}{% else %}NVIDIA{% endif %}"
CONTACT "{{ cookiecutter.contact_email }}"
DEPENDS "holoscan (>= {{ cookiecutter.holoscan_version }})"
EXPORT_NAME "holoscan_{{ cookiecutter.module_slug }}_targets"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The target is only being created when we have C++, right?
https://github.com/tbirdso/holohub/blob/cf3022a8441e7d711a4e12740e2a81e2e3d32e60/modules/template/%7B%7Bcookiecutter.module_repo_name%7D%7D/operators/%7B%7Bcookiecutter.operator_slug%7D%7D/CMakeLists.txt#L20-L21

However, the export statement here is unconditional and would be exported even when we have Python only. Should we make it conditional to the C++ language? Thanks

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c2e3c1d-c7d1-4580-a823-526bbf92c3ad

📥 Commits

Reviewing files that changed from the base of the PR and between 8377416 and b8eb01d.

📒 Files selected for processing (3)
  • modules/template/hooks/post_gen_project.py
  • modules/template/{{cookiecutter.module_repo_name}}/operators/{{cookiecutter.operator_slug}}/CMakeLists.txt
  • modules/template/{{cookiecutter.module_repo_name}}/pkg/{{cookiecutter.module_repo_name}}/CMakeLists.txt

Walkthrough

The templates now export the module package target for downstream find_package use and copy the companion Config.cmake.in helper during project generation. The operator template installs its target into the export set, and the package template passes the export name.

Changes

CMake package export setup

Layer / File(s) Summary
Export metadata and target installation
modules/template/{{cookiecutter.module_repo_name}}/pkg/{{cookiecutter.module_repo_name}}/CMakeLists.txt, modules/template/{{cookiecutter.module_repo_name}}/operators/{{cookiecutter.operator_slug}}/CMakeLists.txt
holohub_configure_deb(...) now receives EXPORT_NAME, and the operator template installs {{ cookiecutter.operator_slug }} into holoscan_{{ cookiecutter.module_slug }}_targets.
Package config asset copy
modules/template/hooks/post_gen_project.py
The post-generation hook comment names Config.cmake.in, and the hook copies that file into the generated project's CMake helpers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • bhashemian
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a complete CMake export interface to the module template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants