forked from xnvme/xnvme
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
484 lines (414 loc) · 14.2 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
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
cmake_minimum_required(VERSION 3.9)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
project(xnvme
LANGUAGES C CXX
VERSION 0.0.19
)
message( STATUS "XNVME_VERSION: ${PROJECT_VERSION}" )
set(CMAKE_C_STANDARD 11)
include(FeatureSummary)
include(CheckCCompilerFlag)
include(CheckLibraryExists)
include(CheckFunctionExists)
include(CheckIPOSupported)
include(bundle_libs)
if(NOT CMAKE_C_COMPILER_ID MATCHES "^(GNU|clang)$")
message( "" )
message( WARNING "You are using an untested toolchain" )
message( " The GNU toolchain is preferred on Linux" )
message( " The clang toolchain is preffered on FreeBSD" )
message( " You are in uncharted territory!" )
message( " Make sure you set CC and CXX" )
message( "" )
message( " CC=gcc CXX=g++ ./configure --enable-<options>" )
message( " AND" )
message( " make CC=gcc CXX=g++" )
message( "" )
message( "" )
endif()
function(enable_c_flag flag)
string(FIND "${CMAKE_C_FLAGS}" "${flag}" flag_already_set)
if(flag_already_set EQUAL -1)
check_c_compiler_flag("${flag}" flag_supported)
if(flag_supported)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE)
endif()
endif()
endfunction()
enable_c_flag("-std=gnu11")
enable_c_flag("-Wall")
enable_c_flag("-Wextra")
enable_c_flag("-Werror")
# Due to a bug in clang
enable_c_flag("-Wno-missing-braces")
# For gprof traces
#enable_c_flag("-pg")
# NOTE: Cannot enable this due to third-party using non-ISO features
#enable_c_flag("-pedantic")
find_package(bash-completion QUIET)
message( STATUS "BASH_COMPLETION_FOUND: '${BASH_COMPLETION_FOUND}'" )
message( STATUS "BASH_COMPLETION_COMPLETIONSDIR: '${BASH_COMPLETION_COMPLETIONSDIR}'" )
# Find pthreads
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
check_ipo_supported(RESULT IPO_SUPPORTED)
check_ipo_supported(RESULT result OUTPUT output)
if(IPO_SUPPORTED)
set(HAS_IPO TRUE)
else()
set(HAS_IPO FALSE)
endif()
if(CMAKE_SYSTEM MATCHES "Linux")
set(FREEBSD 0)
set(LINUX 1)
elseif(CMAKE_SYSTEM MATCHES "FreeBSD")
set(FREEBSD 1)
set(LINUX 0)
else()
set(FREEBSD 0)
set(LINUX 0)
endif()
message( STATUS "CMAKE_INTERPROCEDURAL_OPTIMIZATION: '${CMAKE_INTERPROCEDURAL_OPTIMIZATION}'" )
message( STATUS "IPO_SUPPORTED: '${IPO_SUPPORTED}'" )
message( STATUS "HAS_IPO: '${HAS_IPO}'" )
message( STATUS "CMAKE_C_FLAGS: '${CMAKE_C_FLAGS}'" )
message( STATUS "CMAKE_SYSTEM: '${CMAKE_SYSTEM}'" )
message( STATUS "CMAKE_SYSTEM_NAME: '${CMAKE_SYSTEM_NAME}'" )
message( STATUS "CMAKE_HOST_SYSTEM_NAME: '${CMAKE_HOST_SYSTEM_NAME}'" )
message( STATUS "CMAKE_C_COMPILER_AR: '${CMAKE_C_COMPILER_AR}'" )
message( STATUS "CMAKE_AR: '${CMAKE_AR}'" )
message( STATUS "UNIX(${UNIX}), FREEBSD(${FREEBSD}), LINUX(${LINUX}), WIN32(${WIN32})" )
if(WIN32)
add_definitions(-D__USE_MINGW_ANSI_STDIO=1)
endif()
#
# Check for struct timespec ts and clock_gettime
#
check_library_exists(c clock_gettime "" LIBC_HAS_CLOCK_GETTIME)
check_library_exists(rt clock_gettime "time.h" LIBRT_HAS_CLOCK_GETTIME)
# On Windows we assume it is available via the TDM-GCC compiler suite
if(WIN32)
message( WARNING "Skipping check for clock_gettime..." )
else ()
if((NOT LIBC_HAS_BLOCK_GETTIME) AND (NOT LIBRT_HAS_CLOCK_GETTIME))
message( FATAL_ERROR "Cannot find clock_gettime" )
endif()
endif()
# Add versioning
add_definitions(-DXNVME_VERSION_MAJOR=${PROJECT_VERSION_MAJOR})
add_definitions(-DXNVME_VERSION_MINOR=${PROJECT_VERSION_MINOR})
add_definitions(-DXNVME_VERSION_PATCH=${PROJECT_VERSION_PATCH})
add_definitions(-DXNVME_VERSION=${PROJECT_VERSION})
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DXNVME_DEBUG_ENABLED")
set(XNVME_TRACE_ENABLED FALSE CACHE BOOL "Enable NVMe command tracing")
if(XNVME_TRACE_ENABLED)
add_definitions(-DXNVME_TRACE_ENABLED)
endif()
#
# NOTE: CMake prefers that filenames are hard-coded in CMakeLists.txt and not
# globbed as it cannot detect, in the build-files genereated by CMake, when a
# new file is added. However, it seems that value of that feature is less than
# the convenience file-globbing.
#
file(GLOB PUBLIC_FILES ${PROJECT_SOURCE_DIR}/include/lib*.h)
file(GLOB INTERNAL_FILES ${PROJECT_SOURCE_DIR}/include/xnvme_*.h)
file(GLOB SOURCE_FILES ${PROJECT_SOURCE_DIR}/src/*.c)
include_directories("${PROJECT_SOURCE_DIR}/include")
# Default 'clang' on FreeBSD does not look here, so we tell it to probably
# another symptom of 'base-system-compiler-we-do-not-care'
link_directories("/usr/local/lib")
#
# LIBS are the libraries which are "submoduled" by xNVMe and linked statically,
# and for the bundled version of the library embedded in the archive
#
list(APPEND LIBS "")
#
# AUX_LIB_PATHS non-system paths to search for libraries, search for 'LIBS here
#
list(APPEND AUX_LIB_PATHS "")
#
# LIBS_STATIC to be populated with absolute paths to 'LIBS' for bundling
#
list(APPEND LIBS_STATIC "")
#
# LIBS_SYSTEM are libraries which are expected to be available on the system on
# which xNVMe is built and at runtime when using the shared version of xNVMe
#
list(APPEND LIBS_SYSTEM Threads::Threads)
#
# BACKENDS -- begin
#
#
# XNVME_BE_SPDK
#
set(XNVME_BE_SPDK_ENABLED ${UNIX} CACHE BOOL "be_spdk: SPDK backend")
set(XNVME_BE_SPDK_TRANSPORT_PCIE_ENABLED ${UNIX} CACHE BOOL "be:spdk: PCIe Transport")
set(XNVME_BE_SPDK_TRANSPORT_TCP_ENABLED ${UNIX} CACHE BOOL "be:spdk: TCP Transport")
set(XNVME_BE_SPDK_TRANSPORT_RDMA_ENABLED ${UNIX} CACHE BOOL "be:spdk: RDMA Transport")
set(XNVME_BE_SPDK_TRANSPORT_FC_ENABLED ${UNIX} CACHE BOOL "be:spdk: FC Transport")
set(SPDK_REPOS
"${PROJECT_SOURCE_DIR}/third-party/spdk/repos"
CACHE PATH "SPDK Repository path")
set(SPDK_INCLUDE_PATH
"${SPDK_REPOS}/build/include"
CACHE PATH "SPDK include path")
set(SPDK_LIBRARY_PATH
"${SPDK_REPOS}/build/lib"
CACHE PATH "SPDK library path")
set(DPDK_INCLUDE_PATH
"${SPDK_REPOS}/dpdk/build/include"
CACHE PATH "DPDK include path")
set(DPDK_LIBRARY_PATH
"${SPDK_REPOS}/dpdk/build/lib"
CACHE PATH "DPDK library path")
if(XNVME_BE_SPDK_ENABLED)
message( STATUS "SPDK_LIBRARY_PATH(${SPDK_LIBRARY_PATH})" )
message( STATUS "SPDK_INCLUDE_PATH(${SPDK_INCLUDE_PATH})" )
message( STATUS "DPDK_LIBRARY_PATH(${DPDK_LIBRARY_PATH})" )
message( STATUS "DPDK_INCLUDE_PATH(${DPDK_INCLUDE_PATH})" )
# Fetch SPDK/DPDK if it is not there
if(NOT EXISTS "${SPDK_INCLUDE_PATH}")
message( STATUS "Preparing SPDK/DPDK" )
execute_process(
COMMAND make third-party-update
RESULT_VARIABLE res
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
if(res)
message( FATAL_ERROR "Failed fetching SPDK/DPDK" )
endif()
endif()
# Build SPDK/DPDK if SPDK libraries are not there
if(NOT EXISTS "${SPDK_LIBRARY_PATH}/libspdk_nvme.a")
message( STATUS "Preparing SPDK/DPDK dependency" )
message( STATUS "Patching SPDK/DPDK" )
execute_process(
COMMAND make third-party-spdk-patch
RESULT_VARIABLE res
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
if(res)
message( FATAL_ERROR "Failed patching SPDK/DPDK" )
endif()
message( STATUS "Configuring SPDK/DPDK" )
execute_process(
COMMAND make third-party-spdk-configure
RESULT_VARIABLE res
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
if(res)
message( FATAL_ERROR "Failed configuring SPDK/DPDK" )
endif()
message( STATUS "Building SPDK/DPDK" )
execute_process(
COMMAND make third-party-spdk-build
RESULT_VARIABLE res
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
if(res)
message( FATAL_ERROR "Failed building SPDK/DPDK" )
endif()
endif()
add_definitions(-DXNVME_BE_SPDK_ENABLED)
if(XNVME_BE_SPDK_TRANSPORT_PCIE_ENABLED)
add_definitions(-DXNVME_BE_SPDK_TRANSPORT_PCIE_ENABLED)
endif()
if(XNVME_BE_SPDK_TRANSPORT_TCP_ENABLED)
add_definitions(-DXNVME_BE_SPDK_TRANSPORT_TCP_ENABLED)
endif()
if(XNVME_BE_SPDK_TRANSPORT_RDMA_ENABLED)
add_definitions(-DXNVME_BE_SPDK_TRANSPORT_RDMA_ENABLED)
endif()
if(XNVME_BE_SPDK_TRANSPORT_FC_ENABLED)
add_definitions(-DXNVME_BE_SPDK_TRANSPORT_FC_ENABLED)
endif()
message( STATUS "ENABLING ASYNC SUPPORT" )
add_definitions(-DXNVME_ASYNC_ENABLED)
# These are expected to be available on the system
list(APPEND LIBS_SYSTEM rt)
if (LINUX)
list(APPEND LIBS_SYSTEM numa)
elseif (FREEBSD)
list(APPEND LIBS_SYSTEM execinfo)
list(APPEND LIBS_SYSTEM elf)
endif()
list(APPEND LIBS_SYSTEM uuid)
#
# Must be built and available in SPDK_LIBRARY_PATH
#
list(APPEND LIBS spdk_nvme)
list(APPEND LIBS spdk_env_dpdk)
list(APPEND LIBS spdk_sock)
list(APPEND LIBS spdk_sock_posix)
list(APPEND LIBS spdk_rpc)
list(APPEND LIBS spdk_jsonrpc)
list(APPEND LIBS spdk_json)
list(APPEND LIBS spdk_util)
list(APPEND LIBS spdk_log)
#
# Must available in DPDK_LIBRARY_PATH
#
list(APPEND LIBS rte_eal)
list(APPEND LIBS rte_telemetry)
list(APPEND LIBS rte_bus_pci)
list(APPEND LIBS rte_pci)
list(APPEND LIBS rte_ring)
list(APPEND LIBS rte_mempool)
list(APPEND LIBS rte_kvargs)
include_directories("${SPDK_INCLUDE_PATH}")
include_directories("${DPDK_INCLUDE_PATH}")
link_directories("${SPDK_LIBRARY_PATH}")
link_directories("${DPDK_LIBRARY_PATH}")
list(APPEND AUX_LIB_PATHS ${SPDK_LIBRARY_PATH})
list(APPEND AUX_LIB_PATHS ${DPDK_LIBRARY_PATH})
endif()
message( STATUS "BE:SPDK ENABLED(${XNVME_BE_SPDK_ENABLED})" )
#
# XNVME_BE_FIOC
#
set(XNVME_BE_FIOC_ENABLED ${FREEBSD} CACHE BOOL "be_fioc: FreeBSD/IOCTL backend")
if(XNVME_BE_FIOC_ENABLED)
add_definitions(-DXNVME_BE_FIOC_ENABLED)
endif()
message( STATUS "BE:FIOC ENABLED(${XNVME_BE_FIOC_ENABLED})" )
#
# XNVME_BE_LIOC
#
set(XNVME_BE_LIOC_ENABLED ${LINUX} CACHE BOOL "be_lioc: Linux/IOCTL backend")
if(XNVME_BE_LIOC_ENABLED)
add_definitions(-DXNVME_BE_LIOC_ENABLED)
endif()
message( STATUS "BE:LIOC ENABLED(${XNVME_BE_LIOC_ENABLED})" )
#
# XNVME_BE_LIOU
#
set(XNVME_BE_LIOU_ENABLED ${LINUX} CACHE BOOL "be_liou: Linux/io_uring backend")
set(LIBURING_REPOS "${PROJECT_SOURCE_DIR}/third-party/liburing/repos")
set(LIBURING_INCLUDE_PATH
"${LIBURING_REPOS}/src/include"
CACHE PATH "LIBURING include path")
set(LIBURING_LIBRARY_PATH
"${LIBURING_REPOS}/src"
CACHE PATH "LIBURING library path")
if(XNVME_BE_LIOU_ENABLED)
message( STATUS "LIBURING_LIBRARY_PATH(${LIBURING_LIBRARY_PATH})" )
message( STATUS "LIBURING_INCLUDE_PATH(${LIBURING_INCLUDE_PATH})" )
if(NOT (EXISTS ${LIBURING_LIBRARY_PATH} AND
EXISTS ${LIBURING_INCLUDE_PATH}))
execute_process(
COMMAND make third-party-update
RESULT_VARIABLE res
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
if(res)
message( FATAL_ERROR "Failed fetching liburing" )
endif()
endif()
if(NOT EXISTS "${LIBURING_LIBRARY_PATH}/liburing.a")
execute_process(
COMMAND make third-party-liburing-build
RESULT_VARIABLE res
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
if(res)
message( FATAL_ERROR "Failed building liburing" )
endif()
endif()
add_definitions(-DXNVME_BE_LIOU_ENABLED)
message( STATUS "ENABLING ASYNC SUPPORT" )
add_definitions(-DXNVME_ASYNC_ENABLED)
list(APPEND LIBS uring)
# Add liburing to library and include
include_directories("${LIBURING_INCLUDE_PATH}")
link_directories("${LIBURING_LIBRARY_PATH}")
list(APPEND AUX_LIB_PATHS ${LIBURING_LIBRARY_PATH})
endif()
message( STATUS "BE:LIOU ENABLED(${XNVME_BE_LIOU_ENABLED})" )
#
# XNVME_BE_LAIO
#
set(XNVME_BE_LAIO_ENABLED ${LINUX} CACHE BOOL "be_laio: Linux/libaio backend")
if(XNVME_BE_LAIO_ENABLED)
add_definitions(-DXNVME_BE_LAIO_ENABLED)
list(APPEND LIBS_SYSTEM aio)
message( STATUS "ENABLING ASYNC SUPPORT" )
add_definitions(-DXNVME_ASYNC_ENABLED)
endif()
message( STATUS "BE:LAIO ENABLED(${XNVME_BE_LAIO_ENABLED})" )
#
# BACKENDS -- end
#
# Find the static version of LIBS
foreach(lib IN LISTS LIBS)
unset(lib_path CACHE)
find_library(lib_path
NAMES "lib${lib}.a"
PATHS ${AUX_LIB_PATHS}
)
list(APPEND LIBS_STATIC "${lib_path}")
endforeach()
message( STATUS "LIBS(${LIBS})" )
message( STATUS "LIBS_STATIC(${LIBS_STATIC})" )
message( STATUS "LIBS_SYSTEM(${LIBS_SYSTEM})" )
#
# The xNVMe library incantations: shared, static, and "bundled"
#
set(LIB_SHARED "${PROJECT_NAME}-shared")
set(LIB_STATIC "${PROJECT_NAME}-static")
set(LIB_STATIC_FN "${CMAKE_STATIC_LIBRARY_PREFIX}${LIB_STATIC}${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(LIB_BUNDLE "${PROJECT_NAME}")
# Static library
add_library(${LIB_STATIC} STATIC ${PUBLIC_FILES} ${INTERNAL_FILES} ${SOURCE_FILES})
set_target_properties(${LIB_STATIC} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION HAS_IPO
)
target_compile_options(${LIB_STATIC} PUBLIC -fPIC)
target_link_libraries(${LIB_STATIC} ${LIBS})
target_link_libraries(${LIB_STATIC} ${LIBS_SYSTEM})
install(TARGETS ${LIB_STATIC} DESTINATION lib COMPONENT dev)
# Bundled library
list(APPEND BUNDLED_LIBS ${LIB_STATIC_FN})
list(APPEND BUNDLED_LIBS ${LIBS_STATIC})
message( STATUS "BUNDLED_LIBS(${BUNDLED_LIBS})" )
bundle_libs("${LIB_STATIC}" "${LIB_BUNDLE}")
message(STATUS "bundle_libs(${BUNDLE_LIBS})")
if(NOT "${BUNDLE_LIBS}" STREQUAL "SUCCESS")
message( FATAL_ERROR "bundling libs failed" )
endif()
# Shared library
add_library(${LIB_SHARED} SHARED ${PUBLIC_FILES} ${INTERNAL_FILES} ${SOURCE_FILES})
set_target_properties(${LIB_SHARED} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION HAS_IPO
)
target_compile_options(${LIB_SHARED} PUBLIC -fPIC)
target_link_libraries(${LIB_SHARED} ${LIBS})
target_link_libraries(${LIB_SHARED} ${LIBS_SYSTEM})
install(TARGETS ${LIB_SHARED} DESTINATION lib COMPONENT dev)
install(FILES ${PUBLIC_FILES} DESTINATION include COMPONENT dev)
add_subdirectory(examples)
add_subdirectory(tests)
add_subdirectory(tools)
add_subdirectory(tools/fio-engine)
#
# Packages
#
if(WIN32)
set(CPACK_GENERATOR "NSIS" "ZIP")
else()
set(CPACK_GENERATOR "TGZ" "DEB")
endif()
#set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_PACKAGE_VERSION "${PROJECT_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}")
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${PROJECT_VERSION}.bin")
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Simon A. F. Lund")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
set(CPACK_COMPONENT_DEV_DESCRIPTION "xnvme-dev: headers and libraries for xNVMe APIs")
if(TOOLS)
set(CPACK_COMPONENT_TOOLS_DESCRIPTION "xnvme-tools: suite of xNVMe command-line tools")
endif()
if(EXAMPLES)
set(CPACK_COMPONENT_EXAMPLES_DESCRIPTION "xnvme-examples: xNVMe examples provided as binaries")
endif()
if(TESTS)
set(CPACK_COMPONENT_TESTS_DESCRIPTION "xnvme-tests: xNVMe test programs")
endif()
include(CPack)