-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
246 lines (222 loc) · 9.82 KB
/
CMakeLists.txt
File metadata and controls
246 lines (222 loc) · 9.82 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
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
cmake_minimum_required(VERSION 3.14)
project(BotCore LANGUAGES CXX C)
set(CMAKE_SYSTEM_VERSION 1)
# Default build with Debug
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
option(WITH_GCOV "bulid with gcov" FALSE)
option(WITH_ASAN "build with address sanitizier" FALSE)
option(WITH_TEST "build with unittest" TRUE)
option(WITH_CORE "build with bot core" TRUE)
option(WITH_TOOLS "build with tools" TRUE)
option(WITH_GAMES "build with games" TRUE)
option(WITH_IMAGE "allow bot print image" TRUE)
option(WITH_GLOG "build with glog" TRUE)
option(WITH_SQLITE "build with sqlite" TRUE)
# 'char' type in arm machines is 'unsigned char', we should define it as 'signed char'
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char -g -Wno-invalid-utf8 -Wno-c99-designator")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsigned-char -g -Wno-invalid-utf8")
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Winconsistent-missing-override COMPILER_SUPPORTS_WINCONSISTENT_MISSING_OVERRIDE)
if (COMPILER_SUPPORTS_WINCONSISTENT_MISSING_OVERRIDE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Winconsistent-missing-override -Werror=inconsistent-missing-override")
else()
check_cxx_compiler_flag(-Wsuggest-override COMPILER_SUPPORTS_WSUGGEST_OVERRIDE)
if (COMPILER_SUPPORTS_WSUGGEST_OVERRIDE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override -Werror=suggest-override")
endif()
endif()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=switch -Werror=unused-result")
check_cxx_compiler_flag(-Wunqualified-std-cast-call COMPILER_SUPPORTS_WUNQUALIFIED_STD_CAST_CALL)
if (COMPILER_SUPPORTS_WUNQUALIFIED_STD_CAST_CALL)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=unqualified-std-cast-call")
endif()
# -Wbraced-scalar-init is clang-only; clang also incorrectly fires on valid
# designated-initializer syntax like .x{false}, so suppress it there too.
check_cxx_compiler_flag(-Wno-braced-scalar-init COMPILER_SUPPORTS_WNO_BRACED_SCALAR_INIT)
if (COMPILER_SUPPORTS_WNO_BRACED_SCALAR_INIT)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init")
endif()
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/json/include)
# On Apple Silicon, Homebrew installs under /opt/homebrew while legacy x86
# Homebrew remnants may still linger in /usr/local. Prepend /opt/homebrew so
# find_package() prefers the native ARM build, and exclude /usr/local from
# library search so that bare library names (e.g. the "gflags" string in
# glog's INTERFACE_LINK_LIBRARIES) resolve from the same prefix as the
# config-mode targets, avoiding rpath cycle warnings.
# On x86 Mac, /opt/homebrew does not exist, so this block is a no-op there.
if (APPLE AND EXISTS /opt/homebrew)
list(PREPEND CMAKE_PREFIX_PATH /opt/homebrew)
list(APPEND CMAKE_IGNORE_PATH /usr/local/lib /usr/local/include)
endif()
if (WITH_IMAGE)
find_package(gflags REQUIRED)
# markdown2image: default to Qt5 WebKit (e.g. RHEL 8); auto-fall back to Qt6 WebEngine when Qt5 WebKit is missing.
option(MARKDOWN2IMAGE_USE_QT5WEBKIT
"Prefer Qt5 WebKit for markdown2image; if unavailable, use Qt6 WebEngine when installed"
ON)
# Guard Qt5 find_package: Qt5CoreConfig.cmake derives its install prefix from
# its own location (get_filename_component 3 levels up), then checks that
# <prefix>/mkspecs/... exists. When Qt5 is partially installed (e.g. missing
# mkspecs), find_package(Qt5) raises a hard CMake error even with QUIET.
# Pre-flight: compute the same prefix and skip Qt5 if mkspecs is absent.
find_file(_qt5_core_cfg_path Qt5CoreConfig.cmake
PATHS
/usr/local/lib/cmake/Qt5Core
/usr/lib/cmake/Qt5Core
/usr/lib64/cmake/Qt5Core)
set(_qt5_usable FALSE)
if (_qt5_core_cfg_path)
# install prefix = Qt5CoreConfig.cmake dir / ../../.. (3 levels up)
get_filename_component(_qt5_prefix "${_qt5_core_cfg_path}" DIRECTORY)
get_filename_component(_qt5_prefix "${_qt5_prefix}" DIRECTORY)
get_filename_component(_qt5_prefix "${_qt5_prefix}" DIRECTORY)
get_filename_component(_qt5_prefix "${_qt5_prefix}" DIRECTORY)
# Qt's CMake files derive prefix from .../lib(64)/cmake/Qt5Core; on RHEL/Fedora
# that is /usr while mkspecs lives under lib64/qt5/mkspecs, not <prefix>/mkspecs.
set(_qt5_mkspecs_ok FALSE)
foreach (_qt5_mkspecs_dir
"${_qt5_prefix}/mkspecs"
"${_qt5_prefix}/lib64/qt5/mkspecs"
"${_qt5_prefix}/lib/qt5/mkspecs"
"${_qt5_prefix}/share/qt5/mkspecs")
if (EXISTS "${_qt5_mkspecs_dir}")
set(_qt5_mkspecs_ok TRUE)
break()
endif()
endforeach()
if (_qt5_mkspecs_ok)
set(_qt5_usable TRUE)
else()
message(STATUS "markdown2image: Qt5 installation broken (no mkspecs next to ${_qt5_prefix}); skipping Qt5")
endif()
endif()
if (_qt5_usable)
find_package(Qt5 QUIET COMPONENTS Gui Widgets WebKit WebKitWidgets)
endif()
find_package(Qt6 QUIET COMPONENTS Gui Widgets WebEngineWidgets)
set(_md2img_qt5_ok FALSE)
if (TARGET Qt5::WebKitWidgets AND TARGET Qt5::WebKit AND TARGET Qt5::Widgets AND TARGET Qt5::Gui)
set(_md2img_qt5_ok TRUE)
endif()
set(_md2img_qt6_ok FALSE)
if (TARGET Qt6::WebEngineWidgets AND TARGET Qt6::Widgets AND TARGET Qt6::Gui)
set(_md2img_qt6_ok TRUE)
endif()
if (MARKDOWN2IMAGE_USE_QT5WEBKIT)
if (_md2img_qt5_ok)
set(_md2img_use_qt5 TRUE)
elseif (_md2img_qt6_ok)
set(_md2img_use_qt5 FALSE)
message(STATUS "markdown2image: Qt5 WebKit not found; using Qt6 WebEngine instead")
else()
message(WARNING "WITH_IMAGE=ON but neither Qt5 WebKit nor Qt6 WebEngine found; disabling image support.")
set(WITH_IMAGE OFF)
endif()
else()
if (_md2img_qt6_ok)
set(_md2img_use_qt5 FALSE)
elseif (_md2img_qt5_ok)
set(_md2img_use_qt5 TRUE)
message(STATUS "markdown2image: Qt6 WebEngine not found; using Qt5 WebKit")
else()
message(WARNING "WITH_IMAGE=ON but neither Qt6 WebEngine nor Qt5 WebKit found; disabling image support.")
set(WITH_IMAGE OFF)
endif()
endif()
if (WITH_IMAGE)
set(USE_QT5WEBKIT "${_md2img_use_qt5}" CACHE BOOL "Forwarded to markdown2image: use Qt5 WebKit backend" FORCE)
add_subdirectory(third_party/markdown2image)
endif()
endif()
if (WITH_GCOV)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -fprofile-arcs -ftest-coverage -lgcov --coverage")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -fprofile-arcs -ftest-coverage -lgcov --coverage")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -lgcov")
endif()
if (WITH_ASAN)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
endif()
if (WITH_SQLITE)
add_definitions(-DWITH_SQLITE)
find_package(SQLite3 REQUIRED)
list(APPEND THIRD_PARTIES SQLite::SQLite3)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sqlite_modern_cpp/hdr)
endif()
if (WITH_GLOG)
find_package(glog REQUIRED)
list(APPEND THIRD_PARTIES glog::glog)
add_definitions(-DWITH_GLOG)
get_target_property(GLOG_INCLUDE_DIRS glog::glog INTERFACE_INCLUDE_DIRECTORIES)
include_directories(${GLOG_INCLUDE_DIRS})
get_target_property(GLOG_COMPILE_DEFS glog::glog INTERFACE_COMPILE_DEFINITIONS)
add_definitions(-DGLOG_USE_GLOG_EXPORT)
endif()
if (WITH_TEST)
enable_testing()
endif()
if (WITH_CORE)
# Prefer protobuf's CMake package (config mode): protobuf >= 22 pulls abseil and
# the bundled FindProtobuf module does not model that, which can break linking.
# EL8 and similar only ship protobuf-devel + CMake's FindProtobuf (module mode),
# so fall back when protobuf-config.cmake is not installed.
# CMP0077 NEW: option() must not clear a normal variable already set by the
# caller; without this, protobuf-options.cmake's option(protobuf_MODULE_COMPATIBLE)
# would silently reset the value we set below.
cmake_policy(SET CMP0077 NEW)
set(protobuf_MODULE_COMPATIBLE TRUE)
find_package(protobuf CONFIG QUIET)
if (NOT TARGET protobuf::libprotobuf)
find_package(Protobuf MODULE REQUIRED)
endif()
if (NOT TARGET protobuf::libprotobuf)
message(FATAL_ERROR
"Could not find protobuf (no protobuf::libprotobuf). Install a build with "
"protobuf-config.cmake, or system protobuf-devel for CMake FindProtobuf.")
endif()
add_subdirectory(match_process)
add_subdirectory(bot_core)
endif()
if (WITH_TOOLS)
add_subdirectory(tools)
endif()
if (WITH_GAMES)
add_subdirectory(third_party/necessary-and-unnecessary-tiles)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/necessary-and-unnecessary-tiles)
find_package(pybind11 QUIET)
if(pybind11_FOUND)
include_directories(${pybind11_INCLUDE_DIRS})
find_package(Python3 COMPONENTS Development QUIET)
if(NOT Python3_FOUND)
set(pybind11_FOUND FALSE)
message(STATUS "Python3 development libraries not found, skipping MahjongPy")
else()
set(PYTHON_LIBRARIES ${Python3_LIBRARIES})
set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS})
if(APPLE)
# Python framework on macOS does not export all symbols; resolve at runtime
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup")
endif()
endif()
endif()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_subdirectory(third_party/mahjong)
unset(CMAKE_CXX_STANDARD)
unset(CMAKE_CXX_STANDARD_REQUIRED)
unset(CMAKE_CXX_EXTENSIONS)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/mahjong)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/tiny_expr)
add_library(tinyexpr SHARED ${CMAKE_CURRENT_SOURCE_DIR}/third_party/tiny_expr/tinyexpr.c)
add_subdirectory(games)
endif()
if (WITH_TEST)
add_subdirectory(game_util) # only build for unittest
add_subdirectory(utility) # only build for unittest
endif()