rugnux was a component of the jfjoch-viewer package, so getting the offline analysis CLI meant installing the desktop viewer, Qt and the XDS plugin with it. It links none of the hardware libraries and talks to no service, so a machine that only processes data should be able to install it alone. It is packaged as "rugnux", not "jfjoch-rugnux": the binary, the release tarball and docs/NAMING.md all call it that, and it is what a user types. Overriding the component's package name is the only way to drop the CPACK_PACKAGE_NAME prefix. /usr/bin/rugnux moves between two packages that both continue to exist, so the declaration has to be a bound on the OLD viewer rather than an Obsoletes - obsoleting jfjoch-viewer would uninstall the viewer. rpm gets Conflicts, deb gets Breaks+Replaces so the two stay co-installable from here on. rpm rewrites "-" to "_" in a package version (an installed release reads 1.0.0_rc.160), so the bound is built with the same substitution; spelled 1.0.0-rc.164 the comparison would silently never match, which is the failure mode this kind of guard usually has. Verified by building rpms from a project mirroring these settings: the package comes out named rugnux at 1.0.0_rc.164 carrying /usr/bin/rugnux and its notices, the jfjoch package no longer carries rugnux, and "rpm -i --test" against the rc.160 viewer installed on this workstation reports the intended dependency conflict rather than a raw file collision - which is what lets dnf resolve it by upgrading the viewer in the same transaction. The deb side is checked against CPackDeb.cmake, which supports NAME, BREAKS and REPLACES per component, but no .deb was built: this host is RHEL. CI needs no change; the upload step globs *.rpm and *.deb.
726 lines
36 KiB
CMake
726 lines
36 KiB
CMake
CMAKE_MINIMUM_REQUIRED(VERSION 3.26)
|
|
|
|
# The VERSION file is the single source of truth for the version, and JFJOCH_VERSION carries it
|
|
# verbatim - including a pre-release suffix such as "-rc.161" - into the package names, the DKMS
|
|
# install path and the version every binary reports. PROJECT(VERSION) cannot hold that string: it
|
|
# only accepts numeric major.minor.patch, so the numeric part is cut out of the same file rather
|
|
# than written out a second time, and PROJECT_VERSION can never drift from VERSION.
|
|
FILE(STRINGS VERSION JFJOCH_VERSION)
|
|
STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" JFJOCH_VERSION_NUMERIC "${JFJOCH_VERSION}")
|
|
|
|
PROJECT(jfjoch VERSION ${JFJOCH_VERSION_NUMERIC} LANGUAGES C CXX)
|
|
SET(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
|
|
|
SET(CMAKE_CXX_STANDARD 20)
|
|
SET(CMAKE_CXX_STANDARD_REQUIRED True)
|
|
|
|
SET(JFJOCH_WRITER_ONLY OFF CACHE BOOL "Compile HDF5 writer only")
|
|
SET(JFJOCH_INSTALL_DRIVER_SOURCE OFF CACHE BOOL "Install kernel driver source (ignored if building writer only; necessary for RPM building)")
|
|
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. 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)
|
|
|
|
OPTION(SLS9 "Build with sls_detector_package v9.2.0" OFF)
|
|
|
|
SET(BUILD_SHARED_LIBS OFF)
|
|
SET(BUILD_TESTING OFF)
|
|
|
|
SET(ZSTD_LEGACY_SUPPORT OFF)
|
|
SET(ZSTD_MULTITHREAD_SUPPORT OFF)
|
|
SET(ZSTD_BUILD_PROGRAMS OFF)
|
|
SET(ZSTD_BUILD_SHARED OFF)
|
|
|
|
SET(SLS_USE_RECEIVER OFF)
|
|
SET(SLS_USE_RECEIVER_BINARIES OFF)
|
|
SET(SLS_BUILD_SHARED_LIBRARIES OFF)
|
|
|
|
SET(BUILD_FAST_INDEXER OFF)
|
|
SET(BUILD_FAST_INDEXER_STATIC ON)
|
|
|
|
INCLUDE(CheckLanguage)
|
|
INCLUDE(CheckIncludeFile)
|
|
|
|
# Locate nvcc ourselves when it isn't already pinned (-DCMAKE_CUDA_COMPILER / $CUDACXX). CHECK_LANGUAGE
|
|
# below only searches PATH, which is missed routinely on Windows and intermittently on Linux; the
|
|
# standard CUDA install locations (CUDA_PATH on Windows, /usr/local/cuda on Linux) cover both, so the
|
|
# compiler need not be passed by hand. Only set it when actually found, leaving CHECK_LANGUAGE to run
|
|
# its normal detection otherwise.
|
|
IF (JFJOCH_USE_CUDA AND NOT CMAKE_CUDA_COMPILER AND NOT DEFINED ENV{CUDACXX})
|
|
FIND_PROGRAM(_jfjoch_nvcc nvcc
|
|
HINTS ENV CUDA_PATH ENV CUDA_HOME ENV CUDA_ROOT /usr/local/cuda /opt/cuda
|
|
PATH_SUFFIXES bin)
|
|
IF (_jfjoch_nvcc)
|
|
SET(CMAKE_CUDA_COMPILER "${_jfjoch_nvcc}")
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
CHECK_LANGUAGE(CUDA)
|
|
|
|
# GPU architectures to generate device code for: Turing (T4), Ampere (A100; RTX A4000), Ada (L4),
|
|
# 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.
|
|
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")
|
|
SET(CMAKE_CUDA_RUNTIME_LIBRARY Static)
|
|
|
|
SET(JFJOCH_CUDA_AVAILABLE OFF)
|
|
|
|
IF (CMAKE_CUDA_COMPILER)
|
|
IF (JFJOCH_USE_CUDA)
|
|
ENABLE_LANGUAGE(CUDA)
|
|
MESSAGE(STATUS "CUDA VERSION: ${CMAKE_CUDA_COMPILER_VERSION}")
|
|
IF (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "12.8")
|
|
FIND_PACKAGE(CUDAToolkit REQUIRED)
|
|
ADD_COMPILE_DEFINITIONS(JFJOCH_USE_CUDA)
|
|
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" 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
|
|
# V100 has no runnable code in the fatbin at all and every launch fails with "no kernel
|
|
# image is available for execution on the device". CUDA 13 removed offline compilation
|
|
# 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" AND NOT JFJOCH_CUDA_ARCHITECTURES)
|
|
LIST(APPEND CMAKE_CUDA_ARCHITECTURES 70)
|
|
SET(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Wno-deprecated-gpu-targets")
|
|
ENDIF()
|
|
ELSE()
|
|
MESSAGE(WARNING "CUDA older than 12.8 not supported")
|
|
ENDIF()
|
|
ELSE()
|
|
MESSAGE(WARNING "CUDA Available, but disabled by user")
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
INCLUDE_DIRECTORIES(include)
|
|
|
|
include(FetchContent)
|
|
|
|
SET(HDF5_ENABLE_SZIP_SUPPORT OFF CACHE BOOL "" FORCE)
|
|
SET(HDF5_ENABLE_SZIP_ENCODING OFF CACHE BOOL "" FORCE)
|
|
SET(HDF5_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|
SET(HDF5_BUILD_CPP_LIB OFF CACHE BOOL "" FORCE)
|
|
SET(HDF5_ENABLE_ZLIB_SUPPORT ON CACHE BOOL "" FORCE)
|
|
SET(HDF5_EXTERNALLY_CONFIGURED 1 CACHE BOOL "" FORCE)
|
|
|
|
SET(SPDLOG_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|
SET(SPDLOG_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
|
SET(SPDLOG_BUILD_BENCH OFF CACHE BOOL "" FORCE)
|
|
set(SPDLOG_BUILD_SHARED OFF CACHE BOOL "" FORCE)
|
|
SET(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
|
|
|
SET(HTTPLIB_USE_NON_BLOCKING_GETADDRINFO OFF CACHE BOOL "" FORCE)
|
|
SET(HTTPLIB_REQUIRE_ZLIB ON CACHE BOOL "" FORCE)
|
|
|
|
FetchContent_Declare(
|
|
spdlog
|
|
GIT_REPOSITORY https://github.com/gabime/spdlog.git
|
|
GIT_TAG v1.17.0
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(
|
|
zstd
|
|
GIT_REPOSITORY https://github.com/facebook/zstd
|
|
GIT_TAG 794ea1b0afca0f020f4e57b6732332231fb23c70
|
|
SOURCE_SUBDIR build/cmake
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(hdf5
|
|
GIT_REPOSITORY https://github.com/HDFGroup/hdf5/
|
|
GIT_TAG hdf5_2.1.0
|
|
GIT_SHALLOW 1
|
|
EXCLUDE_FROM_ALL)
|
|
|
|
SET(SLS_DETECTOR_GIT_TAG "8.0.2")
|
|
IF(SLS9)
|
|
SET(SLS_DETECTOR_GIT_TAG "9.2.0")
|
|
ENDIF()
|
|
|
|
FetchContent_Declare(
|
|
sls_detector_package
|
|
GIT_REPOSITORY https://github.com/slsdetectorgroup/slsDetectorPackage
|
|
GIT_TAG ${SLS_DETECTOR_GIT_TAG}
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(
|
|
catch2
|
|
GIT_REPOSITORY https://github.com/catchorg/Catch2
|
|
GIT_TAG v3.13.0
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(
|
|
httplib
|
|
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
|
|
GIT_TAG v0.39.0
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
# httplib enables Brotli content-encoding whenever it finds system Brotli; we don't use it
|
|
# (gzip/zlib is enough for the broker), so disable it to avoid linking libbrotli.
|
|
SET(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF CACHE BOOL "" FORCE)
|
|
|
|
# httplib auto-enables HTTPS by linking system OpenSSL whenever it finds it. The broker serves
|
|
# plain HTTP only (TLS, if ever wanted, is terminated by a front reverse proxy), so disable it --
|
|
# otherwise jfjoch_broker would pull in libssl/libcrypto for no reason.
|
|
SET(HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF CACHE BOOL "" FORCE)
|
|
|
|
# ZeroMQ (libzmq): fetch it here, at the top level, so that THIS project - not
|
|
# slsDetectorPackage - controls the version. slsDetectorPackage bundles its own libzmq
|
|
# archive, but only populates it behind `if(NOT libzmq_POPULATED)`; by making libzmq
|
|
# available before sls below, sls reuses this copy and a single libzmq-static target is
|
|
# built (no duplicate target / double-symbol clash). A future viewer-only / Windows build
|
|
# (which does not build sls) fetches the same libzmq standalone.
|
|
SET(BUILD_SHARED OFF CACHE BOOL "" FORCE) # libzmq: static only (matches sls)
|
|
SET(BUILD_TESTS OFF CACHE BOOL "" FORCE) # libzmq: no test build
|
|
SET(WITH_PERF_TOOL OFF CACHE BOOL "" FORCE) # libzmq: no perf tools
|
|
SET(WITH_DOCS OFF CACHE BOOL "" FORCE) # libzmq: no docs
|
|
SET(ENABLE_CPACK OFF CACHE BOOL "" FORCE) # libzmq: no CPack injection
|
|
FetchContent_Declare(
|
|
libzmq
|
|
GIT_REPOSITORY https://github.com/zeromq/libzmq.git
|
|
GIT_TAG v4.3.5
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
# CMake >= 4.0 (e.g. the 4.x bundled with Visual Studio 2026) makes any
|
|
# cmake_minimum_required(VERSION < 3.5) a fatal error. Some fetched dependencies still
|
|
# declare such old floors (libzmq: 3.0.2), so raise the policy-version floor for the
|
|
# FetchContent subprojects. Ignored (harmless) on CMake < 3.30, which lacks this variable.
|
|
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_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)
|
|
ELSE()
|
|
FetchContent_MakeAvailable(zstd sls_detector_package catch2 hdf5 spdlog httplib)
|
|
ENDIF()
|
|
|
|
# libtiff (used by JFJochPreview in every build mode): build it ourselves. Its C++ binding
|
|
# (tiffxx) is packaged inconsistently across distros (missing on Rocky 9) and absent on
|
|
# Windows. Library only; the SET()s below are libtiff's own codec/tool switches.
|
|
# We only need DEFLATE (zlib) + the internal LZW codec, matching what Python tifffile writes
|
|
# by default. The remaining codecs default to ON whenever their library is found on the build
|
|
# host, so each must be explicitly turned OFF to keep the dependency set minimal -- otherwise
|
|
# webp pulls in libwebp + libsharpyuv and lerc pulls in libLerc.
|
|
SET(jbig OFF)
|
|
SET(zstd OFF)
|
|
SET(lzma OFF)
|
|
SET(jpeg OFF)
|
|
SET(old-jpeg OFF)
|
|
SET(webp OFF)
|
|
SET(lerc OFF)
|
|
SET(tiff-tools OFF)
|
|
SET(tiff-tests OFF)
|
|
FetchContent_Declare(tiff
|
|
GIT_REPOSITORY https://gitlab.com/libtiff/libtiff.git
|
|
GIT_TAG v4.7.1
|
|
EXCLUDE_FROM_ALL)
|
|
FetchContent_MakeAvailable(tiff)
|
|
|
|
# FFTW single precision (target fftw3f): the CPU fallback indexer, enables JFJOCH_USE_FFTW.
|
|
# Built from the release tarball -- the git repo ships no pre-generated codelets (needs the
|
|
# OCaml genfft).
|
|
SET(ENABLE_FLOAT ON CACHE BOOL "" FORCE)
|
|
SET(BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
|
# SIMD codelets are runtime-dispatched (cpuid), so enabling AVX2 does NOT require an AVX2 CPU
|
|
# -- FFTW falls back at runtime. The codelet sets are arch-specific, so guard by processor:
|
|
# x86 gets SSE2/AVX/AVX2, aarch64 (e.g. Grace on DGX Spark) gets NEON; other arches build scalar.
|
|
IF (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64")
|
|
SET(ENABLE_SSE2 ON CACHE BOOL "" FORCE)
|
|
SET(ENABLE_AVX ON CACHE BOOL "" FORCE)
|
|
SET(ENABLE_AVX2 ON CACHE BOOL "" FORCE)
|
|
ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
|
|
SET(ENABLE_NEON ON CACHE BOOL "" FORCE)
|
|
ENDIF()
|
|
FetchContent_Declare(fftw
|
|
URL https://www.fftw.org/fftw-3.3.10.tar.gz
|
|
URL_HASH SHA256=56c932549852cddcfafdab3820b0200c7742675be92179e59e6215b340e26467
|
|
EXCLUDE_FROM_ALL)
|
|
FetchContent_MakeAvailable(fftw)
|
|
# FFTW exposes fftw3.h only via $<INSTALL_INTERFACE:include>, so consuming fftw3f straight from
|
|
# the build tree (FetchContent) leaves the header unreachable. On Linux a system-installed
|
|
# fftw3.h masks this; on Windows it does not. Add the source-tree api/ dir for build-tree use.
|
|
TARGET_INCLUDE_DIRECTORIES(fftw3f INTERFACE $<BUILD_INTERFACE:${fftw_SOURCE_DIR}/api>)
|
|
ADD_COMPILE_DEFINITIONS(JFJOCH_USE_FFTW)
|
|
|
|
# Eigen is an EXTERNAL dependency (like ZLIB), resolved by find_package(Eigen3) in the subdirectories
|
|
# that need it (image_analysis, and transitively Ceres and ffbidx). It is deliberately NOT vendored
|
|
# via FetchContent: declaring Eigen with OVERRIDE_FIND_PACKAGE makes the CMake bundled with Visual
|
|
# Studio (cmake 4.x "-msvc") intermittently SEGFAULT during configure. The fault is in CMake's own
|
|
# FetchContent variable-stack cleanup, reached when Ceres' find_package(Eigen3) resolves the override
|
|
# through a nested FetchContent_MakeAvailable -- ~1 in 3 fresh configures, and 100% with Ceres CUDA on.
|
|
# Stock Kitware CMake runs the identical scripts fine, so it is a bug in the VS-bundled cmake binary;
|
|
# providing Eigen externally avoids that code path entirely and is stable (verified, both Ceres CUDA
|
|
# on and off). Provide it via the system package on Linux (eigen3-devel / libeigen3-dev) or a build
|
|
# prefix on Windows (point CMAKE_PREFIX_PATH / Eigen3_DIR at it), exactly as for ZLIB.
|
|
|
|
# getopt/getopt_long shim for Windows: the MSVC CRT has no <getopt.h>. Vendored OpenBSD/NetBSD
|
|
# implementation (BSD-licensed). Built only on Windows and defined here, before the subdirectories,
|
|
# so the portable CLI tools in tools/ can link it. A no-op on Linux/macOS, where getopt lives in
|
|
# libc (macOS uses the system getopt even though it is also a forced viewer-only platform).
|
|
IF (WIN32)
|
|
ADD_LIBRARY(wingetopt STATIC tools/wingetopt/getopt.c tools/wingetopt/getopt.h)
|
|
TARGET_INCLUDE_DIRECTORIES(wingetopt PUBLIC tools/wingetopt)
|
|
ENDIF()
|
|
|
|
# libcurl: the jfjoch_viewer HTTP client (viewer/JFJochHttpReader). Fetched and STATICALLY linked
|
|
# ONLY for viewer builds, so the broker/writer never pull in a TLS/Kerberos stack. Backends are
|
|
# OS-native per platform to keep the Windows build self-contained: Schannel (TLS) + SSPI
|
|
# (Negotiate/Kerberos) on Windows -- no external OpenSSL/krb5 -- and system OpenSSL + GSSAPI (krb5)
|
|
# on Linux. Trimmed to HTTP(S) only, mirroring the libtiff codec pruning above.
|
|
IF (JFJOCH_VIEWER_BUILD OR JFJOCH_VIEWER_ONLY)
|
|
SET(BUILD_CURL_EXE OFF CACHE BOOL "" FORCE)
|
|
SET(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) # static libcurl only, never a shared lib
|
|
SET(BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE)
|
|
SET(BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
|
SET(CURL_DISABLE_INSTALL ON CACHE BOOL "" FORCE)
|
|
SET(HTTP_ONLY ON CACHE BOOL "" FORCE) # HTTP/HTTPS only; drop FTP/LDAP/SMTP/...
|
|
SET(CURL_USE_LIBPSL OFF CACHE BOOL "" FORCE) # avoid the libpsl dependency
|
|
SET(CURL_USE_LIBSSH2 OFF CACHE BOOL "" FORCE)
|
|
SET(CURL_ZLIB ON CACHE BOOL "" FORCE) # reuse the project's ZLIB
|
|
IF (WIN32)
|
|
SET(CURL_USE_SCHANNEL ON CACHE BOOL "" FORCE) # native Windows TLS (no OpenSSL)
|
|
SET(CURL_USE_SSPI ON CACHE BOOL "" FORCE) # native Negotiate/Kerberos (no krb5)
|
|
ELSE()
|
|
SET(CURL_USE_OPENSSL ON CACHE BOOL "" FORCE)
|
|
SET(CURL_USE_GSSAPI ON CACHE BOOL "" FORCE) # Kerberos via system krb5 (needs krb5-dev)
|
|
ENDIF()
|
|
FetchContent_Declare(curl
|
|
GIT_REPOSITORY https://github.com/curl/curl.git
|
|
GIT_TAG curl-8_11_1
|
|
EXCLUDE_FROM_ALL)
|
|
FetchContent_MakeAvailable(curl)
|
|
# The viewer links libcurl_static (curl's concrete static-lib target) directly rather than the
|
|
# CURL::libcurl alias: the alias can be shadowed by a system libcurl (find_package / dependency
|
|
# provider / a distro CURL config), silently linking the OS curl with the wrong TLS/Kerberos
|
|
# backend. libcurl_static is unambiguous; guard that FetchContent actually produced it.
|
|
IF (NOT TARGET libcurl_static)
|
|
MESSAGE(FATAL_ERROR "libcurl_static missing after FetchContent_MakeAvailable(curl) -- "
|
|
"the vendored static libcurl was not built.")
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
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)
|
|
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)
|
|
ADD_SUBDIRECTORY(viewer)
|
|
ADD_SUBDIRECTORY(tools) # builds only the portable analysis tools (rugnux/extract_hkl)
|
|
ELSE()
|
|
ADD_SUBDIRECTORY(jungfrau)
|
|
ADD_SUBDIRECTORY(compression)
|
|
ADD_SUBDIRECTORY(common)
|
|
ADD_SUBDIRECTORY(writer)
|
|
ADD_SUBDIRECTORY(frame_serialize)
|
|
ADD_SUBDIRECTORY(reader)
|
|
ADD_SUBDIRECTORY(detector_control)
|
|
ADD_SUBDIRECTORY(image_puller)
|
|
ADD_SUBDIRECTORY(preview)
|
|
ADD_SUBDIRECTORY(gemmi_gph)
|
|
ADD_SUBDIRECTORY(xds-plugin)
|
|
|
|
IF (JFJOCH_WRITER_ONLY)
|
|
MESSAGE(STATUS "Compiling HDF5 writer only")
|
|
ELSE()
|
|
ADD_SUBDIRECTORY(image_pusher)
|
|
ADD_SUBDIRECTORY(broker)
|
|
ADD_SUBDIRECTORY(fpga)
|
|
ADD_SUBDIRECTORY(acquisition_device)
|
|
ADD_SUBDIRECTORY(receiver)
|
|
ADD_SUBDIRECTORY(image_analysis)
|
|
ADD_SUBDIRECTORY(rugnux)
|
|
ADD_SUBDIRECTORY(tests)
|
|
ADD_SUBDIRECTORY(tools)
|
|
ENDIF()
|
|
|
|
IF (JFJOCH_VIEWER_BUILD)
|
|
ADD_SUBDIRECTORY(viewer)
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
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
|
|
COMMAND npm run licenses # write dist/THIRD_PARTY_LICENSES.txt (npm deps attribution)
|
|
COMMAND npm run redocly
|
|
COMMAND npm run docs # bundle Sphinx docs into dist/docs (served at /frontend/docs)
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/frontend)
|
|
ADD_CUSTOM_TARGET(frontend DEPENDS frontend/dist/index.html)
|
|
|
|
ADD_CUSTOM_TARGET(update_version
|
|
COMMAND bash update_version.sh
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
|
|
IF (JFJOCH_INSTALL_DRIVER_SOURCE)
|
|
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/
|
|
DESTINATION /usr/src/jfjoch-${JFJOCH_VERSION}
|
|
COMPONENT driver-dkms
|
|
FILES_MATCHING PATTERN "dkms.conf")
|
|
|
|
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/
|
|
DESTINATION /usr/src/jfjoch-${JFJOCH_VERSION}/src
|
|
COMPONENT driver-dkms
|
|
FILES_MATCHING PATTERN "*.c" PATTERN "*.h" PATTERN "Makefile")
|
|
ENDIF()
|
|
FILE(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/frontend/dist/)
|
|
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/frontend/dist/ DESTINATION share/jfjoch/frontend COMPONENT jfjoch )
|
|
ENDIF()
|
|
|
|
# Windows has no static cuFFT (the toolkit ships no cufft_static.lib), so there the indexer links
|
|
# the import library and the self-contained products must carry the DLL beside the executable --
|
|
# the same idea the Linux builds no longer need, since they link libcufft_static.a. CUDA 13 keeps
|
|
# the redistributable DLLs in bin/x64, earlier toolkits in bin; glob both.
|
|
IF (WIN32 AND JFJOCH_CUDA_AVAILABLE AND JFJOCH_PORTABLE_ONLY AND NOT TARGET CUDA::cufft_static)
|
|
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()
|
|
IF (JFJOCH_RUGNUX_ONLY)
|
|
INSTALL(FILES ${_cufft_dll} DESTINATION bin COMPONENT rugnux)
|
|
ELSE()
|
|
INSTALL(FILES ${_cufft_dll} DESTINATION bin COMPONENT viewer)
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
|
SET(CMAKE_INSTALL_PREFIX /opt/jfjoch CACHE PATH "Default directory" FORCE)
|
|
ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
|
|
|
# Set Package Name
|
|
SET(CPACK_PACKAGE_NAME "jfjoch")
|
|
|
|
# Select the components to package based on build mode
|
|
if (JFJOCH_RUGNUX_ONLY)
|
|
set(CPACK_COMPONENTS_ALL rugnux)
|
|
elseif (JFJOCH_VIEWER_ONLY)
|
|
set(CPACK_COMPONENTS_ALL viewer)
|
|
else()
|
|
# rugnux is packaged separately from everything else, as "rugnux" rather than "jfjoch-rugnux"
|
|
# (see the DEB/RPM branches below). It is the offline analysis CLI: it links none of the
|
|
# hardware libraries and talks to no service, so a machine that only processes data can install
|
|
# it alone. Up to 1.0.0-rc.163 it rode inside the jfjoch-viewer package, which is why both
|
|
# branches below declare the file move.
|
|
set(CPACK_COMPONENTS_ALL jfjoch writer rugnux)
|
|
if (JFJOCH_INSTALL_DRIVER_SOURCE)
|
|
list(APPEND CPACK_COMPONENTS_ALL driver-dkms)
|
|
endif()
|
|
if (JFJOCH_VIEWER_BUILD)
|
|
list(APPEND CPACK_COMPONENTS_ALL viewer)
|
|
endif()
|
|
endif()
|
|
|
|
# Common metadata
|
|
set(CPACK_PACKAGE_CONTACT "Filip Leonarski <filip.leonarski@psi.ch>")
|
|
set(CPACK_PACKAGE_VENDOR "Paul Scherrer Institut")
|
|
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 AND NOT JFJOCH_RUGNUX_ONLY)
|
|
# .dmg containing jfjoch_viewer.app (Qt runtime already deployed into the bundle).
|
|
set(CPACK_GENERATOR "DragNDrop")
|
|
elseif (WIN32 AND NOT JFJOCH_RUGNUX_ONLY)
|
|
# NSIS installer .exe (Qt runtime deployed next to the binary by windeployqt).
|
|
set(CPACK_GENERATOR "NSIS")
|
|
|
|
# GPLv3 text shown as the click-through license page of the installer.
|
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
|
|
|
# Branding is split across three CPack knobs so the CUDA/CPU variant surfaces exactly where we
|
|
# want it and nowhere else:
|
|
# - Install folder + Start Menu group come from CPACK_PACKAGE_INSTALL_DIRECTORY and
|
|
# CPACK_NSIS_PACKAGE_NAME (the latter feeds $(^Name), the Start Menu group's default folder).
|
|
# Both stay plain "Jungfraujoch", so the Start Menu group carries no variant tag and the two
|
|
# builds install to the same place (CUDA is a strict superset -- they replace, not coexist).
|
|
# - CPACK_NSIS_DISPLAY_NAME is the Add/Remove Programs entry -- tagged "(CUDA)"/"(CPU)".
|
|
# - CPACK_PACKAGE_FILE_NAME is the installer .exe filename -- tagged "-cuda<major>"/"-cpu", so
|
|
# the (much larger) CUDA download is self-identifying, with the CUDA major version baked in.
|
|
# The tag follows JFJOCH_CUDA_AVAILABLE automatically; CUDAToolkit_VERSION_MAJOR is set whenever
|
|
# it is ON (find_package(CUDAToolkit) ran in the same guard above).
|
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Jungfraujoch")
|
|
set(CPACK_NSIS_PACKAGE_NAME "Jungfraujoch")
|
|
if (JFJOCH_CUDA_AVAILABLE)
|
|
set(CPACK_NSIS_DISPLAY_NAME "Jungfraujoch (CUDA)")
|
|
set(CPACK_PACKAGE_FILE_NAME "jfjoch-viewer-${JFJOCH_VERSION}-win64-cuda${CUDAToolkit_VERSION_MAJOR}")
|
|
else()
|
|
set(CPACK_NSIS_DISPLAY_NAME "Jungfraujoch (CPU)")
|
|
set(CPACK_PACKAGE_FILE_NAME "jfjoch-viewer-${JFJOCH_VERSION}-win64-cpu")
|
|
endif()
|
|
|
|
# Start Menu shortcut for the viewer ("<exe basename>;<label>"). The shortcut and the
|
|
# Add/Remove Programs entry both use the .exe's embedded icon.
|
|
set(CPACK_PACKAGE_EXECUTABLES "jfjoch_viewer;Jungfraujoch Viewer")
|
|
# Forward slash on purpose: CPack writes this value verbatim into CPackConfig.cmake, and a
|
|
# 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 (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
|
|
# Linux -- unlike the per-distro .rpm/.deb this is meant to replace in the release. Named to
|
|
# mirror the Windows/macOS artifacts, with the same -cuda<major>/-cpu tag so the (larger) GPU
|
|
# build is self-identifying. CI renames the .tar.gz to .tgz before upload.
|
|
set(CPACK_GENERATOR "TGZ")
|
|
# Package only the components in CPACK_COMPONENTS_ALL (here: viewer). Without this the archive
|
|
# generator falls back to a monolithic install and walks every install() rule in the tree --
|
|
# including the fetched HDF5 command-line tools, abseil's EXCLUDE_FROM_ALL sub-libraries and the
|
|
# non-viewer components -- none of which the viewer-only build produces, so cpack aborts with
|
|
# "cannot find <artifact>". ALL_COMPONENTS_IN_ONE keeps the output a single tarball named
|
|
# CPACK_PACKAGE_FILE_NAME (no per-component suffix), matching the CI upload glob. This mirrors
|
|
# 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)
|
|
# The rugnux archive always carries its architecture, because it is built for more than one:
|
|
# x86_64 natively and aarch64 through the cross toolchain. CMAKE_SYSTEM_PROCESSOR is the TARGET
|
|
# architecture (the toolchain file declares it), never the build host's, so a cross-built tarball
|
|
# cannot be mistaken for a native one. The viewer is x86_64-only and keeps its existing name.
|
|
if (JFJOCH_RUGNUX_ONLY)
|
|
set(_jfjoch_tgz_name "rugnux")
|
|
set(_jfjoch_tgz_arch "-${CMAKE_SYSTEM_PROCESSOR}")
|
|
else()
|
|
set(_jfjoch_tgz_name "jfjoch_viewer")
|
|
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")
|
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
|
|
|
# Debian/Ubuntu: .deb with components
|
|
set(CPACK_GENERATOR "DEB")
|
|
set(CPACK_DEB_COMPONENT_INSTALL ON)
|
|
# Every component package is named "<CPACK_PACKAGE_NAME>-<component>" unless the component
|
|
# overrides it, so the broker component came out as "jfjoch-jfjoch". Name it plain "jfjoch", to
|
|
# match what the RPM generator produces for CPACK_RPM_MAIN_COMPONENT below. (There is no
|
|
# CPACK_DEBIAN_MAIN_COMPONENT: only CPackRPM.cmake has that variable, and the DEB spelling this
|
|
# used to set was silently ignored.)
|
|
set(CPACK_DEBIAN_JFJOCH_PACKAGE_NAME "jfjoch")
|
|
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
|
|
|
|
# Up to 1.0.0-rc.160 that package was "jfjoch-jfjoch". It owns the same files as "jfjoch" does
|
|
# now, so dpkg would refuse to unpack over it; declare the rename so an existing installation
|
|
# upgrades instead of conflicting.
|
|
set(CPACK_DEBIAN_JFJOCH_PACKAGE_REPLACES "jfjoch-jfjoch")
|
|
set(CPACK_DEBIAN_JFJOCH_PACKAGE_CONFLICTS "jfjoch-jfjoch")
|
|
|
|
# rugnux ships as plain "rugnux", not "jfjoch-rugnux": it is a separately named product (see
|
|
# docs/NAMING.md), the released tarball is called rugnux-<version>-..., and it is what a user
|
|
# types. Overriding the name is the only way to drop the CPACK_PACKAGE_NAME prefix.
|
|
set(CPACK_DEBIAN_RUGNUX_PACKAGE_NAME "rugnux")
|
|
|
|
# /usr/bin/rugnux moved out of jfjoch-viewer into this package. Breaks+Replaces, NOT Conflicts:
|
|
# the two packages are meant to be co-installable from 1.0.0-rc.164 on, and this only has to
|
|
# stop an OLD viewer (which still owns the file) from being unpacked alongside. Without it dpkg
|
|
# refuses with "trying to overwrite '/usr/bin/rugnux', which is also in package jfjoch-viewer".
|
|
set(CPACK_DEBIAN_RUGNUX_PACKAGE_BREAKS "jfjoch-viewer (<< ${JFJOCH_VERSION})")
|
|
set(CPACK_DEBIAN_RUGNUX_PACKAGE_REPLACES "jfjoch-viewer (<< ${JFJOCH_VERSION})")
|
|
|
|
# Enable automatic shlib dependency discovery
|
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
|
|
|
# Optional DEB metadata (tune as needed)
|
|
set(CPACK_DEBIAN_PACKAGE_SECTION "science")
|
|
# set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://example.org/jfjoch")
|
|
|
|
# DKMS component (maps from RPM settings)
|
|
if (JFJOCH_INSTALL_DRIVER_SOURCE)
|
|
# Dependencies and arch for the DKMS component
|
|
# Note: component name "driver-dkms" maps to variable suffix "DRIVER_DKMS"
|
|
set(CPACK_DEBIAN_DRIVER_DKMS_PACKAGE_DEPENDS "dkms, gcc, bash, sed")
|
|
set(CPACK_DEBIAN_DRIVER_DKMS_PACKAGE_ARCHITECTURE "all")
|
|
|
|
# Provide Debian control scripts (postinst/prerm).
|
|
# We rename existing scripts to Debian control names at configure time.
|
|
set(_dkms_ctrl_dir "${CMAKE_CURRENT_BINARY_DIR}/cpack-debian-driver-dkms")
|
|
file(MAKE_DIRECTORY "${_dkms_ctrl_dir}")
|
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/postinstall.sh
|
|
${_dkms_ctrl_dir}/postinst COPYONLY)
|
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/preuninstall.sh
|
|
${_dkms_ctrl_dir}/prerm COPYONLY)
|
|
set(CPACK_DEBIAN_DRIVER_DKMS_PACKAGE_CONTROL_EXTRA
|
|
"${_dkms_ctrl_dir}/postinst;${_dkms_ctrl_dir}/prerm")
|
|
endif()
|
|
|
|
elseif (EXISTS "/etc/redhat-release")
|
|
# RHEL/Rocky: .rpm with components (original behavior)
|
|
set(CPACK_GENERATOR "RPM")
|
|
set(CPACK_RPM_COMPONENT_INSTALL ON)
|
|
set(CPACK_RPM_MAIN_COMPONENT jfjoch)
|
|
set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
|
|
set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
|
|
set(CPACK_RPM_PACKAGE_VERSION ${JFJOCH_VERSION})
|
|
set(CPACK_RPM_PACKAGE_RELEASE 1)
|
|
set(CPACK_RPM_PACKAGE_SUMMARY "Jungfraujoch data acquisition system")
|
|
set(CPACK_RPM_PACKAGE_DESCRIPTION "Jungfraujoch")
|
|
set(CPACK_RPM_PACKAGE_LICENSE "GPLv3")
|
|
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
|
/usr/src /usr/share /usr/share/dbus-1 /usr/share/dbus-1/services /usr/share/pixmaps /usr/share/applications)
|
|
|
|
# rugnux ships as plain "rugnux", not "jfjoch-rugnux" -- see the DEB branch above for why.
|
|
set(CPACK_RPM_RUGNUX_PACKAGE_NAME "rugnux")
|
|
set(CPACK_RPM_RUGNUX_PACKAGE_SUMMARY "Offline crystallographic data analysis for Jungfraujoch")
|
|
set(CPACK_RPM_RUGNUX_PACKAGE_DESCRIPTION
|
|
"rugnux processes a stored Jungfraujoch HDF5 dataset: spot finding, indexing, geometry
|
|
refinement, Bragg integration, scaling and merging. It needs none of the acquisition stack -- no
|
|
broker, no detector, no FPGA card -- so it can be installed on a machine that only processes data.")
|
|
|
|
# /usr/bin/rugnux moved out of the jfjoch-viewer package into this one. Conflicts against the
|
|
# OLD viewer only, and deliberately NOT Obsoletes: obsoleting jfjoch-viewer would uninstall the
|
|
# viewer, which still exists and is still wanted. rpm turns "-" into "_" in a package version
|
|
# (an installed release reads 1.0.0_rc.160), so the bound has to be spelled the same way or the
|
|
# comparison silently never matches.
|
|
string(REPLACE "-" "_" _jfjoch_rpm_version "${JFJOCH_VERSION}")
|
|
set(CPACK_RPM_RUGNUX_PACKAGE_CONFLICTS "jfjoch-viewer < ${_jfjoch_rpm_version}")
|
|
|
|
# DKMS component scripts and requirements for RPM
|
|
if (JFJOCH_INSTALL_DRIVER_SOURCE)
|
|
set(CPACK_RPM_DRIVER-DKMS_PACKAGE_REQUIRES "dkms, gcc, bash, sed")
|
|
set(CPACK_RPM_DRIVER-DKMS_PACKAGE_ARCHITECTURE "noarch")
|
|
set(CPACK_RPM_DRIVER-DKMS_POST_INSTALL_SCRIPT_FILE
|
|
${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/postinstall.sh)
|
|
set(CPACK_RPM_DRIVER-DKMS_PRE_UNINSTALL_SCRIPT_FILE
|
|
${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/preuninstall.sh)
|
|
endif()
|
|
else()
|
|
# Fallback if OS is unknown
|
|
set(CPACK_GENERATOR "TGZ")
|
|
endif()
|
|
|
|
|
|
# Ship the license notices (top-level LICENSE, the third-party manifest, and the verbatim
|
|
# license texts) with every package variant. Installed per component so the files land in
|
|
# whichever component package(s) the current build mode produces.
|
|
#
|
|
# Each component gets a directory of its own, named after the package's principal binary:
|
|
# share/doc/jfjoch_broker, jfjoch_writer, jfjoch_viewer, jfjoch_driver_dkms. No two components
|
|
# may write the same path, and no component writes the plain share/doc/jfjoch these all used to
|
|
# share. Deployment updates the packages one at a time (jfjoch first, then jfjoch-writer), so a
|
|
# path claimed by two packages blocks the first step as soon as a release changes its content -
|
|
# and leaving the main package on the old shared path would keep blocking it for anyone
|
|
# upgrading from a release that still had the collision. These notices were the only files any
|
|
# two components had in common.
|
|
SET(JFJOCH_NOTICE_FILES
|
|
${CMAKE_SOURCE_DIR}/LICENSE
|
|
${CMAKE_SOURCE_DIR}/THIRD_PARTY_NOTICES.md)
|
|
FOREACH(_component IN LISTS CPACK_COMPONENTS_ALL)
|
|
IF (_component STREQUAL "jfjoch")
|
|
SET(_suffix broker)
|
|
ELSE()
|
|
STRING(REPLACE "-" "_" _suffix ${_component})
|
|
ENDIF()
|
|
INSTALL(FILES ${JFJOCH_NOTICE_FILES}
|
|
DESTINATION share/doc/jfjoch_${_suffix} COMPONENT ${_component})
|
|
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/licenses/
|
|
DESTINATION share/doc/jfjoch_${_suffix}/licenses COMPONENT ${_component}
|
|
PATTERN "COLLECT.sh" EXCLUDE)
|
|
ENDFOREACH()
|
|
|
|
INCLUDE(CPack)
|