-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
488 lines (430 loc) · 23.8 KB
/
CMakeLists.txt
File metadata and controls
488 lines (430 loc) · 23.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
# ___________________________________________________________________________________
# SPDX-License-Identifier: MIT
# This file is part of H5CPP.
# Copyright (c) 2025-2026 Varga Labs, Toronto, ON, Canada.
# __________________________________________________________________________________
cmake_minimum_required(VERSION 3.22.0)
# Must be set before project() — CMake's Apple toolchain reads this at project() time.
# macOS 14.0 is the minimum deployment target that exposes std::stop_token in Apple's libc++.
if(APPLE)
set(CMAKE_OSX_DEPLOYMENT_TARGET "14.4" CACHE STRING "Minimum macOS deployment version")
endif()
# Derive package version from the latest git tag before project(), so CPack
# embeds it as PROJECT_VERSION rather than a stale hardcoded number. Falls
# back to a placeholder when building from a tarball without git history.
find_package(Git QUIET)
set(H5CPP_PROJECT_VERSION "1.12.7")
if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 --match "v[0-9]*"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE H5CPP_GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if(H5CPP_GIT_TAG MATCHES "^v([0-9]+(\\.[0-9]+)*)$")
set(H5CPP_PROJECT_VERSION "${CMAKE_MATCH_1}")
endif()
endif()
project(libh5cpp-dev VERSION ${H5CPP_PROJECT_VERSION} LANGUAGES CXX C)
# ─── Standard Settings ────────────────────────────────────────────────────────────
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(WARNING "In-source builds are discouraged.")
else()
execute_process(
COMMAND ${CMAKE_COMMAND} -E create_symlink
${CMAKE_BINARY_DIR}/compile_commands.json
${CMAKE_SOURCE_DIR}/compile_commands.json
OUTPUT_QUIET ERROR_QUIET
)
endif()
# ─── Git Version Injection ────────────────────────────────────────────────────────
execute_process(COMMAND git rev-parse --short HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
execute_process(COMMAND git describe --tags --abbrev=0
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_TAG OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
set(H5CPP_BASE_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
if(GIT_TAG)
set(H5CPP_VERSION "${GIT_TAG}")
else()
set(H5CPP_VERSION "${H5CPP_BASE_VERSION}-${GIT_COMMIT_HASH}")
endif()
# ─── Options ──────────────────────────────────────────────────────────────────────
option(H5CPP_BUILD_EXAMPLES "Build examples" OFF)
option(H5CPP_BUILD_TESTS "Build tests" OFF)
option(H5CPP_BUILD_BENCH "Build benches" OFF)
option(H5CPP_USE_LIBDEFLATE "Use libdeflate for H5CPP deflate/gzip filters when available" ON)
option(H5CPP_REQUIRE_LIBDEFLATE "Fail configuration if H5CPP_USE_LIBDEFLATE is ON and libdeflate is not found" OFF)
option(H5CPP_INSTALL_LIBDEFLATE "Install the resolved libdeflate header and library with H5CPP" OFF)
option(H5CPP_USE_LZ4 "Use LZ4 compression filter when available" ON)
option(H5CPP_USE_ZSTD "Use Zstd compression filter when available" ON)
option(H5CPP_USE_SZIP "Use vendored SZIP (Rice) compression filter when available" ON)
# ─── System Dependencies ──────────────────────────────────────────────────────────
include(GNUInstallDirs)
find_package(Threads REQUIRED QUIET)
find_package(Python3 COMPONENTS Interpreter QUIET)
# match hdf5 versioning x.x.x.h5cpp-version
set(H5CPP_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
if(WIN32)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "C:/h5cpp" CACHE PATH "default install path" FORCE)
endif()
elseif(UNIX)
# Pick up custom HDF Group installs at /usr/local/HDF_Group/HDF5/<version>/
# before falling back to system paths. Versioned directories are sorted
# in descending order so the newest custom install wins over older ones
# and over /usr/local. Honour a pre-set HDF5_ROOT (via -D or $ENV{...},
# e.g. CI source-build at /home/runner/work/_temp/hdf5-X.Y.Z-install)
# without overwriting it.
if(NOT DEFINED HDF5_ROOT AND DEFINED ENV{HDF5_ROOT})
set(HDF5_ROOT "$ENV{HDF5_ROOT}")
endif()
if(NOT DEFINED HDF5_ROOT)
file(GLOB _hdf5_custom_roots LIST_DIRECTORIES true "/usr/local/HDF_Group/HDF5/[0-9]*")
list(SORT _hdf5_custom_roots ORDER DESCENDING)
set(HDF5_ROOT ${_hdf5_custom_roots} "/usr/local" "/usr")
endif()
find_package(PkgConfig REQUIRED QUIET)
endif()
if(APPLE)
message(STATUS "H5CPP macOS support: CI runs on macos-13 with Homebrew HDF5 and LLVM clang-17/18")
endif()
if(ANDROID)
message(STATUS "***WARNING: h5cpp is not fully tested on android ***")
endif()
find_package(Threads REQUIRED QUIET)
# ─── HDF5 ─────────────────────────────────────────────────────────────────────────
find_package(HDF5 REQUIRED COMPONENTS C)
# HDF5 floor is decoupled from h5cpp package version. Previously the check
# compared HDF5_VERSION against PROJECT_VERSION, which coupled package
# versioning to HDF5 minimums by coincidence. After #247 made
# PROJECT_VERSION track the git tag, the comparison stopped being meaningful.
# Pin the floor explicitly.
#
# 1.10.4 matches the prior implicit floor (the stale project(VERSION 1.10.4.6)
# line that #247 removed). The CI matrix runs Ubuntu 22.04 with system
# HDF5 1.10.7 (floor coverage restored by #235); raising the floor above
# 1.10.4 would break that matrix entry. When dropping 1.10.x coverage in
# a future cohort, bump this constant deliberately and remove the 22.04
# matrix entry in the same commit.
set(H5CPP_HDF5_FLOOR "1.10.4")
if(HDF5_VERSION VERSION_LESS ${H5CPP_HDF5_FLOOR})
message(FATAL_ERROR
"-- !!! H5CPP requires HDF5 v${H5CPP_HDF5_FLOOR} or greater (found ${HDF5_VERSION}) !!!"
)
else()
message(STATUS
"H5CPP ${PROJECT_VERSION} matches with minimum required HDF5 v${HDF5_VERSION}"
)
endif()
# ─── ROS3 VFD detection ───────────────────────────────────────────────────────────
foreach(_hdf5_inc IN LISTS HDF5_INCLUDE_DIRS)
foreach(_pubconf IN ITEMS "H5pubconf.h" "H5pubconf-64.h")
if(EXISTS "${_hdf5_inc}/${_pubconf}")
file(STRINGS "${_hdf5_inc}/${_pubconf}" _ros3_line REGEX "H5_HAVE_ROS3_VFD")
if(_ros3_line MATCHES "#define H5_HAVE_ROS3_VFD")
set(H5CPP_HAVE_ROS3_VFD TRUE)
break()
endif()
endif()
endforeach()
if(H5CPP_HAVE_ROS3_VFD)
break()
endif()
endforeach()
if(H5CPP_HAVE_ROS3_VFD)
message(STATUS "H5CPP: ROS3 VFD detected — S3 read-only support enabled")
else()
message(STATUS "H5CPP: ROS3 VFD not found — S3 support disabled")
endif()
option(H5CPP_NETWORK_TESTS "Enable network-dependent tests (requires outbound S3 access)" OFF)
# ─── MPI (optional) ───────────────────────────────────────────────────────────────
find_package(MPI QUIET COMPONENTS C CXX)
if(MPI_FOUND AND HDF5_IS_PARALLEL)
message(STATUS "MPI and PHDF5 found: Parallel H5CPP enabled")
endif()
# ─── Include Directories & Libraries ──────────────────────────────────────────────
find_package(ZLIB REQUIRED)
list(APPEND H5CPP_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${HDF5_INCLUDE_DIRS})
list(APPEND H5CPP_LIBS Threads::Threads ${HDF5_LIBRARIES} ZLIB::ZLIB)
# ─── Thirdparty ───────────────────────────────────────────────────────────────────
add_subdirectory(thirdparty EXCLUDE_FROM_ALL)
if(H5CPP_LIBDEFLATE_FOUND)
message(STATUS "H5CPP libdeflate support: vendored ${H5CPP_LIBDEFLATE_INCLUDE_DIR}")
elseif(H5CPP_USE_LIBDEFLATE)
message(STATUS "H5CPP libdeflate support: not found; zlib fallback will be used")
endif()
if(H5CPP_INSTALL_LIBDEFLATE AND NOT H5CPP_LIBDEFLATE_FOUND)
message(FATAL_ERROR "H5CPP_INSTALL_LIBDEFLATE is ON, but libdeflate was not found")
endif()
# ─── LZ4 (optional) ───────────────────────────────────────────────────────────────
if(H5CPP_USE_LZ4)
find_library(H5CPP_LZ4_LIBRARY NAMES lz4)
find_path(H5CPP_LZ4_INCLUDE_DIR NAMES lz4.h)
if(H5CPP_LZ4_LIBRARY AND H5CPP_LZ4_INCLUDE_DIR)
message(STATUS "H5CPP LZ4 support: ${H5CPP_LZ4_LIBRARY}")
else()
message(STATUS "H5CPP LZ4 support: not found")
endif()
endif()
# ─── Zstd (optional) ──────────────────────────────────────────────────────────────
if(H5CPP_USE_ZSTD)
if(H5CPP_ZSTD_FOUND)
message(STATUS "H5CPP Zstd support: vendored ${H5CPP_ZSTD_INCLUDE_DIR}")
else()
message(STATUS "H5CPP Zstd support: not found")
endif()
endif()
# ─── SZIP (optional) ──────────────────────────────────────────────────────────────
if(H5CPP_USE_SZIP)
if(H5CPP_SZIP_FOUND)
message(STATUS "H5CPP SZIP support: vendored ${H5CPP_SZIP_INCLUDE_DIR}")
else()
message(STATUS "H5CPP SZIP support: not found")
endif()
endif()
# ─── Header-only Library Target ───────────────────────────────────────────────────
add_library(h5cpp INTERFACE)
add_library(h5cpp::h5cpp ALIAS h5cpp)
target_include_directories(h5cpp INTERFACE $<BUILD_INTERFACE:${H5CPP_INCLUDE_DIRS}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_link_libraries(h5cpp INTERFACE ${H5CPP_LIBS})
target_compile_features(h5cpp INTERFACE cxx_std_20)
# MSVC does not update __cplusplus to reflect the actual standard without this flag;
# without it the #error guard in H5Qall.hpp always fires even under /std:c++20.
if(MSVC)
target_compile_options(h5cpp INTERFACE /Zc:__cplusplus)
endif()
# The h5cpp-compiler reflection annotations ([[h5::doc]], [[h5::chunk]],
# [[h5::compress]], [[h5::name]], [[h5::ignore]], ...) live in the `h5::`
# attribute namespace. A plain compiler — i.e. one not running the h5cpp-compiler
# preprocessing pass — does not know that namespace, ignores the attributes, and
# emits -Wattributes for every annotated struct. Declare the namespace
# intentional so consumers that annotate their own types build cleanly. Scoped
# to `h5::` where the compiler supports it (GCC 11+); Clang/older GCC fall back
# to the broader unknown-attribute switch; MSVC silences C5030. Guarded by
# check_cxx_compiler_flag so unsupported toolchains are left untouched. (#291)
if(MSVC)
target_compile_options(h5cpp INTERFACE /wd5030)
else()
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-Wno-attributes=h5::" H5CPP_HAS_WNO_ATTRIBUTES_NS)
if(H5CPP_HAS_WNO_ATTRIBUTES_NS)
target_compile_options(h5cpp INTERFACE -Wno-attributes=h5::)
else()
check_cxx_compiler_flag("-Wno-unknown-attributes" H5CPP_HAS_WNO_UNKNOWN_ATTRIBUTES)
if(H5CPP_HAS_WNO_UNKNOWN_ATTRIBUTES)
target_compile_options(h5cpp INTERFACE -Wno-unknown-attributes)
endif()
endif()
endif()
if(H5CPP_HAVE_ROS3_VFD)
target_compile_definitions(h5cpp INTERFACE H5CPP_HAVE_ROS3_VFD=1)
endif()
if(H5CPP_LIBDEFLATE_FOUND)
target_link_libraries(h5cpp INTERFACE ${H5CPP_LIBDEFLATE_TARGET})
target_compile_definitions(h5cpp INTERFACE H5CPP_HAS_LIBDEFLATE=1)
else()
target_compile_definitions(h5cpp INTERFACE H5CPP_DISABLE_LIBDEFLATE=1)
endif()
if(H5CPP_USE_LZ4 AND H5CPP_LZ4_LIBRARY AND H5CPP_LZ4_INCLUDE_DIR)
target_compile_definitions(h5cpp INTERFACE H5CPP_HAS_LZ4=1)
target_include_directories(h5cpp INTERFACE $<BUILD_INTERFACE:${H5CPP_LZ4_INCLUDE_DIR}>)
target_link_libraries(h5cpp INTERFACE ${H5CPP_LZ4_LIBRARY})
endif()
if(H5CPP_USE_ZSTD AND H5CPP_ZSTD_FOUND)
target_link_libraries(h5cpp INTERFACE ${H5CPP_ZSTD_TARGET})
endif()
if(H5CPP_USE_SZIP AND H5CPP_SZIP_FOUND)
target_link_libraries(h5cpp INTERFACE ${H5CPP_SZIP_TARGET})
endif()
# ─── Subdirectories ───────────────────────────────────────────────────────────────
if(H5CPP_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
include(CTest)
if(H5CPP_BUILD_TESTS AND BUILD_TESTING AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt)
add_subdirectory(test)
endif()
if(H5CPP_BUILD_BENCH AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/bench/CMakeLists.txt)
add_subdirectory(bench)
endif()
# ─── Install Rules ────────────────────────────────────────────────────────────────
#
# Install destinations are RELATIVE to CMAKE_INSTALL_PREFIX (or, when packaging,
# to CPACK_PACKAGING_INSTALL_PREFIX). This is what CPack's productbuild driver
# expects on macOS — absolute destinations bypass CPack's staging entirely and
# the .pkg build fails trying to write to /usr/local/include literally
# (see https://gitlab.kitware.com/cmake/cmake/-/issues/14642). DEB/RPM on Linux
# use DESTDIR-style staging, so they tolerate either form, but keeping a single
# relative scheme across all generators is cleaner.
#
# productbuild on macOS always builds per-component sub-packages, and NSIS
# on Windows derives an internal variable name from the component name
# (rejecting '-' chars). Set a single short, alpha-only component name
# ("h5cpp") for every install() rule. CPACK_COMPONENTS_ALL below tells
# productbuild to actually pack it; DEB/RPM/NSIS treat the component name
# as cosmetic and produce the same monolithic output. The user-visible
# package name (CPACK_PACKAGE_NAME = "h5cpp-dev") and DEB/RPM/Brew names
# are unchanged.
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "h5cpp")
if(WIN32)
set(INSTALL_DIR_CMAKE "share/h5cpp/cmake")
set(INSTALL_DIR_INCLUDE "include")
set(INSTALL_DIR_EXAMPLES "examples")
elseif(UNIX)
set(INSTALL_DIR_CMAKE "${CMAKE_INSTALL_LIBDIR}/cmake/h5cpp")
set(INSTALL_DIR_INCLUDE "${CMAKE_INSTALL_INCLUDEDIR}")
set(INSTALL_DIR_EXAMPLES "${CMAKE_INSTALL_DATADIR}/h5cpp")
endif()
message(STATUS "Install directory: ${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_INCLUDE}")
# Generate single-header amalgamation during build
set(H5CPP_AMALGAMATED_HEADER ${CMAKE_BINARY_DIR}/h5cpp.hpp)
add_custom_command(
OUTPUT ${H5CPP_AMALGAMATED_HEADER}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/amalgamate.py ${CMAKE_SOURCE_DIR}/h5cpp ${H5CPP_AMALGAMATED_HEADER}
DEPENDS ${CMAKE_SOURCE_DIR}/scripts/amalgamate.py ${CMAKE_SOURCE_DIR}/h5cpp/core ${CMAKE_SOURCE_DIR}/h5cpp/io
COMMENT "Amalgamating h5cpp headers into h5cpp.hpp"
)
add_custom_target(h5cpp-amalgamate ALL DEPENDS ${H5CPP_AMALGAMATED_HEADER})
# Install header-only library (directory + single-header)
install(DIRECTORY h5cpp DESTINATION ${INSTALL_DIR_INCLUDE})
install(FILES ${H5CPP_AMALGAMATED_HEADER} DESTINATION ${INSTALL_DIR_INCLUDE})
install(TARGETS h5cpp EXPORT h5cpp-targets)
if(H5CPP_LIBDEFLATE_FOUND)
install(FILES "${H5CPP_LIBDEFLATE_INCLUDE_DIR}/libdeflate.h" DESTINATION "${INSTALL_DIR_INCLUDE}")
install(TARGETS libh5cpp-libdeflate libh5cpp-libdeflate-static EXPORT h5cpp-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
if(H5CPP_ZSTD_FOUND)
install(TARGETS libh5cpp-zstd libh5cpp-zstd-static EXPORT h5cpp-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
if(H5CPP_SZIP_FOUND)
install(TARGETS libh5cpp-szip libh5cpp-szip-static EXPORT h5cpp-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
# Install examples
install(DIRECTORY examples/attributes DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/basics DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY thirdparty/ DESTINATION "${INSTALL_DIR_EXAMPLES}/thirdparty"
# blitz/v*/config/ and m4/ hold autotools-era symlinks (compile,
# config.guess, ltmain.sh, libtool.m4 …) pointing into /usr/share/
# automake-1.16/. On Windows git checks them out as broken symlinks
# which CPack -G NSIS aborts on ("File: failed opening file …
# blitz/v1.0.2/config/compile"). h5cpp examples are CMake-only so
# these autotools artifacts are dead weight everywhere — drop them
# from the install entirely.
REGEX "blitz/v[0-9.]+/(config|m4)/" EXCLUDE)
install(DIRECTORY examples/compound DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/csv DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/datasets DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/datatypes DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/half-float DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/multi-tu DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/optimized DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/packet-table DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/raw_memory DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/stl DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/string DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/transform DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(DIRECTORY examples/utf DESTINATION "${INSTALL_DIR_EXAMPLES}")
install(FILES examples/CMakeLists.txt DESTINATION "${INSTALL_DIR_EXAMPLES}")
# Package config
include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/config.cmake.in
${CMAKE_BINARY_DIR}/h5cpp-config.cmake
INSTALL_DESTINATION ${INSTALL_DIR_CMAKE}
)
write_basic_package_version_file(
${CMAKE_BINARY_DIR}/h5cpp-config-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(PACKAGE h5cpp)
export(EXPORT h5cpp-targets)
install(EXPORT h5cpp-targets DESTINATION ${INSTALL_DIR_CMAKE})
install(FILES
${CMAKE_BINARY_DIR}/h5cpp-config.cmake
${CMAKE_BINARY_DIR}/h5cpp-config-version.cmake
DESTINATION ${INSTALL_DIR_CMAKE}
)
# ─── pkg-config ───────────────────────────────────────────────────────────────
configure_file(cmake/h5cpp.pc.in h5cpp.pc @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/h5cpp.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# ─── CPack ────────────────────────────────────────────────────────────────────
set(CPACK_PACKAGE_NAME "h5cpp-dev")
set(CPACK_PACKAGE_VENDOR "Varga Labs")
set(CPACK_PACKAGE_CONTACT "steven.varga@gmail.com")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "C++ template library for HDF5 I/O")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://h5cpp.org")
set(CPACK_PACKAGE_VERSION "${H5CPP_VERSION}")
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
# productbuild on macOS rejects license files without a .rtf/.rtfd/.html/.txt
# extension. The canonical LICENSE in the source tree is extensionless, so
# stage a LICENSE.txt copy in the build dir and point CPack at it. Other
# generators (DEB/RPM/NSIS) accept .txt fine.
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
"${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt"
COPYONLY)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt")
set(CPACK_STRIP_FILES OFF)
# productbuild iterates CPACK_COMPONENTS_ALL to decide which component
# sub-packages to build and pack. Without this set explicitly, the install
# step shows up as `Install project: libh5cpp-dev []` (empty components
# list) and the resulting .pkg is metadata-only at ~2.3 KB. Listing the
# one component our install rules use (via CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
# above) is enough — CPack will pack that component's files.
# DEB/RPM/NSIS ignore CPACK_COMPONENTS_ALL when no per-component packaging
# is configured, so this is a no-op for them.
set(CPACK_COMPONENTS_ALL "h5cpp")
# Headers land at <prefix>/include/h5cpp/ — ambient, no -I flag needed by
# consumers. The prefix differs per platform convention:
# * Linux DEB/RPM → /usr (already what apt/yum users expect)
# * macOS productbuild → /usr/local (Homebrew / Apple convention)
# * Windows NSIS does not honour CPACK_PACKAGING_INSTALL_PREFIX; the
# installer lets the user pick a target dir (defaulting to Program Files).
if(APPLE)
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local")
else()
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
endif()
set(CPACK_DEBIAN_PACKAGE_NAME "h5cpp-dev")
set(CPACK_DEBIAN_PACKAGE_SECTION "libdevel")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libhdf5-dev")
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "h5cpp-compiler")
# RPM
set(CPACK_RPM_PACKAGE_NAME "h5cpp-devel")
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
set(CPACK_RPM_PACKAGE_REQUIRES "hdf5-devel")
set(CPACK_RPM_PACKAGE_SUGGESTS "h5cpp-compiler")
# NSIS (Windows installer)
set(CPACK_NSIS_PACKAGE_NAME "h5cpp ${H5CPP_VERSION}")
set(CPACK_NSIS_DISPLAY_NAME "H5CPP ${H5CPP_VERSION}")
set(CPACK_NSIS_URL_INFO_ABOUT "https://h5cpp.org")
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
# productbuild (macOS .pkg)
set(CPACK_PRODUCTBUILD_IDENTIFIER "org.h5cpp.h5cpp")
# Override the default per-generator filename so that amd64 / arm64 / x86_64 /
# aarch64 / darwin-arm64 / windows-amd64 produce distinct names when collected
# into a single release upload directory. Without this, multi-arch CI matrix
# builds emit identical filenames and overwrite each other on the Release page.
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-v${PROJECT_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
string(TOLOWER "${CPACK_PACKAGE_FILE_NAME}" CPACK_PACKAGE_FILE_NAME)
include(CPack)
# ─── Developer convenience targets ───────────────────────────────────────────
find_program(DOXYGEN_EXECUTABLE doxygen)
if(DOXYGEN_EXECUTABLE)
add_custom_target(docs-doxygen COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/doxy
COMMENT "Building Doxygen API reference → docs/doxygen/html"
VERBATIM
)
endif()