Skip to content

Namespace installed headers and runtime libs to allow depthai/depthai_v3 co-installation - #1946

Open
bjsowa wants to merge 3 commits into
luxonis:ros-old-develfrom
bjsowa:jazzy-v3-namespaced-install
Open

Namespace installed headers and runtime libs to allow depthai/depthai_v3 co-installation#1946
bjsowa wants to merge 3 commits into
luxonis:ros-old-develfrom
bjsowa:jazzy-v3-namespaced-install

Conversation

@bjsowa

@bjsowa bjsowa commented Aug 17, 2026

Copy link
Copy Markdown

Purpose

The main purpose of this PR is to fix an issue which prevents installing ros-jazzy-depthai-v3 alongside ros-jazzy-depthai packages. Currently, both packages install their headers into /opt/ros/jazzy/include/depthai, which causes a collision and prevents both packages from being installed at the same time.

To avoid such collisions, ament_cmake documentation recommends namespacing the installed headers under the package name, e.g. include/depthai_v3/depthai instead of include/depthai (see ament_cmake documentation).

The package also installs third-party dependencies (xtensor, xtl, libnop, XLink) via FetchContent, which also install their headers to the same unnamespaced include/ path and a dynamic library under a generic name (libdynamic_calibration.so) to lib/ which could also collide with other variants of the same package.

Specification

  • CMAKE_INSTALL_INCLUDEDIR is now set once, globally, to include/${PROJECT_NAME} near the top of CMakeLists.txt, before dependencies are processed. This namespaces both depthai's own installed headers and the vendored FetchContent dependencies (xtensor, xtl, libnop, XLink), which all install headers via the plain CMAKE_INSTALL_INCLUDEDIR variable.
  • The vendored dependencies additionally hardcode the literal include path inside the $<INSTALL_INTERFACE:...> generator expression of their own INTERFACE_INCLUDE_DIRECTORIES target property (instead of referencing ${CMAKE_INSTALL_INCLUDEDIR}), so their exported CMake targets would otherwise still advertise the old, unnamespaced path to consumers. A new _depthai_namespace_install_interface_includedir() macro in cmake/depthaiDependencies.cmake patches this property in-place for xtl, xtensor, libnop, and XLinkPublic right after they're made available via FetchContent.
  • target_include_directories(${TARGET_CORE_NAME} ...) now references ${CMAKE_INSTALL_INCLUDEDIR} directly instead of a hardcoded include path, staying in sync automatically.
  • The runtime-downloaded libdynamic_calibration.so (used when DEPTHAI_DYNAMIC_CALIBRATION_SUPPORT is enabled) is now installed to lib/${PROJECT_NAME}/ instead of directly under lib/. INSTALL_RPATH for the core target is extended with $ORIGIN/${PROJECT_NAME} (and @loader_path/${PROJECT_NAME} on macOS) so it's still found at runtime. Windows DLL install location is left unchanged (must stay next to the loading binary).
  • Namespacing libdynamic_calibration.so under lib/${PROJECT_NAME}/ reintroduces a name collision it was meant to avoid, but at a different resolution layer (ld/ld.so search order) instead of the filesystem: on Linux, some distros (e.g. a ros-*-depthai system package) may already ship an unrelated, incompatible libdynamic_calibration.so on LD_LIBRARY_PATH. Two additional fixes close this gap:
    • ${TARGET_CORE_NAME} is now linked with -Wl,--disable-new-dtags, forcing the classic DT_RPATH tag (searched before LD_LIBRARY_PATH at runtime) instead of the default DT_RUNPATH (searched after it), so the correct, namespaced copy is always preferred at runtime regardless of environment.
    • ${TARGET_CORE_NAME} also gets an INTERFACE -Wl,-rpath-link,<dir> link option (pointing at the FetchContent source dir at build time, and at lib/${PROJECT_NAME} at install time via $<BUILD_INTERFACE:>/$<INSTALL_INTERFACE:>). Since dynamic_calibration_imported is a PRIVATE dependency, downstream consumers (e.g. depthai_bridge) otherwise have no path hint for it, and ld's link-time search order for transitive NEEDED symbols checks LD_LIBRARY_PATH before the dependency's own RPATH/RUNPATH (the reverse of the runtime order) - without this, consumers could fail to link with "undefined reference" errors against a wrong/older libdynamic_calibration.so found via LD_LIBRARY_PATH.
  • Out of scope for this PR: the vendored dependencies' own installed CMake package config files - lib/cmake/libnop, lib/cmake/XLink, share/cmake/xtensor, share/cmake/xtl, and share/pkgconfig/{xtensor,xtl}.pc - are still installed unnamespaced by their own install(EXPORT)/install(FILES) rules. Only their header install locations and exported INTERFACE_INCLUDE_DIRECTORIES are namespaced here (see Dependencies & Potential Impact below).

Old install layout:

