macOS: ship libwgpu_native.dylib into the bundle and set the rpath

BonsaiViewer.app crashed at launch on a fresh macOS arm64 mac with:

    Library not loaded: @rpath/libwgpu_native.dylib
    Referenced from: /Applications/BonsaiViewer.app/Contents/MacOS/BonsaiViewer
    Reason: no LC_RPATH's found

The exe had \`LC_LOAD_DYLIB @rpath/libwgpu_native.dylib\` (CMake baked
that in from the upstream dylib's install_name), but zero \`LC_RPATH\`
entries, so dyld had nowhere to look — and macdeployqt hadn't pulled
the dylib in either, since it sat at \`<install_root>/lib/\` rather
than inside the .app.

Two changes:

- \`src/ifcviewer-wgpu/CMakeLists.txt\`: on macOS, when
  BUILD_BONSAIVIEWER is on, install libwgpu_native.dylib straight
  into \`BonsaiViewer.app/Contents/Frameworks/\` instead of
  \`<prefix>/lib/\`. That matches the standard macOS bundle layout.

- \`src/bonsaiviewer/CMakeLists.txt\`: set
  \`INSTALL_RPATH "@executable_path/../Frameworks"\` on the
  BonsaiViewer target on Apple. That's where dyld looks at launch,
  and where the dylib now lives.

Together the @rpath load resolves at launch without depending on
macdeployqt to follow non-Qt @rpath references (it usually only
chases Qt frameworks).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-06-02 17:05:41 +10:00
parent edc598357b
commit f66ad22f1d
2 changed files with 26 additions and 3 deletions
+13
View File
@@ -120,6 +120,19 @@ set_target_properties(BonsaiViewer PROPERTIES
MACOSX_BUNDLE ON
)
# macOS bundle runtime layout. BonsaiViewer's exe has
# `LC_LOAD_DYLIB @rpath/libwgpu_native.dylib` (CMake bakes that in from
# the dylib's own install_name). Without an LC_RPATH entry pointing at
# the bundle's Frameworks/ dir, dyld aborts at launch with
# "no LC_RPATH's found". Set the standard macOS app-bundle rpath so
# the load resolves; the wgpu CMakeLists installs the dylib straight
# into BonsaiViewer.app/Contents/Frameworks for us.
if(APPLE)
set_target_properties(BonsaiViewer PROPERTIES
INSTALL_RPATH "@executable_path/../Frameworks"
)
endif()
target_link_libraries(BonsaiViewer PRIVATE
# IfcViewer still ships SceneLoader / Federation / GeometryStreamer /
# SidecarBuilder until the GL ViewportWindow is deleted. IfcViewerWgpu
+13 -3
View File
@@ -173,10 +173,20 @@ install(FILES ${IFCVIEWER_WGPU_H_FILES}
# Install the wgpu_native shared library so the deployed runtime can find it.
# At build/run-from-build-tree time CMake adds wgpu_native_SOURCE_DIR to the
# binary's rpath automatically (IMPORTED_LOCATION dirname).
if(NOT WIN32)
install(FILES "${wgpu_native_SOURCE_DIR}/lib/${_wgpu_lib}" DESTINATION lib)
else()
#
# macOS: drop libwgpu_native.dylib straight into BonsaiViewer.app's
# Frameworks/. The exe has `LC_LOAD_DYLIB @rpath/libwgpu_native.dylib`
# (baked from the dylib's install_name), and BonsaiViewer's
# INSTALL_RPATH is set to @executable_path/../Frameworks — together
# they resolve at launch without depending on macdeployqt to follow
# non-Qt @rpath references.
if(WIN32)
install(FILES "${wgpu_native_SOURCE_DIR}/lib/${_wgpu_runtime}" DESTINATION bin)
elseif(APPLE AND BUILD_BONSAIVIEWER)
install(FILES "${wgpu_native_SOURCE_DIR}/lib/${_wgpu_lib}"
DESTINATION "BonsaiViewer.app/Contents/Frameworks")
else()
install(FILES "${wgpu_native_SOURCE_DIR}/lib/${_wgpu_lib}" DESTINATION lib)
endif()
if(BUILD_BONSAIVIEWER_TESTS)