-
Notifications
You must be signed in to change notification settings - Fork 2
/
CMakeLists.txt
274 lines (234 loc) · 8.98 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
cmake_minimum_required(VERSION 3.20)
project(fchk VERSION 3.0.3 LANGUAGES CXX)
## ============================================================================
## Global CMake Variables.
## ============================================================================
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
## ============================================================================
## Global compiler options.
## ============================================================================
## Turn on diagnostics colours.
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-fdiagnostics-color=always)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-fcolor-diagnostics)
endif()
## Use mold as the default linker, if it exists.
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
find_program(MOLD_LINKER "mold")
if (MOLD_LINKER)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-fuse-ld=mold)
endif()
add_link_options(-fuse-ld=mold)
endif()
endif()
## ============================================================================
## Compiler options.
## ============================================================================
add_library(_fchk_options INTERFACE)
## Allow the user to force building this in release mode.
option(FCHK_FORCE_RELEASE "Force building fchk in release mode." OFF)
## Flags for Clang and GCC.
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(_fchk_options INTERFACE
## Warnings.
-Wall -Wextra # Enable ‘all’ warnings.
-Wundef # Invalid #undef or undefined macro in #if.
-Wcast-align # Casting that changes alignment.
-Wconversion # Implicit conversions.
-Wsign-conversion # Implicit sign conversions.
-Wformat=2 # Stricter format checking.
## Disabled warnings.
-Wno-unused-function
-Wno-unused-local-typedefs
## NULL Errors.
-Werror=nonnull # Passing NULL to nonnull parameter.
## Memory Errors.
-Werror=address # Suspicious use of addresses.
-Werror=init-self # Initialization of a variable with itself.
-Werror=uninitialized
## Return type.
-Werror=return-type
## C/C++.
-Werror=implicit-fallthrough
-Werror=pointer-arith # Disallow void* and function pointer arithmetic.
-Werror=string-compare # Nonsensical string comparisons.
-Werror=switch # Missing switch cases.
# -Werror=switch-enum # Switch on enum (even if there is a default case).
-Werror=write-strings # Strings in C should be const char*.
## C++.
-Werror=missing-field-initializers
-Werror=non-virtual-dtor
-Werror=pessimizing-move
)
endif()
## Additional flags for GCC.
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(_fchk_options INTERFACE
-Wlogical-op # Duplicate or unintended logical operators.
-Werror=invalid-memory-model # For atomics.
-Werror=maybe-uninitialized
-Werror=missing-requires
-Werror=return-local-addr
)
endif()
## Additional flags for Clang.
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(_fchk_options INTERFACE
-Werror=dangling
-Werror=return-stack-address
)
endif()
## Flags for MSVC.
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(_fchk_options INTERFACE
/W4 # Enable ‘all’ warnings.
# Allow unnamed structs/unions.
/wd4201
# Source code is UTF-8.
/utf-8
)
endif()
## On Windows, don’t suggest the _s nonsense functions.
if (WIN32)
target_compile_definitions(_fchk_options INTERFACE
_CRT_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS_GLOBALS
_CRT_NONSTDC_NO_WARNINGS
)
endif()
if (ENABLE_ASAN)
target_compile_options(_fchk_options INTERFACE -fsanitize=address)
target_link_options(_fchk_options INTERFACE -fsanitize=address)
endif()
if (MSVC)
target_compile_options(_fchk_options INTERFACE /Zc:preprocessor)
endif()
## Debug/Release flags.
if (FCHK_FORCE_RELEASE)
if (NOT MSVC)
target_compile_options(_fchk_options INTERFACE -O3 -march=native)
target_link_options(_fchk_options INTERFACE -O3 -march=native)
else()
target_compile_options(_fchk_options INTERFACE /O2)
endif()
else()
if (NOT MSVC)
target_compile_definitions(_fchk_options INTERFACE _GLIBCXX_DEBUG)
target_compile_options(_fchk_options INTERFACE
$<$<CONFIG:DEBUG>:-O0 -g3 -ggdb3>
$<$<CONFIG:RELEASE>:-O3 -march=native>
)
target_link_options(_fchk_options INTERFACE
$<$<CONFIG:DEBUG>:-O0 -g3 -ggdb3 -rdynamic>
$<$<CONFIG:RELEASE>:-O3 -march=native>
)
else()
target_compile_options(_fchk_options INTERFACE
$<$<CONFIG:DEBUG>:/Od>
$<$<CONFIG:RELEASE>:/O2>
)
endif()
endif()
## ============================================================================
## Submodules and include dirs.
## ============================================================================
include(FetchContent)
## Add clopts.
message(STATUS "Downloading Clopts...")
FetchContent_Declare(_fchk_clopts
GIT_REPOSITORY https://github.com/Sirraide/clopts.git
GIT_TAG v2.2.0
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/libs/clopts"
)
FetchContent_MakeAvailable(_fchk_clopts)
target_include_directories(_fchk_options INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/libs/clopts/include")
## Find PCRE2.
set(PCRE2_SUPPORT_JIT ON)
set(PCRE2_BUILD_PCRE2GREP OFF)
set(PCRE2_BUILD_TESTS OFF)
message(STATUS "Downloading PCRE2 ...")
FetchContent_Declare(_fchk_pcre2
GIT_REPOSITORY https://github.com/PCRE2Project/pcre2
GIT_TAG pcre2-10.42
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/libs/pcre2"
)
FetchContent_MakeAvailable(_fchk_pcre2)
## Get libassert.
include(FetchContent)
FetchContent_Declare(
_fchk_libassert
GIT_REPOSITORY https://github.com/jeremy-rifkin/libassert.git
GIT_TAG v2.0.2
)
FetchContent_MakeAvailable(_fchk_libassert)
## Suppress warnings for PCRE, otherwise there will be a lot of them
file(
GLOB_RECURSE _fchk_pcre2_sources
${CMAKE_CURRENT_BINARY_DIR}/libs/pcre2/*.c
${CMAKE_CURRENT_BINARY_DIR}/libs/pcre2/*.h
)
## Link against libfmt.
target_link_libraries(_fchk_options INTERFACE fmt pcre2-8 libassert::assert)
## ‘src’ should be an include directory.
target_include_directories(_fchk_options INTERFACE src)
## ‘include’ too, if it exists.
if (EXISTS ${PROJECT_SOURCE_DIR}/include)
target_include_directories(_fchk_options INTERFACE include)
endif()
## As well as everything in ‘libs’.
if (EXISTS ${PROJECT_SOURCE_DIR}/libs)
file(GLOB libs ${PROJECT_SOURCE_DIR}/libs/*)
## Add the include directory to the include path, or the root
## directory if there is no include directory.
foreach(lib ${libs})
if (IS_DIRECTORY ${lib}/include)
target_include_directories(_fchk_options INTERFACE ${lib}/include)
else()
target_include_directories(_fchk_options INTERFACE ${lib})
endif()
endforeach()
## Also add all of them as subdirectories if they have a CMakeLists.txt.
foreach (lib ${libs})
if (EXISTS ${lib}/CMakeLists.txt)
add_subdirectory(${lib})
endif()
endforeach()
endif()
## ============================================================================
## Executables and libraries.
## ============================================================================
add_library(fchk-core STATIC src/core.cc src/core.hh src/utils.hh src/errs.hh)
add_executable(fchk src/main.cc)
## Project dir so we can strip it from diags.
target_compile_definitions(fchk-core PUBLIC
"FCHK_PROJECT_DIR_NAME=\"fchk\""
"FCHK_PROJECT_DIR=\"${PROJECT_SOURCE_DIR}\""
"FCHK_VERSION=\"${PROJECT_VERSION}\""
)
## Apply our options.
target_link_libraries(fchk-core PRIVATE _fchk_options)
target_link_libraries(fchk PRIVATE fchk-core _fchk_options)
target_include_directories(fchk-core PUBLIC src)
## Automatically provide access to the test discovery feature.
set(FCHK_EXE_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/fchk")
include("${PROJECT_SOURCE_DIR}/cmake/FCHKDiscoverTests.cmake")
## ============================================================================
## Tests.
## ============================================================================
if (FCHK_TEST_FCHK)
Include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.4.0
)
FetchContent_MakeAvailable(Catch2)
add_executable(tests test/tests.cc)
target_link_libraries(tests PRIVATE fchk-core Catch2::Catch2WithMain _fchk_options)
include(CTest)
include(Catch)
catch_discover_tests(tests)
endif()