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
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.
Summary
cmake --installfails during the packaging step when SEA-Stack is built against a Chrono installed into a user prefix, withChrono::Chrono_parserspulling in urdfdom from a ROS 2 installation.The build itself succeeds completely — all 226 targets compile and link,
run_seastackis produced and runs correctly (verified on the 5sa bimodal demo with VSG water surface and mooring visualization). Only the--packageinstall step fails.Reproduction
Environment:
~/project-chrono_v10/install(user prefix, not a system location)Chrono::Chrono_parsers)Chrono_DIRandLD_LIBRARY_PATHboth set correctly; the build links fineDropping
--packagefrom the same command succeeds end to end.Root cause
In the top-level
CMakeLists.txt(~L631–659):RUNTIME_DEPENDENCIESinvokesfile(GET_RUNTIME_DEPENDENCIES), which on Linux resolves.sofiles using only the binary's RPATH plus default system paths. It deliberately ignoresLD_LIBRARY_PATH(documented behaviour, so installs are reproducible without ambient environment).Meanwhile
apps/seastack/CMakeLists.txt(~L82) sets:So at install time the RPATH points only at the not-yet-populated bundle directory, and neither library is findable:
libChrono_core.so~/project-chrono_v10/install/lib/liburdfdom_model.so.4.0/opt/ros/jazzy/lib/x86_64-linux-gnu/Neither is in the system linker cache:
Note urdfdom lives in
lib/x86_64-linux-gnu/, notlib/— appending/opt/ros/jazzy/libalone would not fix it.POST_EXCLUDE_REGEXEScurrently 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:Then pass it to both the
APPLEand non-APPLEinstall calls:Unset
_seastack_dep_dirsalongside the existingunset(_seastack_dep_exclude).2. Exclude ROS from the bundle
Add to
_seastack_dep_exclude: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 thatSEASTACK_RUNTIME_DEP_DIRS=/opt/ros/<distro>/lib/x86_64-linux-gnumust be supplied — but that would make the ZIP distro-specific.Acceptance criteria
./scripts/unix/build.sh --clean --package --moordyn --vsg --demoscompletes without error when Chrono is installed to a non-system prefix and ROS 2 is on the environment.build/install/lib/containslibChrono_core.soand the other Chrono shared libraries.build/install/lib/contains no files originating from/opt/ros/.build/install/bin/run_seastackstarts and runs a demo case whenLD_LIBRARY_PATHis cleared but ROS is still installed on the system (verifies$ORIGIN/../libresolves the bundled Chrono).DIRECTORIESargument.Workaround until fixed
Omit
--package. A plain install populates the tree downstream projects consume:Notes
--packagerun targetsbuild/install/, so a separate pre-existing install tree (e.g.~/SEA-Stack/install/) is left untouched and downstream consumers keep working.CMP0144warnings forCHRONO_ROOT; unrelated to this failure, but present in the same log.