-
Notifications
You must be signed in to change notification settings - Fork 13
/
CMakeLists.txt
344 lines (285 loc) · 12.8 KB
/
CMakeLists.txt
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
cmake_minimum_required(VERSION 3.12)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(FetchContent)
# -------------------------------------------------------------------------------- #
# CMake policy
# -------------------------------------------------------------------------------- #
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13")
cmake_policy(SET CMP0077 NEW)
endif ()
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24")
cmake_policy(SET CMP0135 NEW)
endif ()
# -------------------------------------------------------------------------------- #
# Metall general configuration
# -------------------------------------------------------------------------------- #
project(Metall
VERSION 0.28
DESCRIPTION "A persistent memory allocator for data-centric analytics"
HOMEPAGE_URL "https://github.com/LLNL/metall")
configure_file(MetallConfig.h.in MetallConfig.h)
# ----- Setting up a INTERFACE library to install header files ----- #
include(GNUInstallDirs)
add_library(${PROJECT_NAME} INTERFACE)
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
target_include_directories(${PROJECT_NAME}
INTERFACE $<BUILD_INTERFACE:${${PROJECT_NAME}_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}_Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(EXPORT ${PROJECT_NAME}_Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/metall DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# -------------------------------------------------------------------------------- #
# Generate and install the package configuration and package version files
# -------------------------------------------------------------------------------- #
include(CMakePackageConfigHelpers)
# generate the version file for the config file
write_basic_package_version_file(
"${PROJECT_NAME}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY ExactVersion)
# create config file
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
# install config files
install(FILES
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Configuration for building test, benchmark, example, etc.
# ----------
# User configurable options
# -------------------------------------------------------------------------------- #
option(JUST_INSTALL_METALL_HEADER "Just install Metall header files (do not build anything)" OFF)
option(BUILD_UTILITY "Build utility programs" OFF)
option(BUILD_DOC "Build API documentation" OFF)
option(BUILD_C "Build C examples and libraries" OFF)
option(BUILD_EXAMPLE "Build the examples" OFF)
option(BUILD_TEST "Build the test" OFF)
option(RUN_LARGE_SCALE_TEST "Run large scale tests" OFF)
option(RUN_BUILD_AND_TEST_WITH_CI "Perform build and basic test with CI" OFF)
option(BUILD_BENCH "Build the benchmark" OFF)
option(BUILD_VERIFICATION "Build verification programs" OFF)
set(COMPILER_DEFS "" CACHE STRING "A list of Metall compile definitions to be added to all targets")
# ---------- Experimental options ---------- #
set(UMAP_ROOT "" CACHE PATH "UMap installed root directory")
set(PRIVATEER_ROOT "" CACHE PATH "Privateer installed root directory")
option(ONLY_DOWNLOAD_GTEST "Only downloading Google Test" OFF)
option(SKIP_DOWNLOAD_GTEST "Skip downloading Google Test" OFF)
option(BUILD_NUMA "Build programs that require the NUMA policy library (numa.h)" OFF)
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Only downloading Google Test
# -------------------------------------------------------------------------------- #
if (ONLY_DOWNLOAD_GTEST)
add_subdirectory(test)
return()
endif ()
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Exit before building anything
# -------------------------------------------------------------------------------- #
if (INSTALL_HEADER_ONLY)
message(WARNING "INSTALL_HEADER_ONLY option has been replaced with JUST_INSTALL_METALL_HEADER.")
endif ()
if (JUST_INSTALL_METALL_HEADER)
return()
endif ()
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Exit CMake if there is nothing to build
# -------------------------------------------------------------------------------- #
if (NOT (BUILD_UTILITY OR BUILD_C OR BUILD_EXAMPLE OR BUILD_BENCH OR BUILD_TEST OR BUILD_VERIFICATION OR RUN_BUILD_AND_TEST_WITH_CI OR BUILD_DOC))
return()
endif ()
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Document (Doxygen)
# -------------------------------------------------------------------------------- #
if (BUILD_DOC)
include(build_doc)
build_doc()
endif ()
# -------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------- #
# Set up for building executables
# -------------------------------------------------------------------------------- #
# Requirements for GCC
if (NOT RUN_BUILD_AND_TEST_WITH_CI)
if (("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"))
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.1)
message(FATAL_ERROR "GCC version must be at least 8.1")
endif ()
endif ()
endif ()
# ---------- Metall Macros ---------- #
foreach (X ${COMPILER_DEFS})
message(STATUS "Metall compile definition: ${X}")
endforeach ()
# ---------- CMAKE_BUILD_TYPE ---------- #
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
message(STATUS "CMAKE_BUILD_TYPE is set as Release")
endif ()
# ---------- Threads ---------- #
find_package(Threads REQUIRED)
# ---------- filesystem ---------- #
include(check_cxx_filesystem_library)
check_cxx_filesystem_library()
# ---------- UMap ---------- #
if (UMAP_ROOT)
if (UNIX AND NOT APPLE)
find_library(LIBUMAP NAMES umap PATHS ${UMAP_ROOT}/lib)
endif ()
endif ()
# ---------- Privateer ---------- #
if (PRIVATEER_ROOT)
message(STATUS "Privateer Root is: ${PRIVATEER_ROOT}")
find_library(LIBPRIVATEER NAMES privateer PATHS ${PRIVATEER_ROOT}/lib)
endif ()
# ---------- Boost ---------- #
# Disable the boost-cmake feature (BoostConfig.cmake or boost-config.cmake) since
# there is a tricky behavior/issue especially in Boost 1.70.0.
set(Boost_NO_BOOST_CMAKE ON)
find_package(Boost 1.64 QUIET)
if (NOT Boost_FOUND)
FetchContent_Declare(Boost
URL https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2)
FetchContent_GetProperties(Boost)
if (NOT Boost_POPULATED)
FetchContent_Populate(Boost)
endif ()
set(BOOST_ROOT ${boost_SOURCE_DIR})
find_package(Boost 1.64)
endif ()
# -------------------------------------------------------------------------------- #
# Add executable functions
# -------------------------------------------------------------------------------- #
function(add_common_compile_options name)
# Common
target_compile_options(${name} PRIVATE -Wall)
# Debug
target_compile_options(${name} PRIVATE $<$<CONFIG:Debug>:-Og>)
target_compile_options(${name} PRIVATE $<$<CONFIG:Debug>:-g3>)
target_compile_options(${name} PRIVATE $<$<CONFIG:Debug>:-Wextra>)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_compile_options(${name} PRIVATE $<$<CONFIG:Debug>:-pg>)
endif ()
# Release
target_compile_options(${name} PRIVATE $<$<CONFIG:Release>:-Ofast>)
target_compile_options(${name} PRIVATE $<$<CONFIG:Release>:-DNDEBUG>)
# Release with debug info
target_compile_options(${name} PRIVATE $<$<CONFIG:RelWithDebInfo>:-Ofast>)
target_compile_options(${name} PRIVATE $<$<CONFIG:RelWithDebInfo>:-g3>)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_compile_options(${name} PRIVATE $<$<CONFIG:RelWithDebInfo>:-pg>)
endif ()
endfunction()
function(common_setup_for_metall_executable name)
target_include_directories(${name} PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(${name} PRIVATE Threads::Threads)
# ----- Compile Options ----- #
add_common_compile_options(${name})
# Memo:
# On macOS and FreeBSD libc++ is the default standard library and the -stdlib=libc++ is not required.
# https://libcxx.llvm.org/docs/UsingLibcxx.html
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND
NOT (CMAKE_CXX_COMPILER_ID MATCHES "Darwin" OR CMAKE_CXX_COMPILER_ID MATCHES "FreeBSD"))
target_compile_options(${name} PRIVATE -stdlib=libc++)
endif ()
# --------------------
# ----- Compile Definitions ----- #
foreach (X ${COMPILER_DEFS})
target_compile_definitions(${name} PRIVATE ${X})
endforeach ()
# --------------------
# ----- CXX17 Filesystem Lib----- #
# GNU compilers prior to 9.1 requires linking with stdc++fs
if (("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"))
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1)
target_link_libraries(${name} PRIVATE stdc++fs)
endif ()
endif ()
# --------------------
# ----- Umap----- #
if (UMAP_ROOT)
target_include_directories(${name} PRIVATE ${UMAP_ROOT}/include)
if (LIBUMAP)
target_link_libraries(${name} PRIVATE ${LIBUMAP})
target_compile_definitions(${name} PRIVATE "METALL_USE_UMAP")
endif ()
endif ()
# --------------------
# ----- Privateer----- #
if (PRIVATEER_ROOT)
target_include_directories(${name} PRIVATE ${PRIVATEER_ROOT}/include)
if (LIBPRIVATEER)
# 1) Privateer Dependencies
FIND_PACKAGE(OpenSSL)
if (OpenSSL_FOUND)
target_link_libraries(${name} PRIVATE OpenSSL::SSL)
target_link_libraries(${name} PRIVATE OpenSSL::Crypto)
endif ()
target_link_libraries(${name} PRIVATE rt)
FIND_PACKAGE(OpenMP REQUIRED)
if (OpenMP_CXX_FOUND)
target_link_libraries(${name} PRIVATE OpenMP::OpenMP_CXX)
else ()
message(FATAL_ERROR "OpenMP is required to build Metall with Privateer")
endif ()
if (ZSTD_ROOT)
find_library(LIBZSTD NAMES zstd PATHS ${ZSTD_ROOT}/lib)
target_include_directories(${name} PRIVATE ${ZSTD_ROOT}/lib)
target_link_libraries(${name} PRIVATE ${LIBZSTD})
target_compile_definitions(${name} PRIVATE USE_COMPRESSION)
endif ()
# 2) Link Privateer
target_link_libraries(${name} PRIVATE ${LIBPRIVATEER})
target_compile_definitions(${name} PRIVATE METALL_USE_PRIVATEER)
endif ()
endif ()
# --------------------
endfunction()
function(add_metall_executable name source)
set(ADDED_METALL_EXE FALSE PARENT_SCOPE) # Tell the caller if an executable is added w/o issue
if (Boost_FOUND)
add_executable(${name} ${source})
target_include_directories(${name} PRIVATE ${PROJECT_SOURCE_DIR}/include)
common_setup_for_metall_executable(${name})
set(ADDED_METALL_EXE TRUE PARENT_SCOPE)
endif ()
endfunction()
function(add_c_executable name source)
add_executable(${name} ${source})
add_common_compile_options(${name})
endfunction()
# -------------------------------------------------------------------------------- #
# Build tree
# -------------------------------------------------------------------------------- #
add_subdirectory(src)
if (BUILD_EXAMPLE)
add_subdirectory(example)
endif ()
if (BUILD_BENCH)
add_subdirectory(bench)
endif ()
if (BUILD_TEST)
enable_testing()
add_subdirectory(test)
endif ()
if (BUILD_VERIFICATION)
add_subdirectory(verification)
endif ()