-
Notifications
You must be signed in to change notification settings - Fork 71
/
CMakeGlobalSettings.cmake
378 lines (311 loc) · 14.4 KB
/
CMakeGlobalSettings.cmake
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
### enable testing
enable_testing()
### enable ccache if available
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)
### set general cmake settings
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
### set boost settings
add_definitions(-DBOOST_ALL_DYN_LINK)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
### detect signature scheme
if(USE_KECCAK AND USE_REVERSED_PRIVATE_KEYS)
add_definitions(-DSIGNATURE_SCHEME_NIS1)
elseif(NOT USE_KECCAK AND NOT USE_REVERSED_PRIVATE_KEYS)
add_definitions(-DSIGNATURE_SCHEME_CATAPULT)
else()
message(FATAL_ERROR "unsupported signature scheme specified - please check USE_KECCAK and USE_REVERSED_PRIVATE_KEYS options")
endif()
### forward docker build settings
if(CATAPULT_TEST_DB_URL)
add_definitions(-DCATAPULT_TEST_DB_URL="${CATAPULT_TEST_DB_URL}")
endif()
if(CATAPULT_DOCKER_TESTS)
add_definitions(-DCATAPULT_DOCKER_TESTS)
endif()
### set compiler settings
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /EHsc")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD /Zi")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd /D_SCL_SECURE_NO_WARNINGS")
# disable: "marked as __forceinline not inlined"
add_definitions(-D_WIN32_WINNT=0x0601 /wd4714 /w44287 /w44388)
# explicitly disable linking against static boost libs
add_definitions(-DBOOST_ALL_NO_LIB)
# min/max macros are useless
add_definitions(-DNOMINMAX)
add_definitions(-DWIN32_LEAN_AND_MEAN)
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
if("${CMAKE_BUILD_TYPE}" MATCHES "Release")
# - Wno-maybe-uninitialized: false positives where gcc isn't sure if an uninitialized variable is used or not
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized")
endif()
# add memset_s
add_definitions(-D_STDC_WANT_LIB_EXT1_=1)
add_definitions(-D__STDC_WANT_LIB_EXT1__=1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
# - Wno-c++98-compat*: catapult is not compatible with C++98
# - Wno-disabled-macro-expansion: expansion of recursive macro is required for boost logging macros
# - Wno-padded: allow compiler to automatically pad data types for alignment
# - Wno-switch-enum: do not require enum switch statements to list every value (this setting is also incompatible with GCC warnings)
# - Wno-weak-vtables: vtables are emitted in all translsation units for virtual classes with no out-of-line virtual method definitions
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-std=c++11 -stdlib=libc++ \
-Weverything \
-Werror \
-Wno-c++98-compat \
-Wno-c++98-compat-pedantic \
-Wno-disabled-macro-expansion \
-Wno-padded \
-Wno-switch-enum \
-Wno-weak-vtables")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
endif()
# set runpath for built binaries on linux
if(("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Linux"))
file(MAKE_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/boost")
set(CMAKE_SKIP_BUILD_RPATH FALSE)
# $origin - to load plugins when running the server
# $origin/boost - same, use our boost libs
set(CMAKE_INSTALL_RPATH "$ORIGIN:$ORIGIN/boost${CMAKE_INSTALL_RPATH}")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# use rpath for executables
# (executable rpath will be used for loading indirect libs, this is needed because boost libs do not set runpath)
# use newer runpath for shared libs
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--enable-new-dtags")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--disable-new-dtags")
endif()
if(USE_SANITATION)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
endif()
### define gtest helper functions
# find and set gtest includes
function(catapult_add_gtest_dependencies)
find_package(GTest REQUIRED)
include_directories(SYSTEM ${GTEST_INCLUDE_DIR})
endfunction()
# sets additional compiler options for test projects in order to quiet GTEST warnings while allowing source warning checks to be stricter
function(catapult_set_test_compiler_options)
# some gtest workarounds for gcc + clang
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
# - Wno-dangling-else: workaround for GTEST ambiguous else blocker not working https://github.com/google/googletest/issues/1119
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-Wno-dangling-else"
PARENT_SCOPE)
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
# - Wno-global-constructors: required for GTEST test definition macros
# - Wno-zero-as-null-pointer-constant: workaround for GTEST NULL/nullptr mismatch https://github.com/google/googletest/issues/1323
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-Wno-global-constructors \
-Wno-zero-as-null-pointer-constant"
PARENT_SCOPE)
endif()
endfunction()
### define version helpers
# set CATAPULT_VERSION_DESCRIPTION to a reasonable value
if(NOT CATAPULT_BUILD_DEVELOPMENT)
# extract version information from git
execute_process(
COMMAND git rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(
COMMAND git log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(CATAPULT_BUILD_RELEASE)
set(CATAPULT_VERSION_DESCRIPTION "(public)")
else()
set(CATAPULT_VERSION_DESCRIPTION "${GIT_COMMIT_HASH} [${GIT_BRANCH}]")
endif()
endif()
if(MSVC)
function(set_win_version_definitions WIN_TARGET_NAME WIN_FILETYPE)
add_definitions(-DCATAPULT_VERSION_DESCRIPTION="${CATAPULT_VERSION_DESCRIPTION}")
add_definitions(-DWIN_TARGET_NAME=${WIN_TARGET_NAME})
add_definitions(-DWIN_FILETYPE=${WIN_FILETYPE})
if(CATAPULT_BUILD_RELEASE)
add_definitions(-DCATAPULT_BUILD_RELEASE=1)
endif()
endfunction()
# embed the version rc file
set(VERSION_RESOURCES ${CMAKE_SOURCE_DIR}/src/catapult/version/win/win_version.rc)
else()
# since strings are not referenced, in order for the linker to include them, they must be forcibly linked via an object file
set(VERSION_RESOURCES $<TARGET_OBJECTS:catapult.version.nix>)
endif()
### define target helper functions
# used to define a catapult target (library, executable) and automatically enables PCH for clang
function(catapult_target TARGET_NAME)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 14)
# indicate boost as a dependency
target_link_libraries(${TARGET_NAME} ${Boost_LIBRARIES})
# copy boost shared libraries
foreach(BOOST_COMPONENT ATOMIC SYSTEM DATE_TIME REGEX TIMER CHRONO LOG THREAD FILESYSTEM PROGRAM_OPTIONS)
if(MSVC)
# copy into ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(Configuration)
string(REPLACE ".lib" ".dll" BOOSTDLLNAME ${Boost_${BOOST_COMPONENT}_LIBRARY_RELEASE})
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${BOOSTDLLNAME}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(Configuration)")
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
# copy into ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/boost
set(BOOSTDLLNAME ${Boost_${BOOST_COMPONENT}_LIBRARY_RELEASE})
set(BOOSTVERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
get_filename_component(BOOSTFILENAME ${BOOSTDLLNAME} NAME)
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${BOOSTDLLNAME}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/boost")
endif()
endforeach()
# put both plugins and plugins tests in same 'folder'
if(TARGET_NAME MATCHES "\.plugins")
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "plugins")
endif()
if(TARGET_NAME MATCHES "\.tools")
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "tools")
endif()
endfunction()
# finds all files comprising a target
function(catapult_find_all_target_files TARGET_TYPE TARGET_NAME)
if (CMAKE_VERBOSE_MAKEFILE)
message("processing ${TARGET_TYPE} '${TARGET_NAME}'")
endif()
file(GLOB ${TARGET_NAME}_INCLUDE_SRC "*.h")
file(GLOB ${TARGET_NAME}_SRC "*.cpp")
set(CURRENT_FILES ${${TARGET_NAME}_INCLUDE_SRC} ${${TARGET_NAME}_SRC})
SOURCE_GROUP("src" FILES ${CURRENT_FILES})
set(TARGET_FILES ${CURRENT_FILES})
# add any (optional) subdirectories
foreach(arg ${ARGN})
set(SUBDIR ${arg})
if (CMAKE_VERBOSE_MAKEFILE)
message("+ processing subdirectory '${arg}'")
endif()
file(GLOB ${TARGET_NAME}_${SUBDIR}_INCLUDE_SRC "${SUBDIR}/*.h")
file(GLOB ${TARGET_NAME}_${SUBDIR}_SRC "${SUBDIR}/*.cpp")
set(CURRENT_FILES ${${TARGET_NAME}_${SUBDIR}_INCLUDE_SRC} ${${TARGET_NAME}_${SUBDIR}_SRC})
SOURCE_GROUP("${SUBDIR}" FILES ${CURRENT_FILES})
set(TARGET_FILES ${TARGET_FILES} ${CURRENT_FILES})
endforeach()
set(${TARGET_NAME}_FILES ${TARGET_FILES} PARENT_SCOPE)
endfunction()
# used to define a catapult library, creating an appropriate source group and adding a library
function(catapult_library TARGET_NAME)
catapult_find_all_target_files("lib" ${TARGET_NAME} ${ARGN})
if (ENABLE_STRESS)
if (NOT STRESS_COUNT)
set(STRESS_COUNT 100)
endif()
MESSAGE(STATUS "Enabling stress test for ${TARGET_NAME} (${STRESS_COUNT})")
add_definitions(-DSTRESS=${STRESS_COUNT})
endif()
add_library(${TARGET_NAME} ${${TARGET_NAME}_FILES})
endfunction()
# combines catapult_library and catapult_target
function(catapult_library_target TARGET_NAME)
catapult_library(${TARGET_NAME} ${ARGN})
set_property(TARGET ${TARGET_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON)
catapult_target(${TARGET_NAME})
endfunction()
# used to define a catapult shared library, creating an appropriate source group and adding a library
function(catapult_shared_library TARGET_NAME)
catapult_find_all_target_files("shared lib" ${TARGET_NAME} ${ARGN})
add_definitions(-DDLL_EXPORTS)
if(MSVC)
set_win_version_definitions(${TARGET_NAME} VFT_DLL)
endif()
add_library(${TARGET_NAME} SHARED ${${TARGET_NAME}_FILES} ${VERSION_RESOURCES})
endfunction()
# combines catapult_shared_library and catapult_target
function(catapult_shared_library_target TARGET_NAME)
catapult_shared_library(${TARGET_NAME} ${ARGN})
catapult_target(${TARGET_NAME})
endfunction()
# used to define a catapult executable, creating an appropriate source group and adding an executable
function(catapult_executable TARGET_NAME)
catapult_find_all_target_files("exe" ${TARGET_NAME} ${ARGN})
if(MSVC)
set_win_version_definitions(${TARGET_NAME} VFT_APP)
endif()
add_executable(${TARGET_NAME} ${${TARGET_NAME}_FILES} ${VERSION_RESOURCES})
if(WIN32 AND MINGW)
target_link_libraries(${TARGET_NAME} wsock32 ws2_32)
endif()
endfunction()
# used to define a catapult header only target, creating an appropriate source group in order to allow VS to create an appropriate folder
function(catapult_header_only_target TARGET_NAME)
if(MSVC)
catapult_find_all_target_files("hdr" ${TARGET_NAME} ${ARGN})
# unfortunately add_library INTERFACE doesn't seem to work
# http://stackoverflow.com/questions/5957134/how-to-setup-cmake-to-generate-header-only-projects
add_library(${TARGET_NAME} STATIC ${${TARGET_NAME}_FILES})
set_target_properties(${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX)
endif()
endfunction()
# used to define a catapult test executable
function(catapult_test_executable TARGET_NAME)
find_package(GTest REQUIRED)
include_directories(SYSTEM ${GTEST_INCLUDE_DIR})
catapult_executable(${TARGET_NAME} ${ARGN})
add_test(NAME ${TARGET_NAME} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${TARGET_NAME})
target_link_libraries(${TARGET_NAME} ${GTEST_LIBRARIES})
if (ENABLE_CODE_COVERAGE)
MESSAGE(STATUS "Enabling code coverage for ${TARGET_NAME}")
set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
target_link_libraries(${TARGET_NAME} gcov)
endif()
if (ENABLE_STRESS)
if (NOT STRESS_COUNT)
set(STRESS_COUNT 100)
endif()
MESSAGE(STATUS "Enabling stress test for ${TARGET_NAME} (${STRESS_COUNT})")
add_definitions(-DSTRESS=${STRESS_COUNT})
endif()
endfunction()
# used to define a catapult test executable for a catapult library by combining catapult_test_executable and
# catapult_target and adding some library dependencies
function(catapult_test_executable_target TARGET_NAME TEST_DEPENDENCY_NAME)
catapult_test_executable(${TARGET_NAME} ${ARGN})
# inline instead of calling catapult_add_gtest_dependencies in order to apply gtest dependencies to correct scope
find_package(GTest REQUIRED)
include_directories(SYSTEM ${GTEST_INCLUDE_DIR})
# customize and export compiler options for gtest
catapult_set_test_compiler_options()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE)
# test libraries are in the form test.xyz, so add xyz as a dependency (the library under test)
string(FIND ${TARGET_NAME} "." TEST_END_INDEX)
MATH(EXPR TEST_END_INDEX "${TEST_END_INDEX}+1")
string(SUBSTRING ${TARGET_NAME} ${TEST_END_INDEX} -1 LIBRARY_UNDER_TEST)
target_link_libraries(${TARGET_NAME} tests.catapult.test.${TEST_DEPENDENCY_NAME} ${LIBRARY_UNDER_TEST})
catapult_target(${TARGET_NAME})
endfunction()
# used to define a catapult test executable for a header only catapult library by combining catapult_test_executable and
# catapult_target and adding some library dependencies
function(catapult_test_executable_target_header_only TARGET_NAME TEST_DEPENDENCY_NAME)
catapult_test_executable(${TARGET_NAME} ${ARGN})
# customize and export compiler options for gtest
catapult_set_test_compiler_options()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE)
target_link_libraries(${TARGET_NAME} tests.catapult.test.${TEST_DEPENDENCY_NAME})
catapult_target(${TARGET_NAME})
endfunction()