-
Notifications
You must be signed in to change notification settings - Fork 13
/
CMakeLists.txt
401 lines (313 loc) · 14 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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
##########################################################################
##########################################################################
function(progress_message message)
string(TIMESTAMP time)
message(STATUS "***************************************************************************")
message(STATUS "**")
message(STATUS "** ${message}")
message(STATUS "** (Time now: ${time})")
message(STATUS "**")
message(STATUS "***************************************************************************")
endfunction()
progress_message("Starting...")
##########################################################################
##########################################################################
cmake_minimum_required(VERSION 3.20)
set(CMAKE_CONFIGURATION_TYPES Debug RelWithDebInfo Final)
project(b2)
set(CMAKE_SKIP_INSTALL_RULES YES)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT b2)
##########################################################################
##########################################################################
enable_testing()
include(FindPkgConfig)
include(CheckCXXSourceCompiles)
##########################################################################
##########################################################################
# Prefer newer GL libraries.
#
# https://cmake.org/cmake/help/latest/policy/CMP0072.html
# cmake_policy(SET CMP0072 NEW)
set(OpenGL_GL_PREFERENCE GLVND)
##########################################################################
##########################################################################
# Normal variables take priority over OPTION.
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
cmake_policy(SET CMP0077 NEW)
##########################################################################
##########################################################################
if(DEFINED RELEASE_NAME)
set(INCLUDE_EXPERIMENTAL OFF)
option(LIBUV_BUILD_TESTS "" OFF)
else()
set(INCLUDE_EXPERIMENTAL ON)
option(LIBUV_BUILD_TESTS "" ON)
endif()
##########################################################################
##########################################################################
# https://cmake.org/Wiki/CMake_FAQ#How_can_I_extend_the_build_modes_with_a_custom_made_one_.3F
set(CMAKE_CXX_FLAGS_FINAL ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
set(CMAKE_C_FLAGS_FINAL ${CMAKE_C_FLAGS_RELWITHDEBINFO})
set(CMAKE_EXE_LINKER_FLAGS_FINAL ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO})
set(CMAKE_SHARED_LINKER_FLAGS_FINAL ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO})
# Use statically linked CRT, to reduce the chances of needing to
# install the VC++ runtime redist. Adds <300 KB to b2.exe.
#
# This only needs to apply to b2.exe, but it's a pain to set this
# seting up on a case by case basis with VC++, and easiest to just set
# it for everything. This does noticeably increase the total size of
# the build byproducts though :( - 3.07 GB when building absolutely
# everything with DLL CRT, and 5.50 GB when building absolutely
# everything with .lib CRT.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:DebugDLL>")
##########################################################################
##########################################################################
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/etc/cmake")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/submodules/sanitizers-cmake/cmake")
##########################################################################
##########################################################################
if(WIN32)
set(USE_SYSTEM_SDL_DEFAULT OFF)
set(USE_SYSTEM_LIBUV_DEFAULT OFF)
set(USE_SYSTEM_CURL_DEFAULT OFF)
elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin")
set(OSX 1)
set(USE_SYSTEM_SDL_DEFAULT OFF)
set(USE_SYSTEM_LIBUV_DEFAULT OFF)
# The OS X version works fine when built with the repo's copy of
# libcurl, and the result is easily stepped through in Xcode - but the
# libcurl CMakeLists.txt takes, like, 15 minutes to run. Might as well
# use the system libcurl, given that it ships with OS X and is
# probably tuned for the system SSL and so on.
set(USE_SYSTEM_CURL_DEFAULT ON)
elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux")
set(LINUX 1)
set(USE_SYSTEM_SDL_DEFAULT ON)
set(USE_SYSTEM_LIBUV_DEFAULT ON)
set(USE_SYSTEM_CURL_DEFAULT ON)
else()
message(FATAL_ERROR "unsupported platform:" ${CMAKE_HOST_SYSTEM_NAME})
endif()
option(USE_SYSTEM_SDL "Use system copy of SDL rather than building the submodule copy from source" ${USE_SYSTEM_SDL_DEFAULT})
option(USE_SYSTEM_LIBUV "Use system copy of libuv rather than building the submodule copy from source" ${USE_SYSTEM_LIBUV_DEFAULT})
option(USE_SYSTEM_CURL "Use system copy of curl rather than building the submodule copy from source" ${USE_SYSTEM_CURL_DEFAULT})
##########################################################################
##########################################################################
set(WANTED_SANITIZE_THREAD ${SANITIZE_THREAD})
set(WANTED_SANITIZE_UNDEFINED ${SANITIZE_UNDEFINED})
set(WANTED_SANITIZE_MEMORY ${SANITIZE_MEMORY})
set(WANTED_SANITIZE_ADDRESS ${SANITIZE_ADDRESS})
progress_message("Sanitizers")
find_package(Sanitizers)
function(check_sanitizer NAME PREFIX)
if(WANTED_SANITIZE_${NAME})
if("${${PREFIX}_${CMAKE_C_COMPILER_ID}_FLAGS}" STREQUAL "")
message(FATAL_ERROR ${NAME} " sanitizer not available")
endif()
endif()
endfunction()
check_sanitizer(THREAD TSan)
check_sanitizer(UNDEFINED UBSan)
check_sanitizer(MEMORY MSan)
check_sanitizer(ADDRESS ASan)
##########################################################################
##########################################################################
progress_message("libcurl")
if(USE_SYSTEM_CURL)
if(OSX)
# The objective here is to link against the system copy of
# libcurl, not the MacPorts one.
#
# (Nor the Homebrew one! - but I don't use Homebrew, so I don't
# know which folders to ignore.)
set(OLD_CMAKE_IGNORE_PATH ${CMAKE_IGNORE_PATH})
set(CMAKE_IGNORE_PATH
/opt/local/lib
/opt/local/include
/opt/local/bin)
endif()
find_package(CURL 7 REQUIRED
COMPONENTS HTTP)
set(LIBCURL_TARGET CURL::libcurl)
if(OSX)
set(CMAKE_IGNORE_PATH ${OLD_CMAKE_IGNORE_PATH})
endif()
else()
# (Even though Windows libcurl is part of submodules, the
# configuration process sets some variables, and find_package (as used
# on OS X/Linux) doesn't seem to have any analogue of PARENT_SCOPE. So
# it's massively easier to do all this stuff in the top-level
# CMakeLists.txt.)
option(BUILD_CURL_EXE "" OFF)
option(BUILD_SHARED_LIBS "" OFF)
option(BUILD_TESTING "" OFF)
# libcurl finds zlib using find_package, which is annoying:
#
# 1. it'll just find some random copy of zlib, if you have one (on
# my laptop it found Anaconda's copy)
#
# 2. it can find some useless copy of zlib (on my laptop, it finds
# Anaconda's copy when building for x86, even though it's an x64
# library, and the link fails)
#
# 3. the obvious solution to this sort of problem is to build zlib
# as part of the b2 project, then arrange for libcurl's find_package
# to find that copy. But this appears to be literally impossible
#
# So (pending a better solution), just disable curl's use of zlib.
#
# (Curl is currently only used for BeebLink, so it's a minority
# thing at best, and if it turns out the BeebLink server is emitting
# gzip'd data that can just be disabled. It's pointless for Beeb
# stuff anyway!)
option(CURL_ZLIB "" OFF)
add_subdirectory(${CMAKE_SOURCE_DIR}/submodules/curl)
set(LIBCURL_TARGET libcurl)
endif()
message(STATUS "libcurl target: ${LIBCURL_TARGET}")
##########################################################################
##########################################################################
progress_message("SDL")
if(USE_SYSTEM_SDL)
find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2)
find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2main)
# Find out whether the version is new enough for
# SDL_SoftStretchLinear.
get_target_property(CMAKE_REQUIRED_INCLUDES SDL2::SDL2 INCLUDE_DIRECTORIES)
get_target_property(CMAKE_REQUIRED_DEFINITIONS SDL2::SDL2 COMPILE_DEFINITIONS)
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DSDL_MAIN_HANDLED)
check_cxx_source_compiles("#include <SDL.h>
typedef decltype(&SDL_SoftStretchLinear) T;int main(void){return 0;}" HAVE_SDL_SOFTSTRETCHLINEAR)
message(STATUS "SDL_SoftStretchLinear exists: ``${HAVE_SDL_SOFTSTRETCHLINEAR}''")
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_DEFINITIONS)
set(SDL2_LIBRARY SDL2::SDL2 SDL2::SDL2main)
else()
if(LINUX)
# https://github.com/tom-seddon/b2/issues/36
pkg_check_modules(B2_PULSEAUDIO libpulse-simple)
if(NOT B2_PULSEAUDIO_FOUND)
message(FATAL_ERROR "PulseAudio libraries not found - the appropriate package on Ubuntu is libpulse-dev")
endif()
endif()
set(SDL_STATIC ON)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
add_subdirectory(${CMAKE_SOURCE_DIR}/submodules/SDL_official)
if(OSX)
# Probably unavoidable, as SDL2 will be trying to support older
# macOS versions.
target_compile_options(SDL2-static PRIVATE "-Wno-deprecated-declarations")
# I'm gambling these are benign.
target_compile_options(SDL2-static PRIVATE "-Wno-shorten-64-to-32")
endif()
set(HAVE_SDL_SOFTSTRETCHLINEAR TRUE)
set(SDL2_LIBRARY SDL2::SDL2-static SDL2::SDL2main)
endif()
##########################################################################
##########################################################################
if(LINUX OR OSX)
progress_message("ffmpeg")
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(FFMPEG libavcodec libavformat libavutil libswresample libswscale)
if(NOT ${FFMPEG_FOUND})
message(STATUS "FFmpeg not found - video writing not available")
else()
set(FFMPEG__GOOD ON)
set(FFMPEG__AVCODEC_VERSION 58)
set(FFMPEG__AVFORMAT_VERSION 58)
set(FFMPEG__AVUTIL_VERSION 56)
set(FFMPEG__SWRESAMPLE_VERSION 3)
set(FFMPEG__SWSCALE_VERSION 5)
# https://gitlab.kitware.com/cmake/cmake/-/issues/18067 - ridiculous
if(NOT FFMPEG_libavcodec_VERSION MATCHES "^58\.")
message(WARNING "Unsupported libavcodec major version - need 58")
set(FFMPEG__GOOD OFF)
endif()
if(NOT FFMPEG_libavformat_VERSION MATCHES "^58\.")
message(WARNING "Unsupported libavformat major version - need 58")
set(FFMPEG__GOOD OFF)
endif()
if(NOT FFMPEG_libavutil_VERSION MATCHES "^56\.")
message(WARNING "Unsupported libavutil major version - need 56")
set(FFMPEG__GOOD OFF)
endif()
if(NOT FFMPEG_libswresample_VERSION MATCHES "^3\.")
message(WARNING "Unsupported libswreasmple major version - need 3")
set(FFMPEG__GOOD OFF)
endif()
if(NOT FFMPEG_libswscale_VERSION MATCHES "^5\.")
message(WARNING "Unsupported libswscale major version - need 5")
set(FFMPEG__GOOD OFF)
endif()
if(FFMPEG__GOOD)
message(STATUS "FFmpeg 4 found")
message(STATUS " Libraries: ${FFMPEG_LIBRARIES}")
message(STATUS " Include dirs: ${FFMPEG_INCLUDE_DIRS}")
message(STATUS " Definitions: ${FFMPEG_DEFINITIONS}")
else()
message(WARNING "FFmpeg 4 required specifically - video writing not available")
set(FFMPEG_FOUND OFF)
endif()
endif()
endif()
endif()
##########################################################################
##########################################################################
if(LINUX)
find_package(GTK2 2.0 REQUIRED gtk)
message(STATUS "GTK2 include folder: " ${GTK2_INCLUDE_DIRS})
endif()
##########################################################################
##########################################################################
progress_message("libuv")
if(USE_SYSTEM_LIBUV)
find_package(LibUV REQUIRED)
else()
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv)
if(OSX)
# I'm trusting (possibly wrongly...) that these are benign.
target_compile_options(uv PRIVATE "-Wno-shorten-64-to-32")
target_compile_options(uv_a PRIVATE "-Wno-shorten-64-to-32")
endif()
# Don't add libuv's tests as a ctest test. The shutdown_eof test fails, for some reason.
# add_test(
# NAME uv
# COMMAND $<TARGET_FILE:run-tests>)
# set_tests_properties(uv PROPERTIES LABELS slow)
set(LibUV_FOUND ON)
set(LibUV_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv)
set(LibUV_LIBRARIES uv_a)
endif()
##########################################################################
##########################################################################
progress_message("submodules; src; dependencies")
add_subdirectory(submodules)
add_subdirectory(dependencies)
add_subdirectory(src)
target_sources(b2 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/CMakeLists.txt ${CMAKE_CURRENT_LIST_DIR}/common.cmake)
target_sources(b2 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/submodules/CMakeLists.txt)
if(INCLUDE_EXPERIMENTAL)
add_subdirectory(experimental)
target_sources(b2 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/experimental/CMakeLists.txt)
endif()
##########################################################################
##########################################################################
# It's handy to have the non-project CMakeLists.txt files somewhere in the VS
# solution.
#
# There's nowhere particularly good for them, so just put them in b2.
#
# This doesn't interact brilliantly with DPack, which strips off the paths
# in its files list, but Ctrl+, works OK.
target_sources(b2 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/CMakeLists.txt ${CMAKE_CURRENT_LIST_DIR}/common.cmake)
target_sources(b2 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/submodules/CMakeLists.txt)
if(INCLUDE_EXPERIMENTAL)
target_sources(b2 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/experimental/CMakeLists.txt)
endif()
if(OSX)
target_sources(b2 PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/b2/macos/template.Info.plist)
endif()
##########################################################################
##########################################################################
progress_message("Done")