-
Notifications
You must be signed in to change notification settings - Fork 7
/
CMakeLists.txt
298 lines (249 loc) · 10.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
cmake_minimum_required(VERSION 3.8)
project(tpl)
# The version number.
set(TPL_VERSION_MAJOR 0)
set(TPL_VERSION_MINOR 5)
# For external projects
include(CMakeParseArguments)
include(ExternalProject)
include(FindPkgConfig)
include(FetchContent)
# Let CMake know where all the modules are (i.e., in ./cmake)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
# Checks from terrier require these
set(BUILD_SUPPORT_DIR "${CMAKE_SOURCE_DIR}/build-support")
# LLVM and Clang versions
set(TPL_LLVM_VERSIONS "11" "10" "9")
set(TPL_CLANG_TOOLS_VERSIONS "11" "10" "9")
list(GET TPL_LLVM_VERSIONS 0 TPL_LLVM_VERSION)
list(GET TPL_CLANG_TOOLS_VERSIONS 0 TPL_CLANG_TOOLS_VERSION)
find_package(ClangTools)
if ("$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}" STREQUAL "1" OR CLANG_TIDY_FOUND)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
endif ()
# configure a header file to pass some of the CMake settings to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/tpl.h.in"
"${PROJECT_BINARY_DIR}/tpl.h"
)
############################################################
#
# Cmake Built Options
#
############################################################
option(TPL_USE_ASAN "Build TPL with AddressSanitizer enabled" OFF)
option(TPL_USE_TSAN "Build TPL with ThreadSanitizer enabled" OFF)
option(TPL_USE_LLD "Use LLVM's LLD linker if available" OFF)
option(TPL_COLORIZE_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." ON)
option(TPL_GENERATE_COVERAGE "Build TPL with code coverage enabled" OFF)
option(TPL_BUILD_DOC "Build Doxygen documentation" OFF)
option(TPL_VERBOSE_THIRDPARTY_BUILD "Verbose output when building third-party librares" OFF)
option(TPL_BUILD_BENCHMARKS "Build TPL benchmarks" ON)
# Is this MacOS ?
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(MACOSX TRUE)
endif()
# Use the first Python installation on PATH, not the newest one
set(Python3_FIND_STRATEGY "LOCATION")
# On Windows, use registry last, not first
set(Python3_FIND_REGISTRY "LAST")
# On macOS, use framework last, not first
set(Python3_FIND_FRAMEWORK "LAST")
find_package(Python3)
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
############################################################
#
# Compiler Options
#
############################################################
# Default to 'Release' if no build type is provided, but warn the user
if (NOT CMAKE_BUILD_TYPE)
message(WARNING "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release")
endif()
# Ensure dependencies
include(Dependencies)
# Setup the compiler and setup the compiler flags
include(SetupCompiler)
############################################################
#
# "make gen-cov" target
#
############################################################
add_custom_target(gen-cov
DEPENDS check check-tpl
COMMAND lcov --directory . --capture --output-file coverage.info && # capture coverage info
lcov --remove coverage.info '/usr/*' --output-file coverage.info # filter out system
--remove coverage.info '*/build/*' --output-file coverage.info # filter out build
--remove coverage.info '*/third_party/*' --output-file coverage.info # filter out third_party
--remove coverage.info '*/test/*' --output-file coverage.info # filter out test
--remove coverage.info '*/src/main/*' --output-file coverage.info && # filter out main
genhtml coverage.info --output-directory coverage-html
)
############################################################
#
# Checks from Terrier
#
############################################################
###########################################################
#
# "make check-lint" and "make check-censored" targets
#
###########################################################
if (UNIX)
file(GLOB_RECURSE LINT_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/test/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/test/*.cpp"
)
find_program(CPPLINT_BIN NAMES cpplint cpplint.py HINTS ${BUILD_SUPPORT_DIR})
message(STATUS "Found cpplint executable at ${CPPLINT_BIN}")
# Full lint
# Balancing act: cpplint.py takes a non-trivial time to launch,
# so process 12 files per invocation, while still ensuring parallelism
add_custom_target(check-lint echo '${LINT_FILES}' | xargs -n12 -P8
${CPPLINT_BIN}
--verbose=2 ${TERRIER_LINT_QUIET}
--linelength=120
--filter=-legal/copyright,-build/header_guard
)
set(CENSOR_FILES ${LINT_FILES})
# If whitelisting becomes necessary, do it here. Make it harder so that people try not to do it.
# list(REMOVE_ITEM CENSOR_FILES
#
# )
add_custom_target(check-censored
grep --invert-match -n -e '^ *//' -e '^ *[*]' ${CENSOR_FILES} # check all uncommented lines w/ line num
| grep -i -f ${BUILD_SUPPORT_DIR}/bad_words.txt # for bad words, not case sensitive
| grep --invert-match -e 'NOLINT' # the count of them that aren't NOLINT
|| exit 0 # if nothing found, return 0
&& exit 1 # else return 1, note || && left-associative
)
endif (UNIX)
###########################################################
#
# "make format" and "make check-format" targets
#
###########################################################
# we modified the format script to take multiple args
string(CONCAT FORMAT_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/benchmark,"
"${CMAKE_CURRENT_SOURCE_DIR}/src,"
"${CMAKE_CURRENT_SOURCE_DIR}/test,"
)
# runs clang format and updates files in place.
add_custom_target(format
${PYTHON_EXECUTABLE}
${BUILD_SUPPORT_DIR}/run_clang_format.py
${CLANG_FORMAT_BIN}
${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
--source_dirs ${FORMAT_DIRS}
--fix ${TERRIER_LINT_QUIET}
)
# runs clang format and exits with a non-zero exit code if any files need to be reformatted
add_custom_target(check-format
${PYTHON_EXECUTABLE}
${BUILD_SUPPORT_DIR}/run_clang_format.py
${CLANG_FORMAT_BIN}
${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
--source_dirs ${FORMAT_DIRS}
${TERRIER_LINT_QUIET}
)
###########################################################
#
# "make check-clang-tidy" target
#
###########################################################
if (${CLANG_TIDY_FOUND})
# runs clang-tidy and exits with a non-zero exit code if any errors are found.
# note that clang-tidy automatically looks for a .clang-tidy file in parent directories
add_custom_target(check-clang-tidy
${PYTHON_EXECUTABLE}
${BUILD_SUPPORT_DIR}/run-clang-tidy.py # run LLVM's clang-tidy script
-clang-tidy-binary ${CLANG_TIDY_BIN} # using our clang-tidy binary
-p ${CMAKE_BINARY_DIR} # using cmake's generated compile commands
)
# TODO(WAN): if we're bringing in gbenchmark and gtest properly, we can set them as dependencies here
endif ()
###########################################################
#
# "make check-tpl" and "make check-tpl-diff" targets
#
###########################################################
# runs the TPL binary on all files in 'sample_tpl' comparing each scripts output
# to the reference output in 'tpl_tests.txt'
add_custom_target(check-tpl
DEPENDS tpl
COMMAND ${BUILD_SUPPORT_DIR}/run_tpl_tests.py
-b ${CMAKE_BINARY_DIR}/bin/tpl
-f ${PROJECT_SOURCE_DIR}/sample_tpl/tpl_tests.txt
-t ${PROJECT_SOURCE_DIR}/sample_tpl
)
# Like 'check-tpl', but runs the test only on added tests to 'tpl_tests.txt'
add_custom_target(check-tpl-diff
DEPENDS tpl
COMMAND git diff -U0 ${PROJECT_SOURCE_DIR}/sample_tpl/tpl_tests.txt
| grep '^[+][^+-]'
| sed 's/^.//'
| uniq > ${CMAKE_BINARY_DIR}/tpl_tests_diff.txt # create tpl_tests_diff.txt containing the new tests
&&
${BUILD_SUPPORT_DIR}/run_tpl_tests.py # run the check only on the new tests
-b ${CMAKE_BINARY_DIR}/bin/tpl
-f ${CMAKE_BINARY_DIR}/tpl_tests_diff.txt
-t ${PROJECT_SOURCE_DIR}/sample_tpl
)
############################################################
#
# Doxygen
#
############################################################
# check if Doxygen is installed
if (TPL_BUILD_DOC)
find_package(Doxygen)
if(NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif()
# set input and output files
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/apidoc/Doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
# request to configure the file
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
message(STATUS "Doxygen build configured")
add_custom_target(docs
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM )
endif ()
############################################################
#
# Project Setup
#
############################################################
# Setup includes. Needed for all directory components.
include_directories("${PROJECT_SOURCE_DIR}/src/include/" "${PROJECT_BINARY_DIR}")
set(TPL_TEST_LINK_LIBS tpl_shared ${TPL_LINK_LIBS} gtest gtest_main)
set(TPL_BENCHMARK_LINK_LIBS tpl_shared ${TPL_LINK_LIBS} benchmark gtest gtest_main)
set(TPL_LSAN_OPTIONS "fast_unwind_on_malloc=0,suppressions=${BUILD_SUPPORT_DIR}/leaksanitizer.conf")
# Let the sources and tests directory set themselves up
add_subdirectory(src)
add_subdirectory(test)
add_subdirectory(benchmark)
############################################################
#
# Done, print final configuration summary
#
############################################################
message(STATUS "")
message(STATUS "******************* TPL Configuration Summary *******************")
message(STATUS "")
message(STATUS "Version : ${TPL_VERSION_MAJOR}.${TPL_VERSION_MINOR}")
message(STATUS "System : ${CMAKE_SYSTEM_NAME}")
message(STATUS "Compiler : ${CMAKE_CXX_COMPILER} (${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION})")
message(STATUS "Build type : ${CMAKE_BUILD_TYPE}")
message(STATUS "CXX flags : ${CMAKE_CXX_FLAGS}")
message(STATUS "Linker flags : ${CMAKE_EXE_LINKER_FLAGS}")
message(STATUS "")
message(STATUS "*****************************************************************")
message(STATUS "")