@@ -100,6 +100,7 @@ if(TARGET std::coroutines)
100100 return ()
101101endif ()
102102
103+ include (CheckCXXCompilerFlag)
103104include (CMakePushCheckState)
104105include (CheckIncludeFileCXX)
105106include (CheckCXXSourceCompiles)
@@ -108,13 +109,16 @@ cmake_push_check_state()
108109
109110set (CMAKE_REQUIRED_QUIET ${Coroutines_FIND_QUIETLY} )
110111
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" )
118122endif ()
119123
120124# Normalize and check the component list we were given
@@ -142,6 +146,13 @@ endif()
142146
143147if (find_final)
144148 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 ()
145156 mark_as_advanced (_CXX_COROUTINES_HAVE_HEADER)
146157 if (_CXX_COROUTINES_HAVE_HEADER)
147158 # We found the non-experimental header. Don't bother looking for the
@@ -154,6 +165,13 @@ endif()
154165
155166if (find_experimental)
156167 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 ()
157175 mark_as_advanced (_CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER)
158176else ()
159177 set (_CXX_COROUTINES_HAVE_EXPERIMENTAL_HEADER FALSE )
@@ -188,7 +206,7 @@ if(CXX_COROUTINES_HAVE_COROUTINES)
188206 int result;
189207 present get_return_object() { return present{*this}; }
190208 @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 {}; }
192210 void return_value(int i) { result = i; }
193211 void unhandled_exception() {}
194212 };
@@ -223,7 +241,7 @@ if(CXX_COROUTINES_HAVE_COROUTINES)
223241
224242 if (NOT CXX_COROUTINES_NO_AWAIT_NEEDED)
225243 # 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 } " )
227245 check_cxx_source_compiles("${code} " CXX_COROUTINES_AWAIT_NEEDED)
228246 set (can_link ${CXX_COROUTINES_AWAIT_NEEDED} )
229247 endif ()
@@ -235,7 +253,7 @@ if(CXX_COROUTINES_HAVE_COROUTINES)
235253 if (CXX_COROUTINES_NO_AWAIT_NEEDED)
236254 # Nothing to add...
237255 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 } )
239257 endif ()
240258 else ()
241259 set (CXX_COROUTINES_HAVE_COROUTINES FALSE )
@@ -247,5 +265,5 @@ cmake_pop_check_state()
247265set (Coroutines_FOUND ${_found} CACHE BOOL "TRUE if we can compile and link a program using std::coroutines" FORCE)
248266
249267if (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? " )
251269endif ()
0 commit comments