Skip to content

--package fails to resolve runtime dependencies when Chrono is in a user prefix and urdfdom comes from ROS #19

Description

@salhus

Summary

cmake --install fails during the packaging step when SEA-Stack is built against a Chrono installed into a user prefix, with Chrono::Chrono_parsers pulling in urdfdom from a ROS 2 installation.

The build itself succeeds completely — all 226 targets compile and link, run_seastack is produced and runs correctly (verified on the 5sa bimodal demo with VSG water surface and mooring visualization). Only the --package install step fails.

-- Installing: /home/shusain/SEA-Stack/build/install/bin/run_seastack
-- Set non-toolchain portion of runtime path of ".../bin/run_seastack" to "$ORIGIN/../lib"
CMake Error at build/cmake_install.cmake:227 (file):
  file Could not resolve runtime dependencies:

    libChrono_core.so
    liburdfdom_model.so.4.0

[FAIL] cmake --install failed

Reproduction

./scripts/unix/build.sh --clean --verbose --package --moordyn --vsg --demos

Environment:

  • Ubuntu 24.04, GCC 13.3.0, CMake 3.28, Ninja
  • Chrono 10.0.0 installed to ~/project-chrono_v10/install (user prefix, not a system location)
  • ROS 2 Jazzy sourced (supplies urdfdom transitively via Chrono::Chrono_parsers)
  • Chrono_DIR and LD_LIBRARY_PATH both set correctly; the build links fine

Dropping --package from the same command succeeds end to end.

Root cause

In the top-level CMakeLists.txt (~L631–659):

install(TARGETS run_seastack
    RUNTIME_DEPENDENCIES
        POST_EXCLUDE_REGEXES ${_seastack_dep_exclude}
    CONFIGURATIONS Release
    RUNTIME DESTINATION bin COMPONENT runtime
    LIBRARY DESTINATION lib COMPONENT runtime)

RUNTIME_DEPENDENCIES invokes file(GET_RUNTIME_DEPENDENCIES), which on Linux resolves .so files using only the binary's RPATH plus default system paths. It deliberately ignores LD_LIBRARY_PATH (documented behaviour, so installs are reproducible without ambient environment).

Meanwhile apps/seastack/CMakeLists.txt (~L82) sets:

set_target_properties(run_seastack PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib")

So at install time the RPATH points only at the not-yet-populated bundle directory, and neither library is findable:

Library Actual location Why unresolvable
libChrono_core.so ~/project-chrono_v10/install/lib/ User prefix; not in RPATH, not a system path
liburdfdom_model.so.4.0 /opt/ros/jazzy/lib/x86_64-linux-gnu/ ROS arch-specific subdir

Neither is in the system linker cache:

$ ldconfig -p | grep -E "urdfdom_model|Chrono_core"
$ find /opt/ros/jazzy /usr/lib -name "liburdfdom_model.so*" 2>/dev/null
/opt/ros/jazzy/lib/x86_64-linux-gnu/liburdfdom_model.so.4.0
/opt/ros/jazzy/lib/x86_64-linux-gnu/liburdfdom_model.so

Note urdfdom lives in lib/x86_64-linux-gnu/, not lib/ — appending /opt/ros/jazzy/lib alone would not fix it.

POST_EXCLUDE_REGEXES currently covers ^/System/Library/, ^/usr/lib/, ^/lib/, ^/usr/libexec/, and the Python frameworks — none of which match either path.


Proposed implementation

Two coordinated changes in the top-level CMakeLists.txt. Both are needed: (1) makes Chrono-from-user-prefix resolvable, (2) stops ROS libraries being vendored into the release ZIP.

1. Derive the Chrono library directory and add a user-overridable search list

Before the install(TARGETS run_seastack ...) block, add:

# file(GET_RUNTIME_DEPENDENCIES) ignores LD_LIBRARY_PATH by design, so a Chrono
# installed outside the system paths must be pointed at explicitly.
set(SEASTACK_RUNTIME_DEP_DIRS "" CACHE STRING
    "Extra directories searched when bundling runtime dependencies for the release package.")

set(_seastack_dep_dirs ${SEASTACK_RUNTIME_DEP_DIRS})
if(TARGET Chrono::Chrono_core)
    foreach(_prop IMPORTED_LOCATION_RELEASE IMPORTED_LOCATION)
        get_target_property(_chrono_core_loc Chrono::Chrono_core ${_prop})
        if(_chrono_core_loc)
            get_filename_component(_chrono_lib_dir "${_chrono_core_loc}" DIRECTORY)
            list(APPEND _seastack_dep_dirs "${_chrono_lib_dir}")
            break()
        endif()
    endforeach()
endif()
list(REMOVE_DUPLICATES _seastack_dep_dirs)

Then pass it to both the APPLE and non-APPLE install calls:

install(TARGETS run_seastack
    RUNTIME_DEPENDENCIES
        DIRECTORIES ${_seastack_dep_dirs}
        POST_EXCLUDE_REGEXES ${_seastack_dep_exclude}
    CONFIGURATIONS Release
    RUNTIME DESTINATION bin COMPONENT runtime
    LIBRARY DESTINATION lib COMPONENT runtime)

Unset _seastack_dep_dirs alongside the existing unset(_seastack_dep_exclude).

2. Exclude ROS from the bundle

Add to _seastack_dep_exclude:

# ROS is an external runtime requirement, not a bundled dependency. urdfdom and
# friends arrive transitively via Chrono::Chrono_parsers when Chrono is built
# with ROS support; a consumer needing those components is expected to have ROS.
"^/opt/ros/"

Rationale for the split

Chrono is SEA-Stack's own dependency and belongs in the ZIP, so it needs DIRECTORIES. ROS is a transitive dependency of an optional Chrono component and does not belong in a SEA-Stack release archive, so it should be excluded rather than located. If maintainers prefer bundling ROS too, drop change (2) and document that SEASTACK_RUNTIME_DEP_DIRS=/opt/ros/<distro>/lib/x86_64-linux-gnu must be supplied — but that would make the ZIP distro-specific.

Acceptance criteria

  • ./scripts/unix/build.sh --clean --package --moordyn --vsg --demos completes without error when Chrono is installed to a non-system prefix and ROS 2 is on the environment.
  • build/install/lib/ contains libChrono_core.so and the other Chrono shared libraries.
  • build/install/lib/ contains no files originating from /opt/ros/.
  • build/install/bin/run_seastack starts and runs a demo case when LD_LIBRARY_PATH is cleared but ROS is still installed on the system (verifies $ORIGIN/../lib resolves the bundled Chrono).
  • Packaging still succeeds on a system-installed Chrono with no ROS present (no regression in the default path).
  • macOS packaging path is unaffected apart from the added DIRECTORIES argument.

Workaround until fixed

Omit --package. A plain install populates the tree downstream projects consume:

./scripts/unix/build.sh --clean --verbose --moordyn --vsg --demos

Notes

  • The failed --package run targets build/install/, so a separate pre-existing install tree (e.g. ~/SEA-Stack/install/) is left untouched and downstream consumers keep working.
  • Configure also emits CMP0144 warnings for CHRONO_ROOT; unrelated to this failure, but present in the same log.

Activity

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

Metadata

Metadata

Labels

bugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions