-
Notifications
You must be signed in to change notification settings - Fork 43
/
CMakeLists.txt
342 lines (294 loc) · 10 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
cmake_minimum_required(VERSION 3.21)
project(coroutine LANGUAGES CXX VERSION 2.0.0)
option(BUILD_SHARED_LIBS "https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html" ON)
option(CMAKE_BUILD_TYPE "https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html" "Debug")
option(BUILD_TESTING "Build test program" OFF)
option(WITH_GCD "Build with GCD(libdispatch)" OFF)
# set(CMAKE_C_STANDARD 17)
# set(CMAKE_CXX_STANDARD 20)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true)
include(GNUInstallDirs)
message(STATUS "system: ${CMAKE_SYSTEM}")
message(STATUS "build_type: ${CMAKE_BUILD_TYPE}")
message(STATUS "paths:")
message(STATUS " - ${CMAKE_INSTALL_PREFIX}")
message(STATUS " - ${PROJECT_SOURCE_DIR}")
message(STATUS " - ${PROJECT_BINARY_DIR}")
message(STATUS)
message(STATUS "compiler:")
message(STATUS " - ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS " - ${CMAKE_CXX_COMPILER}")
message(STATUS)
message(STATUS "cmake:")
message(STATUS " - ${CMAKE_VERSION}")
message(STATUS " - ${CMAKE_COMMAND}")
message(STATUS " - ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS " - ${CMAKE_GENERATOR}")
message(STATUS " - ${CMAKE_BUILD_TOOL}")
message(STATUS)
# get_filename_component(CMAKE_COROUTINES_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/FindCoroutines.cmake ABSOLUTE)
# if(NOT EXISTS ${CMAKE_COROUTINES_MODULE_PATH})
# file(DOWNLOAD https://raw.githubusercontent.com/facebookexperimental/libunifex/main/cmake/FindCoroutines.cmake
# ${CMAKE_COROUTINES_MODULE_PATH}
# EXPECTED_HASH SHA256=0129305dd3d030de21684543fec9b1e7b0af7a67ed1bad4348c3259ecfb20cef
# )
# endif()
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
#
# Known STL-Compiler issues
# - https://github.com/microsoft/STL, issue 100
#
if(CMAKE_CXX_COMPILER_ID MATCHES Clang AND WIN32)
message(WARNING "clang-cl won't work with <experimental/coroutine>")
endif()
find_package(Coroutines REQUIRED)
find_package(Threads REQUIRED) # Threads::Threads
find_package(fmt CONFIG REQUIRED) # fmt::fmt-header-only
find_package(spdlog CONFIG REQUIRED) # spdlog::spdlog_header_only
# see https://github.com/microsoft/GSL/tree/v4.0.0
# check https://github.com/microsoft/vcpkg ms-gsl
# find_package(Microsoft.GSL 4.0 CONFIG REQUIRED) # Microsoft.GSL::GSL
add_library(coro_cpp17 src/coro.hpp src/coro.cpp)
add_library(coro_cpp20 src/coro.hpp src/coro.cpp)
add_library(coro_latest src/coro.hpp src/coro.cpp)
add_library(coro_action17 SHARED src/action.hpp src/action.cpp)
add_library(coro_action20 SHARED src/action.hpp src/action.cpp)
if(MSVC)
add_library(coro_clangcl INTERFACE)
target_compile_definitions(coro_clangcl
INTERFACE
__cpp_impl_coroutine=201902L
_DOWNLEVEL_COROUTINES_SUPPORTED
)
if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
target_compile_options(coro_cpp17 PRIVATE "SHELL:/clang:-std=c++20" "SHELL:/clang:-fcoroutines-ts")
target_compile_options(coro_action17 PRIVATE "SHELL:/clang:-std=c++20")
target_link_libraries(coro_action17 PRIVATE coro_cpp17 coro_clangcl)
target_link_libraries(coro_action20 PRIVATE coro_cpp20 coro_clangcl)
else()
target_compile_options(coro_cpp17 PUBLIC /std:c++17 /await PRIVATE /Zc:__cplusplus)
target_compile_options(coro_action17 PRIVATE /Zc:__cplusplus)
target_link_libraries(coro_action17 PRIVATE coro_cpp17)
target_link_libraries(coro_action20 PRIVATE coro_cpp20)
endif()
target_compile_options(coro_cpp20 PUBLIC /std:c++20 PRIVATE /Zc:__cplusplus)
target_compile_options(coro_latest PUBLIC /std:c++latest PRIVATE /Zc:__cplusplus)
target_compile_options(coro_action20 PRIVATE /Zc:__cplusplus)
elseif(CMAKE_CXX_COMPILER_ID MATCHES Clang)
target_compile_options(coro_cpp17 PUBLIC -std=c++17 -fcoroutines-ts)
target_compile_options(coro_cpp20 PUBLIC -std=c++20)
target_compile_options(coro_latest PUBLIC -std=c++2b)
target_link_libraries(coro_action17 PRIVATE coro_cpp17)
target_link_libraries(coro_action20 PRIVATE coro_cpp20)
elseif(CMAKE_CXX_COMPILER_ID MATCHES GNU)
# ...
endif()
if(WITH_GCD) # libdispatch
if(APPLE)
find_library(DISPATCH_LIBPATH NAMES CoreFoundation REQUIRED)
elseif(WIN32)
find_library(DISPATCH_LIBPATH NAMES dispatch REQUIRED)
find_library(BLOCKS_RUNTIME_LIBPATH NAMES BlocksRuntime REQUIRED)
endif()
add_library(coro_gcd17 SHARED src/gcd.hpp src/gcd.cpp)
set_target_properties(coro_gcd17 PROPERTIES CXX_STANDARD 17)
target_include_directories(coro_gcd17 PRIVATE src)
target_link_libraries(coro_gcd17 PRIVATE ${DISPATCH_LIBPATH} ${BLOCKS_RUNTIME_LIBPATH} coro_cpp17 coro_action17 spdlog::spdlog)
endif()
return()
string(TOLOWER ${CMAKE_SYSTEM_NAME} system_name)
list(APPEND headers
src/coroutine/frame.h
src/coroutine/${system_name}.h
)
add_library(coroutine
${headers}
# src/frame.cpp
# src/${system_name}.cpp
src/libmain.cpp
)
set_target_properties(coroutine
PROPERTIES
PUBLIC_HEADER "${headers}"
WINDOWS_EXPORT_ALL_SYMBOLS true
CXX_STANDARD_REQUIRED true
CXX_STANDARD 20
)
target_include_directories(coroutine
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_link_libraries(coroutine
PRIVATE
Threads::Threads
fmt::fmt-header-only
spdlog::spdlog_header_only
)
# compiler options / macro hints
if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
if(WIN32)
# 'target_compile_options' removes duplicated -Xclang directive.
# avoide the removal using cmake flag variable
target_compile_options(coroutine
PUBLIC
"/clang:-std=c++20" # c++2b for experiment?
PRIVATE
"/clang:-fms-compatibility-version=1900"
# -Wall -Wextra -ferror-limit=5
)
# clang 13: `__cpp_coroutines` macro is 201703L. `__cpp_lib_coroutine` is NOT defined
target_compile_definitions(coroutine
PUBLIC
# force feature activation.
# see https://github.com/llvm/llvm-project/blob/release/13.x/clang/lib/Frontend/InitPreprocessor.cpp
__cpp_impl_coroutine=201902L
# make <yvals_core.h> define __cpp_lib_coroutine
# see https://github.com/microsoft/STL, issue 1730, 2510
_DOWNLEVEL_COROUTINES_SUPPORTED
)
elseif(UNIX OR APPLE)
target_compile_options(coroutine
PUBLIC
-stdlib=libc++
-fcoroutines-ts
)
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES GNU)
target_compile_options(coroutine
PUBLIC
-fcoroutines
)
target_link_libraries(coroutine
PUBLIC
stdc++
)
elseif(MSVC)
# select between C++ Coroutines TS & C++ 20 Coroutines
# if(support_intrinsic_builtin AND has_coroutine)
# target_compile_options(coroutine
# PUBLIC
# /std:c++20
# )
# else()
# target_compile_options(coroutine
# PUBLIC
# /std:c++17 /await
# )
# endif()
# see https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus
target_compile_options(coroutine
PRIVATE
/Zc:__cplusplus
/JMC-
)
endif()
# compile definition and linkage
if(WIN32)
target_compile_definitions(coroutine
PRIVATE
WIN32_LEAN_AND_MEAN NOMINMAX
)
elseif(CMAKE_SYSTEM_NAME MATCHES Linux)
if(ANDROID)
target_link_libraries(coroutine
PUBLIC
${ANDROID_STL} # expect c++_shared
)
else()
target_link_libraries(coroutine
PUBLIC
rt
)
endif()
elseif(UNIX OR APPLE)
target_link_libraries(coroutine
PUBLIC
c++
)
endif()
install(TARGETS coroutine
EXPORT coroutine-config
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
#
# export declared cmake targets
#
# 'coroutine-targets' is indeed better name, but without using 'configure_file()'
# the exporting step will be more complicated for non-CMake users.
# just merge all contents into the file 'coroutine-config.cmake'
#
install(EXPORT ${PROJECT_NAME}-config
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME} # share/coroutine
)
#
# generate/install config & version info
#
include(CMakePackageConfigHelpers)
set(VERSION_FILE_PATH ${CMAKE_BINARY_DIR}/cmake/${PROJECT_NAME}-config-version.cmake)
write_basic_package_version_file(${VERSION_FILE_PATH}
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
install(FILES ${VERSION_FILE_PATH}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME} # share/coroutine
)
#
# for testing, CTest will be used
#
if(NOT BUILD_TESTING)
message(STATUS "Test is disabled.")
return()
endif()
enable_testing()
find_package(Catch2 2.13 CONFIG REQUIRED) # Catch2::Catch2
# create a test exe with the given name ...
add_executable(coroutine_test_suite
test/test_main.cpp
test/test_action.cpp
)
set_target_properties(coroutine_test_suite
PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED true
)
# target_compile_definitions(coroutine_test_suite
# PRIVATE
# CATCH_CONFIG_FAST_COMPILE
# )
target_link_libraries(coroutine_test_suite
PRIVATE
Catch2::Catch2 coroutine
)
if(coroutine_IS_TOP_LEVEL)
install(TARGETS coroutine_test_suite DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
add_test(NAME test_exception COMMAND coroutine_test_suite "[exception]")
# create_ctest( article_russian_roulette coroutine_portable )
#
# <coroutine/yield.hpp>
#
#
# <coroutine/frame.h>
# <coroutine/return.h>
#
#
# <coroutine/windows.h>
# <coroutine/unix.h>, <coroutine/linux.h>
# <coroutine/pthread.h>
#
if(APPLE)
add_test(NAME test_dispatch COMMAND coroutine_test_suite "[dispatch]")
endif()
#
# <coroutine/net.h>
#
#
# <coroutine/channel.hpp>
#
if(CMAKE_CXX_COMPILER_ID MATCHES GNU)
message(WARNING "using gcc: the compiler may not work for current code")
endif()