|-- include
|   |-- XLink
|   |-- depthai
|   |-- depthai-bootloader-shared
|   |-- nop
|   |-- xtensor
|   |-- xtensor.hpp
|   `-- xtl
|-- lib
|   |-- cmake
|   |   |-- XLink
|   |   |-- depthai_v3
|   |   `-- libnop
|   |-- libdepthai_v3-core.so
|   `-- libdynamic_calibration.so
`-- share
    |-- ament_index
    |   `-- resource_index
    |-- cmake
    |   |-- xtensor
    |   `-- xtl
    |-- colcon-core
    |   `-- packages
    |-- depthai_v3
    |   |-- cmake
    |   |-- environment
    |   |-- hook
    |   |-- local_setup.bash
    |   |-- local_setup.sh
    |   |-- local_setup.zsh
    |   |-- package.bash
    |   |-- package.dsv
    |   |-- package.ps1
    |   |-- package.sh
    |   |-- package.xml
    |   `-- package.zsh
    `-- pkgconfig
        |-- xtensor.pc
        `-- xtl.pc

New install layout:

|-- include
|   `-- depthai_v3
|       |-- XLink
|       |-- depthai
|       |-- depthai-bootloader-shared
|       |-- nop
|       |-- xtensor
|       |-- xtensor.hpp
|       `-- xtl
|-- lib
|   |-- cmake
|   |   |-- XLink
|   |   |-- depthai_v3
|   |   `-- libnop
|   |-- depthai_v3
|   |   `-- libdynamic_calibration.so
|   `-- libdepthai_v3-core.so
`-- share
    |-- ament_index
    |   `-- resource_index
    |-- cmake
    |   |-- xtensor
    |   `-- xtl
    |-- colcon-core
    |   `-- packages
    |-- depthai_v3
    |   |-- cmake
    |   |-- environment
    |   |-- hook
    |   |-- local_setup.bash
    |   |-- local_setup.dsv
    |   |-- local_setup.sh
    |   |-- local_setup.zsh
    |   |-- package.bash
    |   |-- package.dsv
    |   |-- package.ps1
    |   |-- package.sh
    |   |-- package.xml
    |   `-- package.zsh
    `-- pkgconfig
        |-- xtensor.pc
        `-- xtl.pc

Dependencies & Potential Impact

  • No public API or #include statement changes for consumers - #include <depthai/...> keeps working unchanged,
  • lib/cmake/libnop, lib/cmake/XLink, share/cmake/xtensor, share/cmake/xtl, and share/pkgconfig/{xtensor,xtl}.pc remain unnamespaced (see Specification) since we can't change vendored third-party install rules without patching sources fetched fresh each configure.
  • Only affects Linux/macOS dynamic_calibration.so runtime location; Windows DLL handling is unchanged.
  • The --disable-new-dtags/-rpath-link fixes only apply on UNIX (Linux and macOS); Windows resolves DLLs differently (via PATH and the runtime-dependency-copying macro already in place) and is unaffected.
  • Downstream consumers that build against the installed depthai package (e.g. depthai_bridge) automatically pick up the -rpath-link fix through depthai::core's INTERFACE_LINK_OPTIONS - no changes needed on their end.

Deployment Plan

None / not applicable - this is a build/install-layout change only, no runtime service impact. A clean rebuild of depthai_v3 (and any package consuming it, e.g. depthai_bridge_v3, depthai_ros_driver) is recommended after pulling this change to avoid stale install artifacts from the previous unnamespaced layout.

Testing & Validation

  • Clean-rebuilt depthai_v3 and confirmed install/depthai_v3/include/ only contains the namespaced depthai_v3/ subfolder (previously also had unnamespaced nop/, XLink/, xtensor/, xtensor.hpp, xtl/).
  • Built depthai_v3 alongside depthai (V2 version) in the same workspace using colcon build --merge-install and confirmed both packages install successfully with no collisions.
  • Verified the exported depthai_v3Targets.cmake (and libnop's/XLink's own independently-exported configs) correctly reference include/depthai_v3 in INTERFACE_INCLUDE_DIRECTORIES.
  • Rebuilt depthai_bridge_v3 and depthai_ros_driver_v3 (downstream consumers via find_package(depthai_v3 CONFIG)) from scratch against the new layout - build and link successfully with no changes needed on the consumer side.
  • Confirmed libdynamic_calibration.so installs to lib/depthai_v3/ and ldd resolves it correctly via the extended RPATH (no "not found" entries).

AI Usage

Assisted-by: Claude Sonnet 5.0

Submitted code was reviewed by a human: YES

The author is taking the responsibility for the contribution: YES

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • develop

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 99a239a3-fa15-4ce5-97f5-a91783c03ad1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@bjsowa

bjsowa commented Aug 17, 2026

Copy link
Copy Markdown
Author

Similar changes apply to ros-devel (Kilted V3) or ros-release (Jazzy V2) branches

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant