Build Packages / Create release (push) Successful in 16s
Build Packages / build:portable:macos-arm64:nocuda (push) Successful in 3m20s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 7m11s
Build Packages / build:portable:linux-x86_64:nocuda (push) Successful in 9m57s
Build Packages / build:portable:linux-x86_64:cuda (push) Successful in 12m39s
Build Packages / build:portable:windows-x86_64:nocuda (push) Successful in 19m41s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 20m21s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 20m36s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 21m50s
Build Packages / build:portable:windows-x86_64:cuda (push) Successful in 23m30s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 19m30s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 28m22s
Build Packages / Generate python client (push) Successful in 44s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 18m58s
Build Packages / Build documentation (push) Successful in 1m25s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 19m3s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 18m9s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 17m14s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 18m37s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 14m23s
Build Packages / Unit tests (push) Failing after 1h17m53s
Plugin: - Module-edge (bit 30) and chip-edge (bit 31) pixels are marked -2 (untrusted). Chip-edge pixels are split from a larger pixel with integer division and read low at low counts; feeding them to XDS as real pixels was what made the three plugins disagree in CI. - A saturated pixel in a signed image (INTx_MAX) is passed through with its value, so XDS counts it as an overload; only the error marker (INTx_MIN / UINTx_MAX) becomes -1. - Release version 1.1.0 set in CMake (library name and start message). VERSION_* in plugin.h stay 0: XDS refuses a plugin whose info-array major version is not 0. - Built and packaged on Linux only; the untested macOS archive is dropped. - The XDS linking permission is removed from LICENSE; the plugin is GPL-3.0. CI: - XDS.INP beam centre corrected to 1091/1137 (ORGY was 7.7 px off, which put IDXREF on a knife edge where one plugin's run fell into a false minimum). - Each XDS case must reach CORRECT, IDXREF spot SD must be < 2 px, and all file layouts read by the same plugin must give identical SPOT.XDS. Docs: recommend Durin (PSI or Global Phasing build); mask-bit table rewritten from measurement. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
955 lines
51 KiB
CMake
955 lines
51 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}")
|
|
|
|
# Oldest macOS the binaries run on (ignored elsewhere). Without it CMake takes the version of the
|
|
# build machine, and a .dmg would refuse to start on anything older. 13 is what the Qt the .dmg
|
|
# bundles (6.11) is built for, so a lower value only makes the linker warn about every framework;
|
|
# our own needs (<latch>, <filesystem>) stop at 11. Has to be set before PROJECT().
|
|
SET(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "Minimum macOS version")
|
|
|
|
PROJECT(jfjoch VERSION ${JFJOCH_VERSION_NUMERIC} LANGUAGES C CXX)
|
|
SET(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
|
INCLUDE(GNUInstallDirs)
|
|
|
|
SET(CMAKE_CXX_STANDARD 20)
|
|
SET(CMAKE_CXX_STANDARD_REQUIRED True)
|
|
|
|
# MSVC gets C++ exception handling only from /EHsc, and CMake puts that flag in the DEFAULT value of
|
|
# CMAKE_CXX_FLAGS ("/DWIN32 /D_WINDOWS /GR /EHsc"), which is used only when the configure does not
|
|
# set CMAKE_CXX_FLAGS itself. CI does (-DCMAKE_CXX_FLAGS="/arch:AVX"), and that drops /EHsc: MSVC then
|
|
# does not unwind the stack on a throw (no destructors run) and does not define _CPPUNWIND, so
|
|
# Catch2 compiles itself with CATCH_CONFIG_DISABLE_EXCEPTIONS. Adding it here, before any
|
|
# FetchContent, reaches every C++ target whatever CMAKE_CXX_FLAGS holds. CUDA gets it from its own
|
|
# default CMAKE_CUDA_FLAGS, which nothing overrides.
|
|
#
|
|
# CUDA's CCCL headers (cub, thrust, libcu++) stop with an #error under MSVC's traditional
|
|
# preprocessor, which miscompiles their macros. nvcc preprocesses and compiles host code with cl.exe,
|
|
# so the standard-conforming preprocessor is switched on for .cu sources here, reaching every CUDA
|
|
# target, fetched ones included (VS 2019 16.5 or newer). ffbidx already sets the same for its own
|
|
# CUB-using kernel, which is why the other CUDA targets never needed it. C++ sources keep the
|
|
# default: none includes a CCCL header, and the switch would change the preprocessing of Qt, the
|
|
# Windows SDK and every fetched dependency with nothing to gain.
|
|
IF (MSVC)
|
|
ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CXX>:/EHsc>)
|
|
ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/Zc:preprocessor>)
|
|
ENDIF()
|
|
|
|
# No contraction of a*b+c into a fused multiply-add. GCC contracts whenever the target has FMA, so a
|
|
# -march=x86-64-v3 build (CI, production) and a baseline build rounded differently, and knife-edge
|
|
# decisions - which candidate cell a first pass indexes with, a resolution cut, a symmetry gate -
|
|
# came out differently from the same source and data. Off, every x86-64 level computes the same bits
|
|
# (measured: identical p.mtz on nine battery sets, no measurable time cost), and aarch64, where FMA is
|
|
# always there and GCC contracts by default, follows the same arithmetic. MSVC does not contract under
|
|
# its default /fp:precise. Host code of .cu sources gets it through nvcc; device code is not affected.
|
|
IF (NOT MSVC)
|
|
ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:C,CXX>:-ffp-contract=off>)
|
|
ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-ffp-contract=off>)
|
|
ENDIF()
|
|
|
|
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 portable products come out of two build modes; every artifact holds exactly one program:
|
|
#
|
|
# JFJOCH_VIEWER_ONLY jfjoch_viewer .tar.gz (Linux) / installer (Windows) / .dmg (macOS)
|
|
# and also rugnux (.tar.gz; .zip on Windows) and, on Linux only, the
|
|
# XDS plugin (.tar.gz)
|
|
# JFJOCH_RUGNUX_ONLY rugnux .tar.gz (Linux, incl. cross-built aarch64) / .zip (Windows)
|
|
#
|
|
# The viewer build compiles everything rugnux needs anyway, so one build packs all three; the
|
|
# rugnux-only mode remains for where there is no Qt (the aarch64 cross build).
|
|
#
|
|
# 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)")
|
|
|
|
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 -DNDEBUG -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)
|
|
|
|
# Dependencies are fetched as PINNED TARBALLS, not git clones. GitHub throttles unauthenticated
|
|
# git-upload-pack and picks its targets by TLS fingerprint, so a clone answers 200 to the initial
|
|
# ref advertisement and then 401 to the fetch itself; git asks for a password, finds no terminal,
|
|
# and the configure stops dead with no error. Which images it hits follows their OpenSSL version,
|
|
# which is why it looks like a broken build image rather than a rate limit. The archive endpoint is
|
|
# not part of that campaign, and a tarball is a fraction of the transfer (hdf5: 40 MB against a
|
|
# 271 MB shallow clone), so it is both the fix and the cheaper fetch.
|
|
#
|
|
# Every URL is pinned by tag or commit and its bytes by URL_HASH, so a silently changed archive
|
|
# fails the configure instead of entering the build. To bump one: change the version in the URL and
|
|
# replace the hash with `sha256sum` of the new tarball.
|
|
#
|
|
# Ceres needs one extra step for its abseil submodule; see image_analysis/CMakeLists.txt.
|
|
|
|
# zlib, via zlib-ng in its zlib-compatible mode: same zlib.h, same API and symbol names, faster
|
|
# deflate. It used to be the one compression library the project asked the host for; providing it
|
|
# here is what makes a build need no zlib-devel.
|
|
#
|
|
# It is built HERE, during the configure, into a small install prefix in the build tree, and
|
|
# ZLIB_ROOT then points every find_package(ZLIB) at it -- ours and those of HDF5, libtiff,
|
|
# cpp-httplib. Two alternatives were rejected:
|
|
#
|
|
# * FetchContent OVERRIDE_FIND_PACKAGE is the mechanism banned by the Eigen note further down
|
|
# (it segfaults the CMake bundled with Visual Studio), and a subproject's find_package(ZLIB)
|
|
# resolving an override through a nested FetchContent_MakeAvailable is exactly the faulting
|
|
# pattern.
|
|
# * Adding zlib-ng with add_subdirectory and aliasing its target to ZLIB::ZLIB looks simpler, but
|
|
# ZLIB::ZLIB is then an alias of a target built in this project, and a consumer that puts
|
|
# ZLIB::ZLIB in CMAKE_REQUIRED_LIBRARIES for its feature checks (libcurl did, when the viewer used
|
|
# it) breaks: try_compile only accepts IMPORTED targets, so that is a hard configure error, not a
|
|
# degraded check (verified).
|
|
#
|
|
# Building it first and finding it as an ordinary installed library avoids both: every consumer
|
|
# runs the stock FindZLIB module against a real libz.a and gets a genuine imported target.
|
|
#
|
|
# Passing -DZLIB_ROOT=<prefix> skips the build below and uses the zlib found there instead.
|
|
IF (NOT ZLIB_ROOT)
|
|
SET(ZLIB_ROOT "${CMAKE_BINARY_DIR}/zlib-ng-install")
|
|
IF (NOT EXISTS "${ZLIB_ROOT}/include/zlib.h")
|
|
FetchContent_Declare(zlib
|
|
URL https://github.com/zlib-ng/zlib-ng/archive/refs/tags/2.3.3.tar.gz
|
|
URL_HASH SHA256=f9c65aa9c852eb8255b636fd9f07ce1c406f061ec19a2e7d508b318ca0c907d1
|
|
SOURCE_SUBDIR cmake) # no CMakeLists.txt there: populate only, do not add_subdirectory
|
|
FetchContent_MakeAvailable(zlib)
|
|
|
|
# The nested configure inherits the toolchain, not the environment: pass the compiler, the
|
|
# flags and the platform selection explicitly, or a cross build (or an MSVC build with a
|
|
# non-default platform/toolset/runtime) would silently produce a library for the wrong one.
|
|
SET(JFJOCH_ZLIB_CMAKE_ARGS
|
|
-DCMAKE_INSTALL_PREFIX=${ZLIB_ROOT}
|
|
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
|
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
|
-DCMAKE_POSITION_INDEPENDENT_CODE=ON # xds-plugin is a shared library
|
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
|
-DBUILD_SHARED_LIBS=OFF
|
|
-DBUILD_TESTING=OFF
|
|
-DINSTALL_UTILS=OFF
|
|
-DZLIB_COMPAT=ON # provide zlib.h and the zlib API, not zlib-ng.h
|
|
-DWITH_GZFILEOP=ON # gzopen/gzread: GEMMI reads gzipped MTZ and CIF
|
|
-DWITH_NATIVE_INSTRUCTIONS=OFF) # portable binary; SIMD is chosen at run time
|
|
SET(JFJOCH_ZLIB_FORWARD CMAKE_TOOLCHAIN_FILE CMAKE_MSVC_RUNTIME_LIBRARY
|
|
CMAKE_OSX_ARCHITECTURES CMAKE_OSX_SYSROOT CMAKE_OSX_DEPLOYMENT_TARGET)
|
|
# CMAKE_SYSTEM_NAME only when actually cross-compiling: setting it is what PUTS a build into
|
|
# cross mode, so forwarding it unconditionally would make even a native zlib-ng think it is
|
|
# being cross-compiled.
|
|
IF (CMAKE_CROSSCOMPILING)
|
|
LIST(APPEND JFJOCH_ZLIB_FORWARD CMAKE_SYSTEM_NAME CMAKE_SYSTEM_PROCESSOR)
|
|
ENDIF()
|
|
FOREACH (_var IN LISTS JFJOCH_ZLIB_FORWARD)
|
|
IF (${_var})
|
|
LIST(APPEND JFJOCH_ZLIB_CMAKE_ARGS "-D${_var}=${${_var}}")
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
IF (CMAKE_GENERATOR_PLATFORM)
|
|
LIST(APPEND JFJOCH_ZLIB_CMAKE_ARGS -A "${CMAKE_GENERATOR_PLATFORM}")
|
|
ENDIF()
|
|
IF (CMAKE_GENERATOR_TOOLSET)
|
|
LIST(APPEND JFJOCH_ZLIB_CMAKE_ARGS -T "${CMAKE_GENERATOR_TOOLSET}")
|
|
ENDIF()
|
|
# Single-config generators pick the configuration at configure time, multi-config ones at
|
|
# build time; give each the one it reads and keep both on this build's configuration.
|
|
IF (CMAKE_CONFIGURATION_TYPES OR NOT CMAKE_BUILD_TYPE)
|
|
SET(JFJOCH_ZLIB_CONFIG Release)
|
|
ELSE()
|
|
SET(JFJOCH_ZLIB_CONFIG ${CMAKE_BUILD_TYPE})
|
|
ENDIF()
|
|
IF (NOT CMAKE_CONFIGURATION_TYPES)
|
|
LIST(APPEND JFJOCH_ZLIB_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${JFJOCH_ZLIB_CONFIG})
|
|
ENDIF()
|
|
|
|
MESSAGE(STATUS "Building zlib-ng (zlib-compatible) into ${ZLIB_ROOT}")
|
|
EXECUTE_PROCESS(
|
|
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" ${JFJOCH_ZLIB_CMAKE_ARGS}
|
|
-S "${zlib_SOURCE_DIR}" -B "${zlib_BINARY_DIR}"
|
|
RESULT_VARIABLE JFJOCH_ZLIB_RESULT
|
|
OUTPUT_VARIABLE JFJOCH_ZLIB_LOG ERROR_VARIABLE JFJOCH_ZLIB_LOG)
|
|
IF (JFJOCH_ZLIB_RESULT EQUAL 0)
|
|
EXECUTE_PROCESS(
|
|
COMMAND ${CMAKE_COMMAND} --build "${zlib_BINARY_DIR}" --config ${JFJOCH_ZLIB_CONFIG}
|
|
--target install
|
|
RESULT_VARIABLE JFJOCH_ZLIB_RESULT
|
|
OUTPUT_VARIABLE JFJOCH_ZLIB_LOG ERROR_VARIABLE JFJOCH_ZLIB_LOG)
|
|
ENDIF()
|
|
IF (NOT JFJOCH_ZLIB_RESULT EQUAL 0)
|
|
MESSAGE(FATAL_ERROR "Building the bundled zlib-ng failed:\n${JFJOCH_ZLIB_LOG}\n"
|
|
"Re-run the configure with -DZLIB_ROOT=<prefix> to use a zlib "
|
|
"already on this machine.")
|
|
ENDIF()
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
SET(ZLIB_USE_STATIC_LIBS TRUE)
|
|
FIND_PACKAGE(ZLIB REQUIRED)
|
|
|
|
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
|
|
URL https://github.com/gabime/spdlog/archive/refs/tags/v1.17.0.tar.gz
|
|
URL_HASH SHA256=d8862955c6d74e5846b3f580b1605d2428b11d97a410d86e2fb13e857cd3a744
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(
|
|
zstd
|
|
URL https://github.com/facebook/zstd/archive/refs/tags/v1.5.7.tar.gz
|
|
URL_HASH SHA256=37d7284556b20954e56e1ca85b80226768902e2edabd3b649e9e72c0c9012ee3
|
|
SOURCE_SUBDIR build/cmake
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(hdf5
|
|
URL https://github.com/HDFGroup/hdf5/archive/refs/tags/2.2.0.tar.gz
|
|
URL_HASH SHA256=5b8d75125ae7b4fef55d3b39e8d3dbfd238cdf63b6518afd67fa69ac80f06542
|
|
EXCLUDE_FROM_ALL)
|
|
|
|
SET(SLS_DETECTOR_VERSION "8.0.2")
|
|
SET(SLS_DETECTOR_SHA256 "783b557ebff281a537ec70a20a775dd412dd345bfcefff85988ecfafe703222a")
|
|
IF(SLS9)
|
|
SET(SLS_DETECTOR_VERSION "9.2.0")
|
|
SET(SLS_DETECTOR_SHA256 "020a7791934e5a9d034cfa4c1c69df7109488ab2f80a4e7fca07b3e51978933f")
|
|
ENDIF()
|
|
|
|
FetchContent_Declare(
|
|
sls_detector_package
|
|
URL https://github.com/slsdetectorgroup/slsDetectorPackage/archive/refs/tags/${SLS_DETECTOR_VERSION}.tar.gz
|
|
URL_HASH SHA256=${SLS_DETECTOR_SHA256}
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(
|
|
catch2
|
|
URL https://github.com/catchorg/Catch2/archive/refs/tags/v3.16.0.tar.gz
|
|
URL_HASH SHA256=0957cae5821b17ce07f0833aaa52b5137643a8382203221f363a8303c109af34
|
|
EXCLUDE_FROM_ALL
|
|
)
|
|
|
|
FetchContent_Declare(
|
|
httplib
|
|
URL https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.56.0.tar.gz
|
|
URL_HASH SHA256=41f214d844e3b9117b734a8cc305b6141c5b47d63009681944e03bc31d92b9ca
|
|
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
|
|
URL https://github.com/zeromq/libzmq/archive/refs/tags/v4.3.5.tar.gz
|
|
URL_HASH SHA256=6c972d1e6a91a0ecd79c3236f04cf0126f2f4dfbbad407d72b4606a7ba93f9c6
|
|
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), and catch2
|
|
# for jfjoch_portable_test. Only sls_detector_package (detector) is not built here -- it does
|
|
# not configure under MSVC.
|
|
FetchContent_MakeAvailable(zstd catch2 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
|
|
URL https://gitlab.com/libtiff/libtiff/-/archive/v4.7.2/libtiff-v4.7.2.tar.gz
|
|
URL_HASH SHA256=62b15f44c10106065211efa22a2dc77937bd97ee1f6e3afd2c9659010de112eb
|
|
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 (Apple Silicon, Grace on DGX Spark) gets NEON - added below the
|
|
# FetchContent, as FFTW's CMake build has no switch for it; 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)
|
|
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>)
|
|
# NEON: only FFTW's autotools build knows it (--enable-neon); its CMake build silently builds scalar
|
|
# code on ARM (and ignores an ENABLE_NEON, as this file once set). So the NEON codelets are added
|
|
# the way its CMakeLists adds the SSE2/AVX ones: the sources, and HAVE_NEON so that dft/conf.c and
|
|
# rdft/conf.c register them - as a definition, because its config.h template carries HAVE_NEON only
|
|
# as a comment. NEON is part of every aarch64 CPU, so no compiler flag is needed. It is single
|
|
# precision, which is all that is built here. Measured on Apple Silicon against the scalar build
|
|
# (same results to 1e-8): the indexer's batched 1D r2c 1.8x faster at a power-of-two length and 1.3x
|
|
# at 730, the 2D r2c of the beam-centre search 1.9x, a 128^3 c2r map 2.6x.
|
|
IF (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
|
|
FILE(GLOB _fftw_neon_sources ${fftw_SOURCE_DIR}/dft/simd/neon/*.c ${fftw_SOURCE_DIR}/rdft/simd/neon/*.c)
|
|
TARGET_SOURCES(fftw3f PRIVATE ${_fftw_neon_sources})
|
|
TARGET_COMPILE_DEFINITIONS(fftw3f PRIVATE HAVE_NEON=1)
|
|
ENDIF()
|
|
ADD_COMPILE_DEFINITIONS(JFJOCH_USE_FFTW)
|
|
|
|
# Eigen (header-only), consumed by the analysis libraries directly and by Ceres and ffbidx through
|
|
# their own find_package(Eigen3). The headers are fetched here and a two-file config package for
|
|
# them is written into the build tree; Eigen3_DIR then points at it, so every find_package(Eigen3)
|
|
# in the build -- ours, Ceres', ffbidx' -- resolves through the ordinary config path and gets this
|
|
# one copy. Nothing needs Eigen's own CMake, so the source is populated but never added.
|
|
#
|
|
# The obvious route, FetchContent_Declare(Eigen3 ... OVERRIDE_FIND_PACKAGE), IS BANNED and must not
|
|
# be reintroduced: it makes the CMake bundled with Visual Studio (cmake 4.x "-msvc") intermittently
|
|
# SEGFAULT during configure -- ~1 in 3 fresh configures, and 100% with Ceres CUDA on. 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. Stock Kitware CMake runs the
|
|
# identical scripts fine, so it is a bug in the VS-bundled cmake binary. A generated config package
|
|
# never enters that machinery: find_package finds an ordinary Eigen3Config.cmake on disk, exactly as
|
|
# it would for an Eigen installed on the system.
|
|
#
|
|
# Passing -DEigen3_DIR=<dir> skips the fetch and uses the Eigen whose config package lives there.
|
|
SET(JFJOCH_EIGEN_VERSION 3.4.1)
|
|
IF (Eigen3_DIR)
|
|
MESSAGE(STATUS "Eigen3_DIR is set (${Eigen3_DIR}) -- using that Eigen instead of the bundled one")
|
|
ELSE()
|
|
FetchContent_Declare(eigen3
|
|
URL https://gitlab.com/libeigen/eigen/-/archive/${JFJOCH_EIGEN_VERSION}/eigen-${JFJOCH_EIGEN_VERSION}.tar.gz
|
|
URL_HASH SHA256=b93c667d1b69265cdb4d9f30ec21f8facbbe8b307cf34c0b9942834c6d4fdbe2
|
|
SOURCE_SUBDIR cmake) # no CMakeLists.txt there: populate only, do not add_subdirectory
|
|
FetchContent_MakeAvailable(eigen3)
|
|
|
|
SET(JFJOCH_EIGEN_CONFIG_DIR "${CMAKE_BINARY_DIR}/eigen3-config")
|
|
FILE(WRITE "${JFJOCH_EIGEN_CONFIG_DIR}/Eigen3Config.cmake"
|
|
"# Generated by the Jungfraujoch build -- do not edit.\n"
|
|
"if (NOT TARGET Eigen3::Eigen)\n"
|
|
" add_library(Eigen3::Eigen INTERFACE IMPORTED GLOBAL)\n"
|
|
" set_target_properties(Eigen3::Eigen PROPERTIES\n"
|
|
" INTERFACE_INCLUDE_DIRECTORIES \"${eigen3_SOURCE_DIR}\")\n"
|
|
"endif()\n"
|
|
"set(EIGEN3_INCLUDE_DIR \"${eigen3_SOURCE_DIR}\")\n"
|
|
"set(EIGEN3_INCLUDE_DIRS \"${eigen3_SOURCE_DIR}\")\n"
|
|
"set(EIGEN3_VERSION_STRING \"${JFJOCH_EIGEN_VERSION}\")\n"
|
|
"set(Eigen3_FOUND TRUE)\n")
|
|
# AnyNewerVersion, not Eigen's own SameMajorVersion rule: Ceres asks for a version RANGE,
|
|
# find_package(Eigen3 3.3.4...5 NO_MODULE), and a same-major file declines any range whose two
|
|
# endpoints differ in major version. Eigen's own config file does exactly that, which is how a
|
|
# build could end up compiling Ceres against one Eigen and everything else against another.
|
|
INCLUDE(CMakePackageConfigHelpers)
|
|
WRITE_BASIC_PACKAGE_VERSION_FILE("${JFJOCH_EIGEN_CONFIG_DIR}/Eigen3ConfigVersion.cmake"
|
|
VERSION ${JFJOCH_EIGEN_VERSION} COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
|
|
SET(Eigen3_DIR "${JFJOCH_EIGEN_CONFIG_DIR}")
|
|
ENDIF()
|
|
|
|
# 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()
|
|
|
|
# Mbed TLS: the TLS backend of cpp-httplib in the jfjoch_viewer HTTP client (viewer/JFJochHttpReader).
|
|
# Fetched and STATICALLY linked ONLY for viewer builds, so the broker/writer never pull in a TLS
|
|
# stack. One backend on every platform: it builds with MSVC and needs nothing from the host, unlike
|
|
# OpenSSL, which the macOS SDK does not have. cpp-httplib loads the trusted roots from the OS store
|
|
# (Windows certificate store, macOS Keychain, the CA bundle on Linux). The release tarball, not
|
|
# the GitHub archive: only it carries the tf-psa-crypto and framework submodules.
|
|
IF (JFJOCH_VIEWER_BUILD OR JFJOCH_VIEWER_ONLY)
|
|
SET(ENABLE_PROGRAMS OFF CACHE BOOL "" FORCE)
|
|
SET(ENABLE_TESTING OFF CACHE BOOL "" FORCE)
|
|
SET(MBEDTLS_FATAL_WARNINGS OFF CACHE BOOL "" FORCE)
|
|
SET(TF_PSA_CRYPTO_FATAL_WARNINGS OFF CACHE BOOL "" FORCE)
|
|
SET(USE_STATIC_MBEDTLS_LIBRARY ON CACHE BOOL "" FORCE)
|
|
SET(USE_SHARED_MBEDTLS_LIBRARY OFF CACHE BOOL "" FORCE)
|
|
SET(USE_SHARED_TF_PSA_CRYPTO_LIBRARY OFF CACHE BOOL "" FORCE)
|
|
FetchContent_Declare(mbedtls
|
|
URL https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-4.2.0/mbedtls-4.2.0.tar.bz2
|
|
URL_HASH SHA256=2bed9d713b4668f76553b097e72b8aa30bc8f112a940d7ae228d524bbde6ffea
|
|
EXCLUDE_FROM_ALL)
|
|
FetchContent_MakeAvailable(mbedtls)
|
|
ENDIF()
|
|
|
|
# The notices every package ships (installed at the end of this file). Set before the subdirectories
|
|
# because the macOS viewer puts them into its .app bundle itself - see viewer/CMakeLists.txt.
|
|
SET(JFJOCH_NOTICE_FILES
|
|
${CMAKE_SOURCE_DIR}/LICENSE
|
|
${CMAKE_SOURCE_DIR}/THIRD_PARTY_NOTICES.md
|
|
${CMAKE_SOURCE_DIR}/docs/ACKNOWLEDGEMENT.md)
|
|
|
|
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)
|
|
ADD_SUBDIRECTORY(tests) # jfjoch_portable_test only
|
|
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)
|
|
ADD_SUBDIRECTORY(tests) # jfjoch_portable_test only
|
|
IF (NOT WIN32 AND NOT APPLE) # no native XDS for Windows; the macOS plugin is not tested
|
|
ADD_SUBDIRECTORY(xds-plugin)
|
|
ENDIF()
|
|
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()
|
|
INSTALL(FILES ${_cufft_dll} DESTINATION bin COMPONENT rugnux)
|
|
IF (JFJOCH_VIEWER_ONLY)
|
|
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 AND (WIN32 OR APPLE))
|
|
set(CPACK_COMPONENTS_ALL viewer rugnux) # the XDS plugin is built on Linux only
|
|
elseif (JFJOCH_VIEWER_ONLY)
|
|
set(CPACK_COMPONENTS_ALL viewer rugnux xds_plugin)
|
|
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})
|
|
|
|
# Names of the portable .tar.gz archives (CI renames them to .tgz). rugnux and the plugin always
|
|
# carry their architecture, because rugnux 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. The Linux viewer is x86_64-only and keeps its existing name.
|
|
# The plugin has no -cuda/-cpu tag: it does not use CUDA, so both variants build the same library.
|
|
if (APPLE)
|
|
set(_jfjoch_tgz_os "macos")
|
|
else()
|
|
set(_jfjoch_tgz_os "linux")
|
|
endif()
|
|
if (JFJOCH_CUDA_AVAILABLE)
|
|
set(_jfjoch_tgz_variant "cuda${CUDAToolkit_VERSION_MAJOR}")
|
|
else()
|
|
set(_jfjoch_tgz_variant "cpu")
|
|
endif()
|
|
set(CPACK_ARCHIVE_VIEWER_FILE_NAME "jfjoch_viewer-${JFJOCH_VERSION}-${_jfjoch_tgz_os}-${_jfjoch_tgz_variant}")
|
|
if (WIN32)
|
|
set(CPACK_ARCHIVE_RUGNUX_FILE_NAME "rugnux-${JFJOCH_VERSION}-win64-${_jfjoch_tgz_variant}")
|
|
else()
|
|
set(CPACK_ARCHIVE_RUGNUX_FILE_NAME "rugnux-${JFJOCH_VERSION}-${_jfjoch_tgz_os}-${CMAKE_SYSTEM_PROCESSOR}-${_jfjoch_tgz_variant}")
|
|
endif()
|
|
set(CPACK_ARCHIVE_XDS_PLUGIN_FILE_NAME "jfjoch_xds_plugin-${JFJOCH_VERSION}-linux-${CMAKE_SYSTEM_PROCESSOR}")
|
|
|
|
# macOS and Windows pack the viewer as a .dmg / NSIS installer and the other programs of the same
|
|
# build (rugnux) as an archive. CPack reads
|
|
# CPACK_PROJECT_CONFIG_FILE once per generator, which is where each generator gets its components.
|
|
file(WRITE ${CMAKE_BINARY_DIR}/CPackProjectConfig.cmake [=[
|
|
if (CPACK_GENERATOR STREQUAL "TGZ" OR CPACK_GENERATOR STREQUAL "ZIP")
|
|
list(REMOVE_ITEM CPACK_COMPONENTS_ALL viewer)
|
|
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
|
set(CPACK_COMPONENTS_GROUPING IGNORE)
|
|
else()
|
|
set(CPACK_COMPONENTS_ALL viewer)
|
|
endif()
|
|
]=])
|
|
|
|
# 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). Named like the
|
|
# Windows and Linux artifacts; CMAKE_SYSTEM_PROCESSOR is arm64 on Apple Silicon.
|
|
# plus rugnux as .tar.gz, see CPackProjectConfig.cmake above
|
|
set(CPACK_GENERATOR "DragNDrop;TGZ")
|
|
set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackProjectConfig.cmake)
|
|
set(CPACK_PACKAGE_FILE_NAME "jfjoch-viewer-${JFJOCH_VERSION}-macos-${CMAKE_SYSTEM_PROCESSOR}")
|
|
set(CPACK_DMG_VOLUME_NAME "Jungfraujoch Viewer ${JFJOCH_VERSION}")
|
|
elseif (WIN32 AND NOT JFJOCH_RUGNUX_ONLY)
|
|
# NSIS installer .exe (Qt runtime deployed next to the binary by windeployqt), plus rugnux as
|
|
# a .zip, see CPackProjectConfig.cmake above.
|
|
set(CPACK_GENERATOR "NSIS;ZIP")
|
|
set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackProjectConfig.cmake)
|
|
|
|
# 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)
|
|
set(CPACK_PACKAGE_FILE_NAME ${CPACK_ARCHIVE_RUGNUX_FILE_NAME})
|
|
elseif (JFJOCH_VIEWER_ONLY OR JFJOCH_RUGNUX_ONLY)
|
|
# Linux portable products: self-contained .tar.gz archives (Qt is linked statically, so there is
|
|
# nothing external to ship alongside a binary). Built on the oldest supported distro (RHEL 8) for
|
|
# a low glibc floor, so an archive runs on any newer Linux -- unlike the per-distro .rpm/.deb
|
|
# these replace in the release.
|
|
set(CPACK_GENERATOR "TGZ")
|
|
# Package only the components in CPACK_COMPONENTS_ALL. 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 and abseil's EXCLUDE_FROM_ALL sub-libraries -- which the
|
|
# portable build does not produce, so cpack aborts with "cannot find <artifact>". This mirrors
|
|
# CPACK_DEB_COMPONENT_INSTALL / CPACK_RPM_COMPONENT_INSTALL in the DEB/RPM branches below.
|
|
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
|
if (JFJOCH_RUGNUX_ONLY)
|
|
# A single tarball named CPACK_PACKAGE_FILE_NAME (no per-component suffix).
|
|
set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)
|
|
set(CPACK_PACKAGE_FILE_NAME ${CPACK_ARCHIVE_RUGNUX_FILE_NAME})
|
|
else()
|
|
# One tarball per program -- viewer, rugnux, XDS plugin -- named by CPACK_ARCHIVE_<C>_FILE_NAME.
|
|
set(CPACK_COMPONENTS_GROUPING IGNORE)
|
|
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 notices (top-level LICENSE, the third-party manifest, the verbatim license texts, and
|
|
# the acknowledgements the programs refer a user to) 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.
|
|
FOREACH(_component IN LISTS CPACK_COMPONENTS_ALL)
|
|
IF (APPLE AND _component STREQUAL "viewer")
|
|
CONTINUE() # inside the .app bundle instead, see viewer/CMakeLists.txt
|
|
ENDIF()
|
|
IF (_component STREQUAL "xds_plugin")
|
|
CONTINUE() # its own, shorter set, see xds-plugin/CMakeLists.txt
|
|
ENDIF()
|
|
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)
|