-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
135 lines (113 loc) · 5.63 KB
/
Copy pathCMakeLists.txt
File metadata and controls
135 lines (113 loc) · 5.63 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
# Copyright 2022 Nokia
# Copyright 2026 Shi-Zhong Chen
# Licensed under the BSD 3 Clause license
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
# ------------------------------------------------------------------------------------------------
project(ut_exe CXX) # as early as possible, eg must before CMAKE_CXX_FLAGS
set(CMAKE_CXX_EXTENSIONS OFF)
# ------------------------------------------------------------------------------------------------
# build mode: cmake -Dci=<mode> .. (empty = fast UT, the local default)
# - 1 knob replaces CMAKE_BUILD_TYPE: each mode bundles -O/-g, sanitizer/coverage and macros
set(ci "" CACHE STRING "UT build mode: <empty>=fast UT | cov | asan | tsan | release")
set(_ci_allowed "" cov asan tsan release)
set_property(CACHE ci PROPERTY STRINGS ${_ci_allowed})
if(NOT ci IN_LIST _ci_allowed)
message(FATAL_ERROR "unknown ci='${ci}', expect one of: cov asan tsan release (or empty)")
endif()
if(CMAKE_BUILD_TYPE)
message(FATAL_ERROR "this project selects flags via -Dci=<mode>, not CMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}'")
endif()
set(_cxx_std cxx_std_17) # 17 since "if constexpr()"
if(ci STREQUAL "cov")
message("!!! coverage & valgrind(only need -g -fno-omit-frame-pointer)")
add_compile_options(--coverage -fPIC -O0 -fprofile-abs-path -g) # gcov + valgrind req
add_link_options(--coverage) # gcov req
add_compile_definitions(SMART_LOG WITH_HID_LOG IN_ALL_UT) # more info to debug ci
set(_cxx_std cxx_std_20) # try c++20/23 to see cov rate inc or not
elseif(ci STREQUAL "asan")
message("!!! asan+lsan+ubsan for: use-after-free, double-free, out-of-bound, leak, undef behavior")
add_compile_definitions(_FORTIFY_SOURCE=2 IN_ALL_UT) # buffer overflow checks
add_compile_options(-g -fno-omit-frame-pointer)
add_compile_options(-fstack-protector-strong) # stack overflow protection
add_compile_options(-O2) # required for FORTIFY_SOURCE
add_compile_options(-fsanitize=address,undefined)
add_link_options(-fsanitize=address,undefined)
add_link_options(-fstack-protector-strong) # ensure stack protector runtime is linked
elseif(ci STREQUAL "tsan") # asan/lsan/msan cover by valgrind(memcheck)
message("!!! SANITIZE for: thread")
add_compile_definitions(_FORTIFY_SOURCE=2 IN_ALL_UT) # buffer overflow checks
add_compile_options(-g -fno-omit-frame-pointer)
add_compile_options(-fstack-protector-strong) # stack overflow protection
add_compile_options(-O2) # required for FORTIFY_SOURCE
add_compile_options(-fsanitize=thread)
add_link_options(-fsanitize=thread)
add_link_options(-fstack-protector-strong) # ensure stack protector runtime is linked
elseif(ci STREQUAL "release")
# release-perf build: cold/hot path separation comes from compiler flags, not source macros
# - O3 : enables block reordering, inlining, vectorization
# - freorder-blocks-and-partition : split hot vs cold blocks into .text vs .text.unlikely
# - freorder-functions : place mutually-called funcs adjacent (better i-cache)
# - ffunction-sections/fdata-s. : 1 section per func, lets linker drop dead code & re-pack hot
# - Wl,--gc-sections : actually drop unused sections at link time
# - DNDEBUG : disable assert in hot path
# NOTE: -flto is intentionally OFF here; with our toolchain it merges all blocks back into a
# single .text and defeats the section partitioning we want to verify.
message("!!! release: max perf, hot/cold sections separated by compiler; no ut/")
add_compile_options(-O3 -DNDEBUG)
add_compile_options(-freorder-blocks-and-partition -freorder-functions)
add_compile_options(-ffunction-sections -fdata-sections)
add_link_options(-Wl,--gc-sections)
else()
message("!!! UT only - no cov, no SANITIZE check etc")
add_compile_options(-O1) # fastest build+ut (1-cpp-change=5s, vs 45s of -g)
add_compile_definitions(IN_SPECIAL_UT IN_ALL_UT) # benchmark etc
endif()
#add_compile_options(-fno-exceptions) # inc branch coverage
add_subdirectory(src)
if(NOT ci STREQUAL "release")
add_executable(ut_exe)
# googletest via FetchContent (always latest, shallow clone to min download)
include(FetchContent)
FetchContent_Declare(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG main
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(googletest)
add_subdirectory(ut)
target_link_libraries(ut_exe PRIVATE
lib_domino
lib_ut
gtest_main
)
# make run
add_custom_target(run
COMMAND ./ut_exe --gtest_brief=0
DEPENDS ut_exe
)
# make soak (not CI; flags in soak.sh)
add_custom_target(soak
COMMAND bash ${CMAKE_SOURCE_DIR}/ut/soak.sh
DEPENDS ut_exe
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
USES_TERMINAL
)
endif()
# C++ standard on targets (decided per ci mode above)
target_compile_features(lib_domino PUBLIC ${_cxx_std})
# make cov (ci=cov only: fresh .gcda, then gcovr; reports land in this build dir)
if(ci STREQUAL "cov")
add_custom_target(cov
COMMAND find . -name "*.gcda" -delete
COMMAND ./ut_exe --gtest_brief=1
COMMAND $ENV{HOME}/.local/bin/gcovr -k --config ${CMAKE_SOURCE_DIR}/ut/gcovr/gcovr.cfg
DEPENDS ut_exe
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
USES_TERMINAL
VERBATIM
)
endif()
# simplify "make help"
set(CMAKE_SKIP_PREPROCESSED_SOURCE_RULES true)
set(CMAKE_SKIP_ASSEMBLY_SOURCE_RULES true)