diff --git a/viewer/CMakeLists.txt b/viewer/CMakeLists.txt index 40358381..c4efdd09 100644 --- a/viewer/CMakeLists.txt +++ b/viewer/CMakeLists.txt @@ -180,17 +180,32 @@ IF(Qt6_VERSION VERSION_GREATER_EQUAL "6.5") INSTALL(SCRIPT ${jfjoch_viewer_deploy_script} COMPONENT viewer) ENDIF() -# Bundle the cuFFT runtime DLL next to the viewer so the installed app runs on Windows hosts that -# have an NVIDIA driver but no CUDA toolkit. cuFFT is the ONLY CUDA component we link dynamically -# (cudart and the fast-feedback indexer are static), so it is the one runtime file the toolkit would -# otherwise have to provide; the DLL is self-contained (depends only on KERNEL32). CUDA 13 keeps -# redistributable DLLs in bin/x64, earlier toolkits in bin -- glob both. Windows + GPU build only. -IF(WIN32 AND JFJOCH_CUDA_AVAILABLE) - FILE(GLOB _cufft_dll - "${CUDAToolkit_BIN_DIR}/x64/cufft64_*.dll" - "${CUDAToolkit_BIN_DIR}/cufft64_*.dll") - IF(NOT _cufft_dll) - MESSAGE(FATAL_ERROR "cuFFT runtime DLL not found under ${CUDAToolkit_BIN_DIR}") +# Bundle the cuFFT runtime next to the viewer so the installed app runs on hosts that have an NVIDIA +# driver but no CUDA toolkit. cuFFT is the ONLY CUDA component we link dynamically (cudart and the +# fast-feedback indexer are static), so it is the one runtime file the toolkit would otherwise have to +# provide; it is self-contained (Windows: depends only on KERNEL32; Linux: only libc/libstdc++ and the +# always-present driver libcuda). GPU build only. macOS has no CUDA, so it is excluded. +IF(JFJOCH_CUDA_AVAILABLE) + IF(WIN32) + # CUDA 13 keeps redistributable DLLs in bin/x64, earlier toolkits in bin -- glob both. + FILE(GLOB _cufft_dll + "${CUDAToolkit_BIN_DIR}/x64/cufft64_*.dll" + "${CUDAToolkit_BIN_DIR}/cufft64_*.dll") + IF(NOT _cufft_dll) + MESSAGE(FATAL_ERROR "cuFFT runtime DLL not found under ${CUDAToolkit_BIN_DIR}") + ENDIF() + INSTALL(FILES ${_cufft_dll} DESTINATION bin COMPONENT viewer) + ELSEIF(UNIX AND NOT APPLE AND JFJOCH_VIEWER_ONLY) + # Only the self-contained Linux .tar.gz (JFJOCH_VIEWER_ONLY) bundles cuFFT: it has no package + # manager, so it must carry its runtime deps, and we want that set really minimal. The .deb/.rpm + # builds deliberately do NOT bundle it - CUDA there is centrally managed by the distro's packages. + # Ship libcufft.so beside the binary and add an $ORIGIN rpath so the loader finds the bundled copy + # (the same self-contained-app idea as the Windows DLL). CUDA::cufft is an UNKNOWN imported target, + # so install its file directly, resolving the symlink chain (libcufft.so -> .so. -> real + # file) so the libcufft.so. the binary is linked against lands in bin. + INSTALL(CODE + "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/bin\" TYPE SHARED_LIBRARY FOLLOW_SYMLINK_CHAIN FILES \"${CUDA_cufft_LIBRARY}\")" + COMPONENT viewer) + SET_TARGET_PROPERTIES(jfjoch_viewer PROPERTIES INSTALL_RPATH "$ORIGIN") ENDIF() - INSTALL(FILES ${_cufft_dll} DESTINATION bin COMPONENT viewer) ENDIF()