-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathTinyCommon.cmake
286 lines (256 loc) · 12 KB
/
TinyCommon.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
# Set common variables and create interface-only library target so all other targets
# will be able to link to, either directly or transitively, to consume common compile
# options/definitions
function(tiny_common target)
set(options EXPORT)
set(oneValueArgs NAMESPACE NAME)
cmake_parse_arguments(PARSE_ARGV 1 TINY "${options}" "${oneValueArgs}" "")
if(DEFINED TINY_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "The ${CMAKE_CURRENT_FUNCTION}() was passed extra arguments: \
${TINY_UNPARSED_ARGUMENTS}")
endif()
add_library(${target} INTERFACE)
add_library(${TINY_NAMESPACE}::${TINY_NAME} ALIAS ${target})
if(TINY_EXPORT)
set_target_properties(${target} PROPERTIES EXPORT_NAME ${TINY_NAME})
endif()
# Full C++ 20 support is required
target_compile_features(${target} INTERFACE cxx_std_20)
# Qt defines
# ---
# Disable deprecated APIs up to the given Qt version
# Disable all the APIs deprecated up to Qt v6.9.0 (including)
# Must be disabled with vcpkg because the qtbase port doesn't define it and it causes
# incompatible API, eg. QByteArray::isNull() or QString::toLongLong() is defined
# inline through this QT_CORE_INLINE_SINCE() deprecated macros and we end up
# with multiple defined symbols, what means QtCore is compiled with old API without
# inline because it doesn't define this QT_DISABLE_DEPRECATED_UP_TO and TinyORM has
# inlined symbols. It of course works with shared DLL builds but fails with static/-md
# triplets (builds). It's a good idea to use the same setting for this like qtbase
# has anyway.
# See: https://bugreports.qt.io/browse/QTBUG-127070
if(NOT TINY_VCPKG)
target_compile_definitions(${target} INTERFACE
QT_DISABLE_DEPRECATED_UP_TO=0x060900
)
endif()
target_compile_definitions(${target}
INTERFACE
#QT_NO_DEPRECATED_WARNINGS
#QT_WARN_DEPRECATED_UP_TO=0x060900
#QT_ASCII_CAST_WARNINGS
#QT_NO_CAST_FROM_ASCII
#QT_RESTRICTED_CAST_FROM_ASCII
QT_NO_CAST_TO_ASCII
QT_NO_CAST_FROM_BYTEARRAY
# Don't define globally, it's better for compatibility, instead use % when needed
#QT_USE_QSTRINGBUILDER
QT_STRICT_ITERATORS
QT_NO_KEYWORDS
# Disable debug output in Release mode
$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG_OUTPUT>
)
# Platform specific configurations
# ---
# WinApi
# For orientation in these versions, see:
# https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/
# https://microsoft.fandom.com/wiki/List_of_Windows_codenames
# https://en.wikipedia.org/wiki/Windows_11_version_history
# https://en.wikipedia.org/wiki/Microsoft_Windows_SDK
# The ideal case would be not to define these and rely on what is defined
# in <qt_/windows.h> but Qt uses too old values for these, eg. MSYS2 patches these and
# uses the latest versions, so we have to define these manually because the original
# Qt code doesn't maintain these correctly.
# All have to be defined because of checks at the beginning of <qt_windows.h> (fixed)
# WINVER, _WIN32_WINNT, NTDDI_VERSION
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
# MSYS2 Qt 6 already defines these macros in the Qt6Targets.cmake Qt6::Platform
# which is included in Package Config file. These C macros comes
# from the QtBaseConfigureTests.cmake#qt_internal_ensure_latest_win_nt_api(),
# this functions is doing compile test using the check_cxx_source_compiles(),
# it includes the <windows.h> and checks whether these C macros are defined and
# if they are not then it appends them to the QT_PLATFORM_DEFINITIONS, then
# the QT_PLATFORM_DEFINITIONS is set for the Qt6::Platform interface library.
# So these C macros are set on MSVC (in <sdkddkver.h> is advanced guess logic)
# and are not set on mingw-w64/MSYS2 in the <windows.h> file.
# What means we can't set them on MSYS2 because it throws [-Wmacro-redefined].
# Flipped expression of : if(MINGW AND QT_VERSION_MAJOR GREATER_EQUAL 6)
if(NOT MINGW OR NOT QT_VERSION_MAJOR GREATER_EQUAL 6)
target_compile_definitions(${target} INTERFACE
# Windows 11 "22H2" - 0x0A00000C
WINVER=_WIN32_WINNT_WIN10
_WIN32_WINNT=_WIN32_WINNT_WIN10
)
endif()
target_compile_definitions(${target} INTERFACE
# Windows 11 "22H2" - 0x0A00000C
NTDDI_VERSION=NTDDI_WIN10_NI
# Internet Explorer 11
_WIN32_IE=_WIN32_IE_IE110
# Exclude unneeded header files
WIN32_LEAN_AND_MEAN
NOMINMAX
# Others
UNICODE _UNICODE
)
endif()
# Compiler and Linker options
# ---
# clang-cl.exe notes:
# /RTC - https://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130902/088105.html
# /bigobj - Clang-cl uses it by default - https://reviews.llvm.org/D12981
if(MSVC)
# Common for MSVC and Clang-cl
target_compile_options(${target} INTERFACE
# Suppress banner and info messages
/nologo
# Is safer to provide this explicitly, qmake do it for MSVC too
/EHsc
/utf-8
# Has to be enabled explicitly
# https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
/Zc:__cplusplus
# Standards-conforming behavior
/Zc:strictStrings
)
# Abort compiling on warnings for Debug builds only (excluding vcpkg),
# Release and vcpkg builds must go on as far as possible
if(NOT TINY_VCPKG)
target_compile_options(${target} INTERFACE
/W4
# Enable Additional Security Checks for Debug builds only
$<$<CONFIG:Debug>:/WX /sdl>
)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(${target} INTERFACE
# Set by default by c++20 but from VS 16.11, can be removed when
# minMsvcReqVersion will be >= 16.11
/permissive-
# Clang-cl 16 throws -Wunused-command-line-argument, so provide it
# only for the MSVC
/guard:cf
/bigobj
# Standards-conforming behavior
/Zc:wchar_t,rvalueCast,inline
/Zc:throwingNew,referenceBinding,ternary
# C/C++ conformant preprocessor
/Zc:preprocessor
/external:anglebrackets /external:W0
# Enable and check it from time to time
# /external:templates-
/wd4702
# Enable only when needed to invoke the MSVC Analyzer
# Also, add external libraries on the CAExcludePath environment variables as
# the /analyze:external- doesn't work in all cases (for me)
# /analyze
# /analyze:external-
)
# TODO cmake this will not work with clang-cl problem is that CMAKE_CXX_SIMULATE_VERSION reports only short version like 19.40, so I can't fix it easily silverqx
# Needed to suppress this because lot of new warnings on latest MSVC, also doesn't
# matter too much because TinyORM compiles even without it with Qt v6, warnings were
# only on Qt v5
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.38.32914.95")
target_compile_definitions(${target} INTERFACE
_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING
)
endif()
endif()
target_link_options(${target} INTERFACE
/guard:cf
$<$<NOT:$<CONFIG:Debug>>:/OPT:REF,ICF=5>
# /OPT:REF,ICF does not support incremental linking
$<$<CONFIG:RelWithDebInfo>:/INCREMENTAL:NO>
# Abort linking on warnings for Debug builds only, Release builds must go on
# as far as possible
$<$<CONFIG:Debug>:/WX>
)
endif()
if(MINGW)
target_compile_options(${target} INTERFACE
$<$<CXX_COMPILER_ID:Clang,AppleClang>:-Wno-ignored-attributes>
)
# All security flags below are enabled by default on MSYS2 and MinGW-w64
# Legend:
# - ASLR - Address space layout randomization
# - same as PIC on Linux (position-independent code)
# - DEP - Windows Data Execution Prevention feature
# ---
# Linker options (supported by both bfd and LLD):
# --dynamicbase - Randomly rebase at load time by using the ASLR
# --high-entropy-va - ASLR can use the entire 64-bit address space
# --nxcompat - Executable is DEP compatible
# --default-image-base-high - Default image bases over 4GB (ASLR)
# ---
# Can be checked by:
# - Exe64bitDetector.exe -f .\TinyOrm0.dll
# - dumpbin.exe /HEADERS .\TinyOrm0.dll
# TODO cmake MSYS2 track /GUARD:CF progress and enable it when will work everywhere; see: https://gist.github.com/alvinhochun/a65e4177e2b34d551d7ecb02b55a4b0a silverqx
# target_link_options(${target} INTERFACE
# $<$<CONFIG:Debug,RelWithDebInfo>:
# LINKER:--dynamicbase,--high-entropy-va,--nxcompat
# LINKER:--default-image-base-high>
# )
endif()
if(NOT MSVC AND
(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
)
# Abort compiling on warnings for Debug builds only (excluding vcpkg),
# Release and vcpkg builds must go on as far as possible
if(NOT TINY_VCPKG)
target_compile_options(${target} INTERFACE
$<$<CONFIG:Debug>:-Werror -Wfatal-errors -pedantic-errors>
)
endif()
target_compile_options(${target} INTERFACE
# -fexceptions for Linux is not needed, it is on by default
-Wall
-Wextra
# Weffc++ is outdated, it warnings about bullshits 🤬, even word about this
# in docs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110186
# -Weffc++
# CMake already defines it
# -Winvalid-pch
-pedantic
-Wcast-qual
-Wcast-align
-Woverloaded-virtual
-Wold-style-cast
-Wshadow
-Wundef
-Wfloat-equal
-Wformat-security
-Wdouble-promotion
-Wconversion
-Wzero-as-null-pointer-constant
-Wuninitialized
-Wdeprecated-copy-dtor
# Reduce I/O operations (use pipes between commands when possible)
-pipe
)
# Clang 12 still doesn't support -Wstrict-null-sentinel
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wstrict-null-sentinel SNS_SUPPORT)
if(SNS_SUPPORT)
target_compile_options(${target} INTERFACE -Wstrict-null-sentinel)
endif()
# Has the potential to catch weird code
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(${target} INTERFACE -Wdeprecated)
endif()
endif()
# Use faster lld linker on Clang (target the Clang except Clang-cl with MSVC)
# Don't set for MINGW to avoid duplicate setting (look a few lines above)
# TODO use LINKER_TYPE target property when min. version will be CMake v3.29 silverqx
if(NOT MINGW AND NOT MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_link_options(${target} INTERFACE -fuse-ld=lld)
endif()
# Use 64-bit off_t on 32-bit Linux, ensure 64bit offsets are used for filesystem
# accesses for 32bit compilation
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
target_compile_definitions(${target} INTERFACE -D_FILE_OFFSET_BITS=64)
endif()
endfunction()