@@ -100,6 +100,7 @@ if(TARGET std::coroutines)
100
100
return ()
101
101
endif ()
102
102
103
+ include (CheckCXXCompilerFlag)
103
104
include (CMakePushCheckState)
104
105
include (CheckIncludeFileCXX)
105
106
include (CheckCXXSourceCompiles)
@@ -108,13 +109,16 @@ cmake_push_check_state()
108
109
109
110
set (CMAKE_REQUIRED_QUIET ${Coroutines_FIND_QUIETLY} )
110
111
111
- # All of our tests required C++17 or later
112
- if (("x${CMAKE_CXX_COMPILER_ID} " MATCHES "x.*Clang" AND "x${CMAKE_CXX_SIMULATE_ID} " STREQUAL "xMSVC" ) OR "x${CMAKE_CXX_COMPILER_ID} " STREQUAL "xMSVC" )
113
- set (_CXX_COROUTINES_STD17 "/std:c++17" )
114
- set (_CXX_COROUTINES_AWAIT "/await" )
115
- else ()
116
- set (_CXX_COROUTINES_STD17 "-std=c++17" )
117
- set (_CXX_COROUTINES_AWAIT "-fcoroutines-ts" )
112
+ check_cxx_compiler_flag(/await _CXX_COROUTINES_SUPPORTS_MS_FLAG)
113
+ check_cxx_compiler_flag(-fcoroutines-ts _CXX_COROUTINES_SUPPORTS_TS_FLAG)
114
+ check_cxx_compiler_flag(-fcoroutines _CXX_COROUTINES_SUPPORTS_CORO_FLAG)
115
+
116
+ if (_CXX_COROUTINES_SUPPORTS_MS_FLAG)
117
+ set (_CXX_COROUTINES_EXTRA_FLAGS "/await" )
118
+ elseif (_CXX_COROUTINES_SUPPORTS_TS_FLAG)
119
+ set (_CXX_COROUTINES_EXTRA_FLAGS "-fcoroutines-ts" )
120
+ elseif (_CXX_COROUTINES_SUPPORTS_CORO_FLAG)
121
+ set (_CXX_COROUTINES_EXTRA_FLAGS "-fcoroutines" )
118
122
endif ()
119
123
120
124
# Normalize and check the component list we were given
@@ -142,6 +146,13 @@ endif()
142
146
143
147
if (find_final)
144
148
check_include_file_cxx("coroutine" _CXX_COROUTINES_HAVE_HEADER)
149
+ if (NOT _CXX_COROUTINES_HAVE_HEADER)
150
+ cmake_push_check_state()
151
+ set (CMAKE_REQUIRED_FLAGS "${_CXX_COROUTINES_EXTRA_FLAGS} " )
152
+ check_include_file_cxx("coroutine" _CXX_COROUTINES_HAVE_HEADER_WITH_FLAG)
153
+ set (_CXX_COROUTINES_HAVE_HEADER ${_CXX_COROUTINES_HAVE_HEADER_WITH_FLAG} )
154
+ cmake_pop_check_state()
155
+ endif ()
145
156
mark_as_advanced (_CXX_COROUTINES_HAVE_HEADER)
146
157
if (_CXX_COROUTINES_HAVE_HEADER)
147
158
# We found the non-experimental header. Don't bother looking for the
@@ -154,6 +165,13 @@ endif()
154
165
155
166
if (find_experimental)
156
167
check_include_file_cxx("experimental/coroutine" _CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER)
168
+ if (NOT _CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER)
169
+ cmake_push_check_state()
170
+ set (CMAKE_REQUIRED_FLAGS "${_CXX_COROUTINES_EXTRA_FLAGS} " )
171
+ check_include_file_cxx("experimental/coroutine" _CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER_WITH_FLAG)
172
+ set (_CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER ${_CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER_WITH_FLAG} )
173
+ cmake_pop_check_state()
174
+ endif ()
157
175
mark_as_advanced (_CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER)
158
176
else ()
159
177
set (_CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER FALSE )
@@ -188,7 +206,7 @@ if(CXX_COROUTINES_HAVE_COROUTINES)
188
206
int result;
189
207
present get_return_object() { return present{*this}; }
190
208
@CXX_COROUTINES_NAMESPACE@::suspend_never initial_suspend() { return {}; }
191
- @CXX_COROUTINES_NAMESPACE@::suspend_always final_suspend() { return {}; }
209
+ @CXX_COROUTINES_NAMESPACE@::suspend_always final_suspend() noexcept { return {}; }
192
210
void return_value(int i) { result = i; }
193
211
void unhandled_exception() {}
194
212
};
@@ -223,7 +241,7 @@ if(CXX_COROUTINES_HAVE_COROUTINES)
223
241
224
242
if (NOT CXX_COROUTINES_NO_AWAIT_NEEDED)
225
243
# Add the -fcoroutines-ts (or /await) flag
226
- set (CMAKE_REQUIRED_FLAGS "${_CXX_COROUTINES_STD17} ${_CXX_COROUTINES_AWAIT } " )
244
+ set (CMAKE_REQUIRED_FLAGS "${_CXX_COROUTINES_EXTRA_FLAGS } " )
227
245
check_cxx_source_compiles("${code} " CXX_COROUTINES_AWAIT_NEEDED)
228
246
set (can_link ${CXX_COROUTINES_AWAIT_NEEDED} )
229
247
endif ()
@@ -235,7 +253,7 @@ if(CXX_COROUTINES_HAVE_COROUTINES)
235
253
if (CXX_COROUTINES_NO_AWAIT_NEEDED)
236
254
# Nothing to add...
237
255
elseif (CXX_COROUTINES_AWAIT_NEEDED)
238
- target_compile_options (std::coroutines INTERFACE ${_CXX_COROUTINES_AWAIT } )
256
+ target_compile_options (std::coroutines INTERFACE ${_CXX_COROUTINES_EXTRA_FLAGS } )
239
257
endif ()
240
258
else ()
241
259
set (CXX_COROUTINES_HAVE_COROUTINES FALSE )
@@ -247,5 +265,5 @@ cmake_pop_check_state()
247
265
set (Coroutines_FOUND ${_found} CACHE BOOL "TRUE if we can compile and link a program using std::coroutines" FORCE)
248
266
249
267
if (Coroutines_FIND_REQUIRED AND NOT Coroutines_FOUND)
250
- message (FATAL_ERROR "Cannot compile simple program using std::coroutines" )
268
+ message (FATAL_ERROR "Cannot compile simple program using std::coroutines. Is C++17 or later activated? " )
251
269
endif ()
0 commit comments