-
Notifications
You must be signed in to change notification settings - Fork 4
/
CMakeLists.txt
191 lines (160 loc) · 5.48 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
cmake_minimum_required(VERSION 3.24)
project(cat LANGUAGES CXX)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
option(CAT_USE_SANITIZERS "Link ASan and UBSan. This doesn't work in Clang." OFF)
else()
option(CAT_USE_SANITIZERS "Link ASan and UBSan" ON)
endif()
list(
APPEND CAT_COMPILE_OPTIONS_COMMON
# Disable linking libC symbols.
-nostdlib
-nostdlib++
# These features are pessimizations to libCat:
# TODO: Exceptions and rtti should have optional support once it's possible to
# implement them.
-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables
# `global_includes.hpp` must be available everywhere.
-include global_includes.hpp
# Enable CPU intrinsics:
-msse4.2
-mavx2
-mfma
-mlzcnt
-mbmi
-mbmi2
-mfsgsbase
# Enable most warnings.
-Wall -Wextra
-Wno-unused-function
-Wno-unknown-pragmas
-Wno-missing-braces # This breaks `cat::tuple`.
# Both GCC and Clang attributes are used.
# See p2565 "Supporting User-Defined Attributes"
$<$<CXX_COMPILER_ID:GNU>:-Wno-attributes>
$<$<CXX_COMPILER_ID:Clang>:-Wno-unknown-attributes>
# Disable some Clang warnings. libCat needs to violate these.
$<$<CXX_COMPILER_ID:Clang>:-Wno-unqualified-std-cast-call>
$<$<CXX_COMPILER_ID:Clang>:-Wno-main>
# This produces many false positives in Clang 17.
$<$<CXX_COMPILER_ID:Clang>:-Wno-redundant-consteval-if>
# Use GCC extensions.
$<$<CXX_COMPILER_ID:Clang>:-Wno-gnu>
# Use Clang lifetime analysis.
$<$<CXX_COMPILER_ID:Clang>:-Wdangling -Wdangling-gsl -Xclang -fexperimental-bounds-safety>
)
if(CAT_USE_SANITIZERS)
list(
APPEND CAT_COMPILE_OPTIONS_COMMON
-fomit-frame-pointer # Required for UBsan.
-fsanitize=undefined
-fsanitize=address
#$<$<CXX_COMPILER_ID:GNU>:--param asan-stack=0>
#$<$<CXX_COMPILER_ID:Clang>:-mllvm -asan-stack=0>
)
endif()
list(
APPEND CAT_COMPILE_OPTIONS_DEBUG
-ggdb3
$<$<CXX_COMPILER_ID:GNU>:-fno-eliminate-unused-debug-types
-fno-eliminate-unused-debug-symbols>
$<$<CXX_COMPILER_ID:Clang>:-gmodules -gfull>
)
list(
APPEND CAT_COMPILE_OPTIONS_RELEASE
# Remove unused symbols.
-ffunction-sections -fdata-sections
-fvisibility=hidden -fvisibility-inlines-hidden
# TODO: Consider why no-plt instead of relro.
-fno-plt
)
list(
APPEND CAT_COMPILE_OPTIONS_RELWITHDEBINFO
${CAT_COMPILE_OPTIONS_DEBUG}
${CAT_COMPILE_OPTIONS_RELEASE}
)
# LTO doesn't work with sanitizers in clang, so it's special-cased.
if (NOT CAT_USE_SANITIZERS)
list(
APPEND CAT_COMPILE_OPTIONS_RELEASE
-flto=auto
)
list(
APPEND CAT_COMPILE_OPTIONS_RELWITHDEBINFO
# Use thin LTO for optimized non-release builds.
-flto=thin
)
endif()
list(
APPEND CAT_COMPILE_OPTIONS
${CAT_COMPILE_OPTIONS_COMMON}
$<$<CONFIG:Debug>:${CAT_COMPILE_OPTIONS_DEBUG}>
$<$<CONFIG:Release>:${CAT_COMPILE_OPTIONS_RELEASE}>
$<$<CONFIG:RelWithDebInfo>:${CAT_COMPILE_OPTIONS_RELWITHDEBINFO}>
)
list(
APPEND CAT_LINK_OPTIONS_COMMON
# This is required to prevent duplicate symbols.
-nostdlib
# `lld` is required for LLVM LTO. Bfd and `mold` do not work.
$<$<CXX_COMPILER_ID:Clang>:-fuse-ld=lld>
)
list(
APPEND CAT_LINK_OPTIONS_RELEASE
# Remove unused symbols.
-Wl,-z,noseparate-code,--gc-sections
)
list(
APPEND CAT_LINK_OPTIONS
${CAT_LINK_OPTIONS_COMMON}
$<$<CONFIG:Release>:${CAT_LINK_OPTIONS_RELEASE}>
$<$<CONFIG:RelWithDebInfo>:${CAT_LINK_OPTIONS_RELEASE}>
)
add_library(cat INTERFACE)
# Everything building with `cat` should be at least C++26, with GNU extensions.
# This is broken for Clang 19 until CMake 3.29.2
# target_compile_features(cat INTERFACE cxx_std_26)
target_compile_options(cat INTERFACE "-std=gnu++26")
# Link the address and undefined behavior sanitizers.
if (CAT_USE_SANITIZERS)
target_link_options(cat INTERFACE
-fsanitize=address
#-fsanitize=undefined
$<$<CXX_COMPILER_ID:Clang>:-shared-libasan>
)
endif()
target_compile_options(cat INTERFACE ${CAT_COMPILE_OPTIONS})
target_link_options(cat INTERFACE ${CAT_LINK_OPTIONS})
# TODO: Implement these symbols in libCat directly.
# target_link_libraries(cat INTERFACE gcc)
# `src/CMakeLists.txt` adds all of the source and headers files to `cat`.
add_subdirectory(src/)
# Tests can be run using ctest, or by manually running the `unit_tests`
# executable from your specified build output directory.
enable_testing()
# Build the tests.
add_subdirectory(tests/)
# Build the examples.
add_subdirectory(examples/)
# # `ctor.ld` is a minimal linker script necessary for thread local storage.
# target_link_options(cat INTERFACE -T ${CMAKE_SOURCE_DIR}/src/ctor.ld)
# set_target_properties(
# cat PROPERTIES
# LINK_DEPENDS ${CMAKE_SOURCE_DIR}/src/ctor.ld
# )
# Find a configurable path to a `clang-format` binary.
find_program(CAT_CLANG_FORMAT_PATH "clang-format" DOC "`clang-format` binary to use.")
get_property(CAT_SOURCES TARGET cat PROPERTY INTERFACE_SOURCES)
# Recursively discover the `.hpp` files.
get_property(CAT_HEADERS TARGET cat PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
file(GLOB_RECURSE CAT_HEADERS "*.hpp")
option(CAT_PCH "Enable precompiled-headers for libCat headers." ON)
if (CAT_PCH)
target_precompile_headers(cat INTERFACE ${CAT_HEADER_FILES})
endif()
set_target_properties(cat PROPERTIES PCH_WARN_INVALID ON)
# Run `clang-format` on all source files of the `cat` target.
add_custom_target(cat-format
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/format.cmake ${CAT_CLANG_FORMAT_PATH} \"${CAT_SOURCES} ${CAT_HEADERS} ${CAT_HEADER_FILES} \"
DEPENDS ${CAT_SOURCES} ${CAT_HEADERS}
)