Ship jfjoch_viewer and rugnux as two packages, and cross-build rugnux for arm64
Build Packages / build:rugnux:windows (push) Failing after 2s
Build Packages / build:rugnux-tgz (x86_64) (push) Failing after 14s
Build Packages / build:rugnux:aarch64 (cross) (push) Failing after 30s
Build Packages / Unit tests (push) Canceled after 2m33s
Build Packages / build:rpm (rocky8) (push) Canceled after 0s
Build Packages / build:rpm (rocky9_sls9) (push) Canceled after 0s
Build Packages / build:rpm (rocky9) (push) Canceled after 0s
Build Packages / build:rpm (ubuntu2204) (push) Canceled after 0s
Build Packages / build:rpm (ubuntu2404) (push) Canceled after 0s
Build Packages / DIALS test (push) Canceled after 0s
Build Packages / XDS test (durin plugin) (push) Canceled after 0s
Build Packages / XDS test (JFJoch plugin) (push) Canceled after 0s
Build Packages / XDS test (neggia plugin) (push) Canceled after 0s
Build Packages / Generate python client (push) Canceled after 0s
Build Packages / build:viewer-tgz:cuda (push) Canceled after 2m29s
Build Packages / Build documentation (push) Canceled after 0s
Build Packages / Create release (push) Canceled after 0s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Canceled after 2m19s
Build Packages / build:viewer-tgz:cpu (push) Canceled after 2m31s
Build Packages / build:rpm (rocky8_sls9) (push) Canceled after 1m54s
Build Packages / build:rpm (rocky9_nocuda) (push) Canceled after 2m21s
Build Packages / build:rpm (rocky8_nocuda) (push) Canceled after 2m23s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Canceled after 2m13s
Build Packages / build:windows:cuda (push) Canceled after 2m42s
Build Packages / build:windows:nocuda (push) Canceled after 2m45s
Build Packages / build:rugnux:windows (push) Failing after 2s
Build Packages / build:rugnux-tgz (x86_64) (push) Failing after 14s
Build Packages / build:rugnux:aarch64 (cross) (push) Failing after 30s
Build Packages / Unit tests (push) Canceled after 2m33s
Build Packages / build:rpm (rocky8) (push) Canceled after 0s
Build Packages / build:rpm (rocky9_sls9) (push) Canceled after 0s
Build Packages / build:rpm (rocky9) (push) Canceled after 0s
Build Packages / build:rpm (ubuntu2204) (push) Canceled after 0s
Build Packages / build:rpm (ubuntu2404) (push) Canceled after 0s
Build Packages / DIALS test (push) Canceled after 0s
Build Packages / XDS test (durin plugin) (push) Canceled after 0s
Build Packages / XDS test (JFJoch plugin) (push) Canceled after 0s
Build Packages / XDS test (neggia plugin) (push) Canceled after 0s
Build Packages / Generate python client (push) Canceled after 0s
Build Packages / build:viewer-tgz:cuda (push) Canceled after 2m29s
Build Packages / Build documentation (push) Canceled after 0s
Build Packages / Create release (push) Canceled after 0s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Canceled after 2m19s
Build Packages / build:viewer-tgz:cpu (push) Canceled after 2m31s
Build Packages / build:rpm (rocky8_sls9) (push) Canceled after 1m54s
Build Packages / build:rpm (rocky9_nocuda) (push) Canceled after 2m21s
Build Packages / build:rpm (rocky8_nocuda) (push) Canceled after 2m23s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Canceled after 2m13s
Build Packages / build:windows:cuda (push) Canceled after 2m42s
Build Packages / build:windows:nocuda (push) Canceled after 2m45s
The viewer tarball also carried rugnux, jfjoch_extract_hkl and jfjoch_recompress. A GUI download that contains a batch processor is confusing on its own, and it forced anyone who only wanted rugnux to take Qt with it. JFJOCH_RUGNUX_ONLY is the viewer-only subtree minus viewer/ and tools/, so it needs no Qt at all, and each of the two options now yields one artifact holding one program: JFJOCH_VIEWER_ONLY jfjoch_viewer .tar.gz / installer / .dmg JFJOCH_RUGNUX_ONLY rugnux .tar.gz / .zip The two CLI tools are still built and no longer installed anywhere. rugnux gets a CPack component of its own, so its notices land in share/doc/jfjoch_rugnux. What makes the split possible is linking cuFFT statically in both products. It was the only CUDA component still dynamic - cudart and the fast-feedback indexer were already static - and shipping it as a .so meant each self-contained archive had to carry the library beside its executables and find it again through an $ORIGIN rpath. That rpath was set on jfjoch_viewer alone, while the same tarball installed three more executables, so those shipped with no runpath at all (cmake strips the build-tree one, which points at the build host's CUDA directory) and could not load the libcufft lying next to them. Static, an artifact is one file that runs: the x86_64 rugnux tarball needs only libc, libstdc++, libgcc_s, libm, libpthread, librt and libdl. The bundling code and the rpath both go away. libcufft_static.a carries a relocatable-device-code object, so a consuming executable needs a CUDA device link; CUDA 13 no longer ships the libcufft_static_nocallback.a that used to avoid this. CUDA_RESOLVE_DEVICE_SYMBOLS emits that step while leaving the host link driver alone, so the -march and -flto flags CI passes still apply. The server build keeps the shared library: its .deb/.rpm take CUDA from the distro, and every executable there would otherwise need the same device link. The guards that exclude server-side targets keyed on NOT JFJOCH_VIEWER_ONLY, which a rugnux-only build does not satisfy - it failed on jfjoch_writer pulling in JFJochImagePuller. They now key on JFJOCH_PORTABLE_ONLY, true for either product, rather than on one product's option in five places. docker/ubuntu2404 additionally cross-compiles rugnux for arm64 SBSA, which is both DGX Spark (GB10, sm_121) and Grace Hopper (GH200, sm_90); one binary with both fatbins runs on either. It needed three things beyond a cross gcc. arm64 is published on ports.ubuntu.com and Noble's deb822 sources carry no Architectures: field, so adding the architecture without splitting the entries 404s on every index. The CUDA cross packages are in neither the x86_64 repo nor the sbsa one but in cross-linux-sbsa, whose fatbinary_section.h ships only in the x86_64 target tree even though it is architecture-neutral. And HDF5 has two try_run probes, so qemu-user-static is needed as CMAKE_CROSSCOMPILING_EMULATOR; every other fetched dependency either guards its run-checks or has none. The cross-built tarball is one ELF aarch64 binary carrying all 17 GPU modules for both sm_90 and sm_121, needing no cuFFT and no CUDA runtime at run time. It is untested on hardware: XDS is x86-64 only, so CI can show it links but only a Spark or a GH200 can show it works. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SQjneRUssfhi1k9rq8Ts3h
This commit is contained in:
@@ -163,9 +163,9 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
# Build the whole viewer-only tree, not just the GUI: the "viewer" CPack component also
|
||||
# contains the portable CLI tools (rugnux, jfjoch_extract_hkl, jfjoch_recompress), which
|
||||
# must exist on disk before cpack installs the component.
|
||||
# The "viewer" component is now jfjoch_viewer alone -- rugnux ships as its own artifact
|
||||
# (build:rugnux-tgz) and the two CLI tools are no longer packaged at all. The full tree is
|
||||
# still built because the viewer links the Rugnux library for its in-process jobs.
|
||||
ninja -j16
|
||||
cpack
|
||||
- name: Upload viewer tgz to release
|
||||
@@ -188,6 +188,113 @@ jobs:
|
||||
mv "$file" "$tgz"
|
||||
python3 gitea_upload_file.py "$tgz"
|
||||
done
|
||||
build-rugnux-tgz:
|
||||
name: build:rugnux-tgz (x86_64)
|
||||
runs-on: jfjoch_rocky8
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Clean previous build
|
||||
shell: bash
|
||||
run: rm -rf build-rugnux # self-hosted runners reuse the workspace volume
|
||||
- name: Configure rugnux build
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -G Ninja -S . -B build-rugnux -DJFJOCH_RUGNUX_ONLY=ON -DJFJOCH_USE_CUDA=ON \
|
||||
${{ env.LINUX_CMAKE_FLAGS }} -DCMAKE_BUILD_TYPE=Release
|
||||
- name: Build rugnux tgz
|
||||
shell: bash
|
||||
run: cmake --build build-rugnux --target package -j16
|
||||
- name: Verify the artifact is self-contained
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
rm -rf /tmp/rgx && mkdir -p /tmp/rgx
|
||||
tar xf build-rugnux/rugnux-*.tar.gz -C /tmp/rgx
|
||||
bin=$(find /tmp/rgx -name rugnux -type f)
|
||||
# cuFFT is static now: no libcufft beside the binary and none needed at run time.
|
||||
! ldd "$bin" | grep -q cufft
|
||||
! find /tmp/rgx -name 'libcufft*'
|
||||
- name: Upload rugnux tgz to release
|
||||
if: github.ref_type == 'tag'
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
files: build-rugnux/rugnux-*.tar.gz
|
||||
|
||||
build-rugnux-windows:
|
||||
name: build:rugnux:windows
|
||||
runs-on: windows-11-cuda-qt
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Configure rugnux build
|
||||
shell: bash
|
||||
# No Qt needed: JFJOCH_RUGNUX_ONLY is the portable subtree minus viewer/.
|
||||
run: |
|
||||
cmake -S . -B build-rugnux -DJFJOCH_RUGNUX_ONLY=ON -DJFJOCH_USE_CUDA=ON \
|
||||
${{ env.MSVC_ARCH_CMAKE_FLAGS }} -DCMAKE_BUILD_TYPE=Release
|
||||
- name: Build rugnux zip
|
||||
shell: bash
|
||||
run: cmake --build build-rugnux --config Release --target PACKAGE -j
|
||||
- name: Upload rugnux zip to release
|
||||
if: github.ref_type == 'tag'
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
files: build-rugnux/rugnux-*.zip
|
||||
|
||||
build-rugnux-arm:
|
||||
name: build:rugnux:aarch64 (cross)
|
||||
# Cross-compiled on an x86_64 runner: nvcc, gcc and cmake all run native and only emit aarch64,
|
||||
# so this costs about what a normal build costs. Uses the ordinary ubuntu2404 image, which now
|
||||
# also carries the aarch64 toolchain and the CUDA sbsa cross tree.
|
||||
runs-on: jfjoch_ubuntu2404
|
||||
container:
|
||||
image: gitea.psi.ch/leonarski_f/jfjoch_ubuntu2404:2508
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Clean previous build
|
||||
shell: bash
|
||||
run: rm -rf build-aarch64 # self-hosted runners reuse the workspace volume
|
||||
- name: Configure (cross to aarch64 SBSA)
|
||||
shell: bash
|
||||
# NOT ${{ env.LINUX_CMAKE_FLAGS }}: that pins -march=x86-64-v3, which an aarch64 compiler
|
||||
# rejects. The aarch64 baseline already has NEON and a vectorised round, so the Eigen gap
|
||||
# that flag closes on x86 does not exist here.
|
||||
# sm_90 = GH200 (Grace Hopper, e.g. ALPS), sm_121 = GB10 (DGX Spark). One tarball, both.
|
||||
run: |
|
||||
cmake -G Ninja -S . -B build-aarch64 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=/opt/cross/aarch64-sbsa.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DJFJOCH_RUGNUX_ONLY=ON \
|
||||
-DJFJOCH_USE_CUDA=ON \
|
||||
-DJFJOCH_CUDA_ARCHITECTURES="90;121"
|
||||
- name: Build and package
|
||||
shell: bash
|
||||
run: cmake --build build-aarch64 --target package -j16
|
||||
# A cross build that silently produced x86_64 still packages cleanly, so assert the artifact.
|
||||
- name: Verify the tarball is really aarch64
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tgz=$(ls build-aarch64/*.tar.gz | head -1)
|
||||
echo "checking $tgz"
|
||||
rm -rf /tmp/tgzcheck && mkdir -p /tmp/tgzcheck
|
||||
tar xf "$tgz" -C /tmp/tgzcheck
|
||||
bin=$(find /tmp/tgzcheck -name rugnux -type f | head -1)
|
||||
file "$bin"
|
||||
file "$bin" | grep -q "ARM aarch64"
|
||||
# nothing x86 may have leaked in (libjpeg-turbo's ExternalProject is the classic culprit)
|
||||
! find /tmp/tgzcheck -type f -exec file {} + | grep -q "x86-64"
|
||||
# cuFFT must be linked statically: no libcufft beside the binary, none needed at run time
|
||||
! ldd "$bin" 2>/dev/null | grep -q cufft
|
||||
# both GPU targets present in the fatbin
|
||||
cuobjdump --list-elf "$bin" | grep -q sm_90
|
||||
cuobjdump --list-elf "$bin" | grep -q sm_121
|
||||
- name: Upload tarball to release
|
||||
if: github.ref_type == 'tag'
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
files: build-aarch64/*.tar.gz
|
||||
|
||||
build-rpm:
|
||||
name: build:rpm (${{ matrix.distro }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
|
||||
+94
-16
@@ -19,15 +19,46 @@ SET(JFJOCH_INSTALL_DRIVER_SOURCE OFF CACHE BOOL "Install kernel driver source (i
|
||||
SET(JFJOCH_USE_CUDA ON CACHE BOOL "Compile Jungfraujoch with CUDA")
|
||||
SET(JFJOCH_VIEWER_BUILD OFF CACHE BOOL "Compile Jungfraujoch viewer")
|
||||
|
||||
# The two shippable products are built separately, one per configure, and each produces exactly one
|
||||
# artifact holding exactly one program:
|
||||
#
|
||||
# JFJOCH_VIEWER_ONLY jfjoch_viewer .tar.gz (Linux) / installer (Windows) / .dmg (macOS)
|
||||
# JFJOCH_RUGNUX_ONLY rugnux .tar.gz (Linux, incl. cross-built aarch64) / .zip (Windows)
|
||||
#
|
||||
# They used to be one package: the viewer tarball also carried rugnux and two CLI tools, which made
|
||||
# the download confusing (a GUI package containing a batch processor) and meant a rugnux user had to
|
||||
# take Qt with it. Splitting them is possible because cuFFT is now linked statically, so neither
|
||||
# artifact has to ship a runtime library beside its executable.
|
||||
SET(JFJOCH_RUGNUX_ONLY OFF CACHE BOOL "Compile only rugnux, the offline analysis CLI (no Qt)")
|
||||
|
||||
# Only the viewer (and its portable dependency tree) is supported on Windows and macOS -- the
|
||||
# broker/receiver/FPGA/writer server stack is Linux-only. Force viewer-only on those platforms so a
|
||||
# plain configure builds the right subset; on Linux it remains a user-togglable option.
|
||||
IF (WIN32 OR APPLE)
|
||||
# plain configure builds the right subset; on Linux it remains a user-togglable option. A rugnux-only
|
||||
# build is portable too (it is the same subtree minus viewer/), so asking for it explicitly wins.
|
||||
# TRUE for either portable product. Both build the same subtree of analysis libraries and neither
|
||||
# wants any server-side target -- the broker service, the writer executables, the FPGA/detector
|
||||
# tools or the frontend -- so the guards that exclude those key on this rather than on one product's
|
||||
# option. Set below, once JFJOCH_VIEWER_ONLY has been resolved.
|
||||
|
||||
IF ((WIN32 OR APPLE) AND NOT JFJOCH_RUGNUX_ONLY)
|
||||
SET(JFJOCH_VIEWER_ONLY ON CACHE BOOL "Compile only jfjoch_viewer and its dependencies" FORCE)
|
||||
ELSEIF (JFJOCH_RUGNUX_ONLY)
|
||||
SET(JFJOCH_VIEWER_ONLY OFF CACHE BOOL "Compile only jfjoch_viewer and its dependencies" FORCE)
|
||||
ELSE()
|
||||
SET(JFJOCH_VIEWER_ONLY OFF CACHE BOOL "Compile only jfjoch_viewer and its dependencies")
|
||||
ENDIF()
|
||||
|
||||
IF (JFJOCH_VIEWER_ONLY OR JFJOCH_RUGNUX_ONLY)
|
||||
SET(JFJOCH_PORTABLE_ONLY ON)
|
||||
ELSE()
|
||||
SET(JFJOCH_PORTABLE_ONLY OFF)
|
||||
ENDIF()
|
||||
|
||||
# GPU architectures to generate device code for. Overridable so a build that targets one machine
|
||||
# can pin its own set instead of paying for the full fat binary -- e.g. a cross build for
|
||||
# GB10 (DGX Spark, sm_121) and GH200 (Grace Hopper, sm_90) passes -DJFJOCH_CUDA_ARCHITECTURES="90;121".
|
||||
SET(JFJOCH_CUDA_ARCHITECTURES "" CACHE STRING "Override the CUDA architecture list (empty = the default set below)")
|
||||
|
||||
SET (ZLIB_USE_STATIC_LIBS TRUE)
|
||||
|
||||
FIND_PACKAGE(ZLIB REQUIRED)
|
||||
@@ -72,7 +103,11 @@ CHECK_LANGUAGE(CUDA)
|
||||
# Hopper, and Blackwell in both its data-centre and consumer forms. A bare entry emits SASS *and*
|
||||
# PTX for that architecture, so the newest one here also covers any future GPU: the driver
|
||||
# JIT-compiles its PTX on first launch. Volta (V100) is added below, once the nvcc version is known.
|
||||
SET(CMAKE_CUDA_ARCHITECTURES 75 80 86 89 90 100 120)
|
||||
IF (JFJOCH_CUDA_ARCHITECTURES)
|
||||
SET(CMAKE_CUDA_ARCHITECTURES ${JFJOCH_CUDA_ARCHITECTURES})
|
||||
ELSE()
|
||||
SET(CMAKE_CUDA_ARCHITECTURES 75 80 86 89 90 100 120)
|
||||
ENDIF()
|
||||
SET(CMAKE_CUDA_STANDARD 20)
|
||||
SET(CMAKE_CUDA_STANDARD_REQUIRED True)
|
||||
SET(CMAKE_CUDA_FLAGS_RELEASE "-O3 -lineinfo")
|
||||
@@ -90,7 +125,7 @@ IF (CMAKE_CUDA_COMPILER)
|
||||
SET(JFJOCH_CUDA_AVAILABLE ON)
|
||||
# Blackwell GB10 (DGX Spark) is sm_121, only known to nvcc >= 12.9; add it there so the
|
||||
# binary runs natively on Spark instead of having the driver JIT sm_120 PTX for it.
|
||||
IF (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "12.9")
|
||||
IF (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "12.9" AND NOT JFJOCH_CUDA_ARCHITECTURES)
|
||||
LIST(APPEND CMAKE_CUDA_ARCHITECTURES 121)
|
||||
ENDIF()
|
||||
# Volta (V100) is sm_70, and PTX only ever JITs *forwards* - without an sm_70 entry a
|
||||
@@ -99,7 +134,7 @@ IF (CMAKE_CUDA_COMPILER)
|
||||
# for Volta, so only a CUDA 12 toolkit can emit it; 12.8/12.9 still do, but warn on
|
||||
# every .cu, hence -Wno-deprecated-gpu-targets. Volta is the floor - older GPUs are
|
||||
# not in use here.
|
||||
IF (CMAKE_CUDA_COMPILER_VERSION VERSION_LESS "13.0")
|
||||
IF (CMAKE_CUDA_COMPILER_VERSION VERSION_LESS "13.0" AND NOT JFJOCH_CUDA_ARCHITECTURES)
|
||||
LIST(APPEND CMAKE_CUDA_ARCHITECTURES 70)
|
||||
SET(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Wno-deprecated-gpu-targets")
|
||||
ENDIF()
|
||||
@@ -212,8 +247,8 @@ SET(CMAKE_POLICY_VERSION_MINIMUM 3.5)
|
||||
|
||||
# libzmq must be made available BEFORE sls_detector_package for the override above to take effect.
|
||||
FetchContent_MakeAvailable(libzmq)
|
||||
IF (JFJOCH_VIEWER_ONLY)
|
||||
# A viewer-only build still needs zstd/hdf5/spdlog/httplib (JFJochReader uses httplib).
|
||||
IF (JFJOCH_PORTABLE_ONLY)
|
||||
# A portable build still needs zstd/hdf5/spdlog/httplib (JFJochReader uses httplib).
|
||||
# Only sls_detector_package (detector) and catch2 (tests) are not built here -- and sls
|
||||
# in particular does not configure under MSVC -- so skip just those two.
|
||||
FetchContent_MakeAvailable(zstd hdf5 spdlog httplib)
|
||||
@@ -326,7 +361,22 @@ IF (JFJOCH_VIEWER_BUILD OR JFJOCH_VIEWER_ONLY)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF (JFJOCH_VIEWER_ONLY)
|
||||
IF (JFJOCH_RUGNUX_ONLY)
|
||||
# The viewer-only subtree minus viewer/ and tools/: just rugnux and what it links. broker/ is
|
||||
# here for JFJochAPI alone (JFJochReader links it); its service targets are gated out. preview/
|
||||
# arrives through JFJochWriter -> JFJochPreview, so libjpeg-turbo and libtiff are built too.
|
||||
ADD_SUBDIRECTORY(jungfrau)
|
||||
ADD_SUBDIRECTORY(compression)
|
||||
ADD_SUBDIRECTORY(common)
|
||||
ADD_SUBDIRECTORY(gemmi_gph)
|
||||
ADD_SUBDIRECTORY(frame_serialize)
|
||||
ADD_SUBDIRECTORY(preview)
|
||||
ADD_SUBDIRECTORY(writer)
|
||||
ADD_SUBDIRECTORY(image_analysis)
|
||||
ADD_SUBDIRECTORY(broker)
|
||||
ADD_SUBDIRECTORY(reader)
|
||||
ADD_SUBDIRECTORY(rugnux)
|
||||
ELSEIF (JFJOCH_VIEWER_ONLY)
|
||||
# Minimal subtree: jfjoch_viewer and only the libraries it transitively links.
|
||||
# (broker here provides JFJochAPI only; its service targets are gated out.)
|
||||
ADD_SUBDIRECTORY(jungfrau)
|
||||
@@ -374,7 +424,7 @@ ELSE()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF (NOT JFJOCH_WRITER_ONLY AND NOT JFJOCH_VIEWER_ONLY)
|
||||
IF (NOT JFJOCH_WRITER_ONLY AND NOT JFJOCH_PORTABLE_ONLY)
|
||||
ADD_CUSTOM_COMMAND(OUTPUT frontend/dist/index.html
|
||||
COMMAND npm ci
|
||||
COMMAND npm run build
|
||||
@@ -411,7 +461,9 @@ ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
SET(CPACK_PACKAGE_NAME "jfjoch")
|
||||
|
||||
# Select the components to package based on build mode
|
||||
if (JFJOCH_VIEWER_ONLY)
|
||||
if (JFJOCH_RUGNUX_ONLY)
|
||||
set(CPACK_COMPONENTS_ALL rugnux)
|
||||
elseif (JFJOCH_VIEWER_ONLY)
|
||||
set(CPACK_COMPONENTS_ALL viewer)
|
||||
else()
|
||||
set(CPACK_COMPONENTS_ALL jfjoch writer)
|
||||
@@ -430,10 +482,10 @@ set(CPACK_PACKAGE_VERSION ${JFJOCH_VERSION})
|
||||
|
||||
# OS-aware packaging: DragNDrop (.dmg) on macOS, NSIS installer on Windows, DEB on Debian/Ubuntu,
|
||||
# RPM on RHEL/Rocky. macOS/Windows are checked first because the /etc/* probes below are Linux-only.
|
||||
if (APPLE)
|
||||
if (APPLE AND NOT JFJOCH_RUGNUX_ONLY)
|
||||
# .dmg containing jfjoch_viewer.app (Qt runtime already deployed into the bundle).
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
elseif (WIN32)
|
||||
elseif (WIN32 AND NOT JFJOCH_RUGNUX_ONLY)
|
||||
# NSIS installer .exe (Qt runtime deployed next to the binary by windeployqt).
|
||||
set(CPACK_GENERATOR "NSIS")
|
||||
|
||||
@@ -468,7 +520,20 @@ elseif (WIN32)
|
||||
# backslash there ("bin\jfjoch...") is an invalid escape that cmake 4.x (CMP0010 strict, e.g. the
|
||||
# VS-bundled cmake) rejects when cpack re-parses it. Windows accepts the forward slash at runtime.
|
||||
set(CPACK_NSIS_INSTALLED_ICON_NAME "bin/jfjoch_viewer.exe")
|
||||
elseif (JFJOCH_VIEWER_ONLY)
|
||||
elseif (WIN32)
|
||||
# rugnux on Windows is a single self-contained rugnux.exe (cuFFT, cudart and the fast-feedback
|
||||
# indexer are all static, so nothing rides alongside it). An NSIS installer would be ceremony
|
||||
# around one file that a user drops wherever they like, so ship a .zip: the .exe plus the
|
||||
# licence notices the component installs.
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
||||
set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)
|
||||
if (JFJOCH_CUDA_AVAILABLE)
|
||||
set(CPACK_PACKAGE_FILE_NAME "rugnux-${JFJOCH_VERSION}-win64-cuda${CUDAToolkit_VERSION_MAJOR}")
|
||||
else()
|
||||
set(CPACK_PACKAGE_FILE_NAME "rugnux-${JFJOCH_VERSION}-win64-cpu")
|
||||
endif()
|
||||
elseif (JFJOCH_VIEWER_ONLY OR JFJOCH_RUGNUX_ONLY)
|
||||
# Linux portable viewer: a single self-contained .tar.gz of jfjoch_viewer (Qt is linked
|
||||
# statically here, so there is nothing external to ship alongside the binary). Built on the
|
||||
# oldest supported distro (RHEL 8) for a low glibc floor, so the archive runs on any newer
|
||||
@@ -485,10 +550,23 @@ elseif (JFJOCH_VIEWER_ONLY)
|
||||
# CPACK_DEB_COMPONENT_INSTALL / CPACK_RPM_COMPONENT_INSTALL in the DEB/RPM branches below.
|
||||
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
||||
set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)
|
||||
if (JFJOCH_CUDA_AVAILABLE)
|
||||
set(CPACK_PACKAGE_FILE_NAME "jfjoch_viewer-${JFJOCH_VERSION}-linux-cuda${CUDAToolkit_VERSION_MAJOR}")
|
||||
if (JFJOCH_RUGNUX_ONLY)
|
||||
set(_jfjoch_tgz_name "rugnux")
|
||||
else()
|
||||
set(CPACK_PACKAGE_FILE_NAME "jfjoch_viewer-${JFJOCH_VERSION}-linux-cpu")
|
||||
set(_jfjoch_tgz_name "jfjoch_viewer")
|
||||
endif()
|
||||
# A cross-built archive is named for the TARGET arch, never the build host's: CMAKE_SYSTEM_PROCESSOR
|
||||
# is what the toolchain file declares, so an aarch64 tarball cannot be mistaken for an x86 one.
|
||||
# Left off for a native build, so the existing x86 artifact names do not change.
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
set(_jfjoch_tgz_arch "-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
else()
|
||||
set(_jfjoch_tgz_arch "")
|
||||
endif()
|
||||
if (JFJOCH_CUDA_AVAILABLE)
|
||||
set(CPACK_PACKAGE_FILE_NAME "${_jfjoch_tgz_name}-${JFJOCH_VERSION}-linux${_jfjoch_tgz_arch}-cuda${CUDAToolkit_VERSION_MAJOR}")
|
||||
else()
|
||||
set(CPACK_PACKAGE_FILE_NAME "${_jfjoch_tgz_name}-${JFJOCH_VERSION}-linux${_jfjoch_tgz_arch}-cpu")
|
||||
endif()
|
||||
elseif (EXISTS "/etc/debian_version")
|
||||
set(CPACK_PACKAGE_LICENSE "GPL-3.0-only")
|
||||
|
||||
@@ -6,9 +6,9 @@ AUX_SOURCE_DIRECTORY(gen/model MODEL_SOURCES)
|
||||
ADD_LIBRARY(JFJochAPI STATIC ${MODEL_SOURCES})
|
||||
TARGET_INCLUDE_DIRECTORIES(JFJochAPI PUBLIC gen/model)
|
||||
|
||||
# The broker service pulls in the receiver/detector stack. A viewer-only build
|
||||
# The broker service pulls in the receiver/detector stack. A portable build (viewer or rugnux)
|
||||
# needs JFJochAPI (the shared OpenAPI model, above) but none of this machinery.
|
||||
IF (NOT JFJOCH_VIEWER_ONLY)
|
||||
IF (NOT JFJOCH_PORTABLE_ONLY)
|
||||
# Jungfraujoch Broker (abstract from HTTP service)
|
||||
ADD_LIBRARY(JFJochBroker STATIC
|
||||
JFJochStateMachine.cpp JFJochStateMachine.h
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
# JOBS=4 docker/build_images.sh # all four at once
|
||||
# JOBS=1 docker/build_images.sh # serial
|
||||
# TAG=2607b docker/build_images.sh # override the tag (default 2607b)
|
||||
#
|
||||
# The tag has to match what .gitea/workflows/build_and_test.yml asks the runner for, or CI pulls a
|
||||
# different image than the one just built. Currently jfjoch_rocky8:2511 and jfjoch_ubuntu2404:2508 --
|
||||
# ubuntu2404 being the image that also carries the aarch64 cross toolchain, so:
|
||||
# TAG=2508 docker/build_images.sh ubuntu2404
|
||||
# PUSH=1 docker/build_images.sh # build (parallel) then push (serial; needs docker login)
|
||||
#
|
||||
# Parallel stdout would be an unreadable interleave, so each build streams to its own log file:
|
||||
|
||||
@@ -16,6 +16,18 @@ ARG EIGEN_VERSION=3.4.0
|
||||
|
||||
# Update base and install toolchain + static-Qt build dependencies
|
||||
# (XCB/X11/OpenGL/EGL/DBus/fontconfig/freetype/zlib headers needed to build static Qt).
|
||||
#
|
||||
# arm64 is enabled as a second dpkg architecture here so this one image can also CROSS-COMPILE the
|
||||
# rugnux CLI for aarch64 (DGX Spark GB10 / Grace Hopper GH200 -- both arm64 SBSA). Noble's deb822
|
||||
# ubuntu.sources carries no Architectures: field, so a bare `dpkg --add-architecture arm64` sends apt
|
||||
# to archive.ubuntu.com for arm64 indexes and 404s on every one; arm64 is published on
|
||||
# ports.ubuntu.com instead. Pin the stock entries to amd64 and add a ports entry for arm64.
|
||||
RUN set -eux; \
|
||||
dpkg --add-architecture arm64; \
|
||||
sed -i 's/^Components: main/Architectures: amd64\nComponents: main/' /etc/apt/sources.list.d/ubuntu.sources; \
|
||||
printf '\nTypes: deb\nURIs: http://ports.ubuntu.com/ubuntu-ports\nSuites: noble noble-updates noble-security\nComponents: main restricted universe multiverse\nArchitectures: arm64\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\n' \
|
||||
>> /etc/apt/sources.list.d/ubuntu.sources
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
@@ -188,6 +200,47 @@ RUN set -eux; \
|
||||
# through Qt's exported config, so DBus1Config.cmake must be on CMAKE_PREFIX_PATH for the viewer build.
|
||||
ENV CMAKE_PREFIX_PATH=/opt/qt-${QT_VERSION}-static:/opt/dbus-${DBUS_VERSION}-static:/opt/eigen-3.4
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
# aarch64 cross-compilation support (rugnux only -- the viewer is not cross-built).
|
||||
#
|
||||
# crossbuild-essential-arm64 the aarch64 gcc/g++.
|
||||
# qemu-user-static HDF5 runs two try_run() probes (config/ConfigureChecks.cmake) that
|
||||
# need CMAKE_CROSSCOMPILING_EMULATOR. libzmq guards its own run-checks
|
||||
# with NOT CMAKE_CROSSCOMPILING; Ceres, libtiff, zstd, Catch2, spdlog,
|
||||
# cpp-httplib, FFTW and ffbidx have no run-checks at all.
|
||||
# binutils-aarch64-linux-gnu reading aarch64 ELF on the build host.
|
||||
# :arm64 libraries ZLIB is one of the project's two external dependencies (Eigen, the
|
||||
# other, is header-only and installed above); OpenSSL is needed by the
|
||||
# libcurl the build fetches.
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
crossbuild-essential-arm64 binutils-aarch64-linux-gnu qemu-user-static \
|
||||
zlib1g-dev:arm64 libssl-dev:arm64; \
|
||||
apt-get clean; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# CUDA cross target tree -> /usr/local/cuda/targets/sbsa-linux, beside the image's x86_64 tree.
|
||||
# These packages are NOT in the x86_64 CUDA repo (it publishes none) and NOT in the sbsa repo (that
|
||||
# is the NATIVE arm64 one a Spark or GH200 installs locally). They have their own repo and keyring:
|
||||
# repos/ubuntu2404/cross-linux-sbsa/
|
||||
# repos/ubuntu2404/cross-linux-aarch64/ also exists -- that is the Tegra/Jetson tree, not this one.
|
||||
RUN set -eux; \
|
||||
cd /tmp; \
|
||||
wget -q https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/cross-linux-sbsa/cuda-keyring_1.1-1_all.deb; \
|
||||
dpkg -i cuda-keyring_1.1-1_all.deb; rm cuda-keyring_1.1-1_all.deb; \
|
||||
apt-get update; \
|
||||
V=$(nvcc --version | sed -nE 's/.*release ([0-9]+)\.([0-9]+).*/\1-\2/p'); \
|
||||
apt-get install -y --no-install-recommends \
|
||||
cuda-cudart-cross-sbsa-$V cuda-crt-cross-sbsa-$V \
|
||||
cuda-culibos-cross-sbsa-$V libcufft-cross-sbsa-$V; \
|
||||
test -f /usr/local/cuda/targets/sbsa-linux/lib/libcufft_static.a; \
|
||||
apt-get clean; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY aarch64-sbsa.cmake /opt/cross/aarch64-sbsa.cmake
|
||||
|
||||
# Set workdir for your project
|
||||
WORKDIR /workspace
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Cross toolchain: x86_64 Ubuntu 24.04 build host -> aarch64 arm64 SBSA.
|
||||
# Covers DGX Spark (GB10, sm_121) and Grace Hopper (GH200, sm_90) alike -- same host architecture,
|
||||
# only the CUDA fatbin differs, and that is chosen with -DJFJOCH_CUDA_ARCHITECTURES.
|
||||
#
|
||||
# Relies on Debian multiarch rather than a separate sysroot: arm64 libraries live in
|
||||
# /usr/lib/aarch64-linux-gnu and headers are shared in /usr/include, so CMAKE_LIBRARY_ARCHITECTURE
|
||||
# is what steers find_library() rather than CMAKE_SYSROOT.
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64) # also selects FFTW's NEON codelets in CMakeLists.txt
|
||||
|
||||
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
|
||||
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)
|
||||
|
||||
# Programs must come from the build host (nvcc, ninja); libraries and headers from the target.
|
||||
set(CMAKE_FIND_ROOT_PATH /usr/lib/aarch64-linux-gnu /usr)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
# HDF5 runs two try_run() probes (config/ConfigureChecks.cmake); without an emulator the configure
|
||||
# aborts. libzmq guards its own run-checks with NOT CMAKE_CROSSCOMPILING and needs nothing here.
|
||||
set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-aarch64-static)
|
||||
|
||||
# --- CUDA -------------------------------------------------------------------------------------
|
||||
# nvcc is an x86_64 binary that emits aarch64 host code: -ccbin picks the cross host compiler and
|
||||
# -target-dir picks which targets/<dir> tree supplies CUDA's headers and libraries.
|
||||
set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)
|
||||
set(CMAKE_CUDA_HOST_COMPILER aarch64-linux-gnu-g++)
|
||||
# fatbinary_section.h ships ONLY in targets/x86_64-linux/include -- it is a host-side codegen header,
|
||||
# not a target one -- so -target-dir alone leaves the generated .stub.c unable to find it and EVERY
|
||||
# .cu fails with "fatbinary_section.h: No such file or directory". The header is architecture-neutral,
|
||||
# so adding the host include dir back is correct rather than a workaround.
|
||||
set(CMAKE_CUDA_FLAGS_INIT "-target-dir sbsa-linux -I/usr/local/cuda/include")
|
||||
# Without this, find_package(CUDAToolkit) resolves against the x86_64 tree and hands back x86
|
||||
# libraries. NVIDIA's cross-linux-sbsa packages ship libcufft_static.a and no libcufft.so, which is
|
||||
# why a cross build links cuFFT statically; a native build keeps the .so and an $ORIGIN rpath.
|
||||
set(CUDAToolkit_ROOT /usr/local/cuda/targets/sbsa-linux)
|
||||
@@ -34,9 +34,23 @@ IF (JFJOCH_CUDA_AVAILABLE)
|
||||
CUDAMemHelpers.h
|
||||
FFTIndexerGPU.cu FFTIndexerGPU.h
|
||||
FFBIDXIndexer.cpp FFBIDXIndexer.h)
|
||||
TARGET_LINK_LIBRARIES(JFJochIndexing fast_indexer_static
|
||||
CUDA::cufft
|
||||
)
|
||||
# The two shipped products (jfjoch_viewer, rugnux) link cuFFT STATICALLY on every platform.
|
||||
# It is the only CUDA component that was ever dynamic -- cudart and the fast-feedback indexer are
|
||||
# already static -- and shipping it as a .so meant each self-contained artifact had to carry the
|
||||
# library beside its executables and find it again through an $ORIGIN rpath, machinery that
|
||||
# silently failed for any executable that was not the one the rpath had been set on. Static, an
|
||||
# artifact is one file that runs; it is also what lets rugnux ship as a bare rugnux.exe on
|
||||
# Windows. A cross build has no alternative anyway: NVIDIA's cross-linux-sbsa packages carry
|
||||
# libcufft_static.a and no libcufft.so at all.
|
||||
#
|
||||
# The server stack keeps the shared library: its .deb/.rpm take CUDA from the distro, so there is
|
||||
# nothing to bundle, and every executable in that build (broker, tests, tools) would otherwise
|
||||
# need the device-link step below.
|
||||
IF (JFJOCH_PORTABLE_ONLY)
|
||||
TARGET_LINK_LIBRARIES(JFJochIndexing fast_indexer_static CUDA::cufft_static)
|
||||
ELSE()
|
||||
TARGET_LINK_LIBRARIES(JFJochIndexing fast_indexer_static CUDA::cufft)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(WARNING "CUDA is strongly recommended for image analysis." )
|
||||
|
||||
|
||||
+11
-1
@@ -22,7 +22,17 @@ TARGET_LINK_LIBRARIES(Rugnux JFJochReader JFJochImageAnalysis JFJochWriter gemmi
|
||||
# default), azint, scale (re-scale/merge stored reflections) or calibration (powder-ring geometry).
|
||||
ADD_EXECUTABLE(rugnux rugnux_cli.cpp)
|
||||
TARGET_LINK_LIBRARIES(rugnux Rugnux JFJochReader JFJochImageAnalysis JFJochWriter)
|
||||
INSTALL(TARGETS rugnux RUNTIME COMPONENT viewer)
|
||||
INSTALL(TARGETS rugnux RUNTIME COMPONENT rugnux)
|
||||
|
||||
# libcufft_static.a carries a relocatable-device-code object (separate_callback.o), so an executable
|
||||
# linking it needs a CUDA device-link step -- without it the host link fails on an undefined
|
||||
# __cudaRegisterLinkedBinary_* symbol. CUDA 13 no longer ships libcufft_static_nocallback.a, which
|
||||
# used to be the way around it. CUDA_RESOLVE_DEVICE_SYMBOLS makes CMake emit that step while leaving
|
||||
# the host link driver alone, so the -march/-flto flags CI passes still apply.
|
||||
IF (JFJOCH_PORTABLE_ONLY AND JFJOCH_CUDA_AVAILABLE)
|
||||
SET_TARGET_PROPERTIES(rugnux PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
|
||||
ENDIF()
|
||||
|
||||
|
||||
# On Windows this CLI gets getopt/getopt_long from the vendored wingetopt shim (libc has none).
|
||||
IF (WIN32)
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
# Offline analysis CLI tools. These link only the portable libraries (reader,
|
||||
# image_analysis, writer, common), so they build in viewer-only / Windows packages too
|
||||
# and install into the "viewer" component.
|
||||
# jfjoch_extract_hkl and jfjoch_recompress are developer utilities: still built, deliberately not
|
||||
# installed into any package. They used to ride inside the viewer tarball, which is part of what
|
||||
# made that artifact confusing.
|
||||
ADD_EXECUTABLE(jfjoch_extract_hkl jfjoch_extract_hkl.cpp
|
||||
XdsIntegrateParser.cpp
|
||||
XdsIntegrateParser.h)
|
||||
TARGET_LINK_LIBRARIES(jfjoch_extract_hkl JFJochReader)
|
||||
INSTALL(TARGETS jfjoch_extract_hkl RUNTIME COMPONENT viewer)
|
||||
|
||||
# rugnux, the single offline analysis CLI, lives in rugnux/ next to its library.
|
||||
|
||||
# In-place re-compress /entry/data/data of a _data file from bitshuffle/LZ4 to bitshuffle/zstd.
|
||||
ADD_EXECUTABLE(jfjoch_recompress jfjoch_recompress.cpp)
|
||||
TARGET_LINK_LIBRARIES(jfjoch_recompress JFJochHDF5Wrappers)
|
||||
INSTALL(TARGETS jfjoch_recompress RUNTIME COMPONENT viewer)
|
||||
|
||||
# On Windows these CLIs get getopt/getopt_long from the vendored wingetopt shim (libc has none).
|
||||
IF (WIN32)
|
||||
@@ -22,7 +23,7 @@ ENDIF()
|
||||
|
||||
# Online / hardware tools (broker, FPGA, receiver, detector). They link the non-portable
|
||||
# libraries and are Linux-only, so they are skipped in a viewer-only build.
|
||||
IF(NOT JFJOCH_VIEWER_ONLY)
|
||||
IF(NOT JFJOCH_PORTABLE_ONLY)
|
||||
ADD_EXECUTABLE(jfjoch_udp_simulator jfjoch_udp_simulator.cpp UDPSimulator.cpp UDPSimulator.h)
|
||||
TARGET_LINK_LIBRARIES(jfjoch_udp_simulator JFJochCommon)
|
||||
INSTALL(TARGETS jfjoch_udp_simulator RUNTIME COMPONENT jfjoch)
|
||||
|
||||
+12
-28
@@ -141,6 +141,16 @@ INSTALL(TARGETS jfjoch_viewer
|
||||
BUNDLE DESTINATION . COMPONENT viewer # macOS .app bundle
|
||||
RUNTIME DESTINATION bin COMPONENT viewer) # Windows .exe / Linux binary
|
||||
|
||||
# libcufft_static.a carries a relocatable-device-code object (separate_callback.o), so an executable
|
||||
# linking it needs a CUDA device-link step -- without it the host link fails on an undefined
|
||||
# __cudaRegisterLinkedBinary_* symbol. CUDA 13 no longer ships libcufft_static_nocallback.a, which
|
||||
# used to be the way around it. CUDA_RESOLVE_DEVICE_SYMBOLS makes CMake emit that step while leaving
|
||||
# the host link driver alone, so the -march/-flto flags CI passes still apply.
|
||||
IF (JFJOCH_PORTABLE_ONLY AND JFJOCH_CUDA_AVAILABLE)
|
||||
SET_TARGET_PROPERTIES(jfjoch_viewer PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(JFJOCH_VIEWER_DBUS)
|
||||
TARGET_SOURCES(jfjoch_viewer PRIVATE dbus/JFJochViewerAdaptor.cpp dbus/JFJochViewerAdaptor.h)
|
||||
TARGET_LINK_LIBRARIES(jfjoch_viewer Qt6::DBus)
|
||||
@@ -192,32 +202,6 @@ IF(Qt6_VERSION VERSION_GREATER_EQUAL "6.5")
|
||||
INSTALL(SCRIPT ${jfjoch_viewer_deploy_script} COMPONENT viewer)
|
||||
ENDIF()
|
||||
|
||||
# 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.<major> -> real
|
||||
# file) so the libcufft.so.<major> 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()
|
||||
# cuFFT is linked statically (see image_analysis/indexing/CMakeLists.txt), so there is no CUDA
|
||||
# runtime library to ship beside jfjoch_viewer on any platform.
|
||||
ENDIF()
|
||||
|
||||
@@ -37,8 +37,8 @@ TARGET_LINK_LIBRARIES(JFJochWriter JFJochPreview JFJochLogger JFJochHDF5Wrappers
|
||||
# portable viewer subset: JFJochStreamWriter pulls in JFJochImagePuller (not built in a viewer-only
|
||||
# tree) and jfjoch_writer uses a fork()/waitpid() multi-process design (<sys/wait.h>, no Windows
|
||||
# equivalent). The portable JFJochWriter library above is what the CLI tools and viewer need; these
|
||||
# two targets are not. (Windows/macOS force JFJOCH_VIEWER_ONLY, so this also excludes them there.)
|
||||
IF (NOT JFJOCH_VIEWER_ONLY)
|
||||
# two targets are not. (Windows/macOS force a portable build, so this also excludes them there.)
|
||||
IF (NOT JFJOCH_PORTABLE_ONLY)
|
||||
ADD_LIBRARY(JFJochStreamWriter StreamWriter.cpp StreamWriter.h)
|
||||
TARGET_LINK_LIBRARIES(JFJochStreamWriter JFJochWriter JFJochImagePuller)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user