Skip to content
Snippets Groups Projects
Commit 4d59debb authored by Jö Fahlke's avatar Jö Fahlke
Browse files

[threads][cmake] Guess the flags needed to get working threading support.

We simply get the flags from find_package(Thread).  If we are compiling
natively, we run a test program to check whether that worked.  Otherwise we
print a warning and assume that threading works.
parent 14cbee71
No related branches found
No related tags found
No related merge requests found
...@@ -197,4 +197,81 @@ check_cxx_source_compiles(" ...@@ -197,4 +197,81 @@ check_cxx_source_compiles("
" HAVE_NOEXCEPT_SPECIFIER " HAVE_NOEXCEPT_SPECIFIER
) )
# find the threading library
find_package(Threads)
set(STDTHREAD_LINK_FLAGS "${CMAKE_THREAD_LIBS_INIT}"
CACHE STRING "Linker flags needed to get working C++11 threads support")
# set linker flags
#
# in all implementations I know it is sufficient to set the linker flags when
# linking the final executable, so this should work. In cmake, this appears
# to only work when building the project however, not for later config tests
# (contrary to CMAKE_CXX_FLAGS). Luckily, later tests don't seem to use any
# threading... (except for our own sanity check)
if(NOT STDTHREAD_LINK_FLAGS STREQUAL "")
#set(vars CMAKE_EXE_LINKER_FLAGS ${CMAKE_CONFIGURATION_TYPES})
# CMAKE_CONFIGURATION_TYPES seems to be empty. Use the configurations from
# adding -std=c++11 above instead.
set(vars CMAKE_EXE_LINKER_FLAGS DEBUG MINSIZEREL RELEASE RELWITHDEBINFO)
string(REPLACE ";" ";CMAKE_EXE_LINKER_FLAGS_" vars "${vars}")
string(TOUPPER "${vars}" vars)
foreach(var ${vars})
if(NOT ${var} STREQUAL "")
set(${var} "${${var}} ${STDTHREAD_LINK_FLAGS}")
endif(NOT ${var} STREQUAL "")
endforeach(var ${vars})
endif(NOT STDTHREAD_LINK_FLAGS STREQUAL "")
include(CheckCXXSourceRuns)
# check that the found configuration works
if(CMAKE_CROSSCOMPILING)
message(WARNING "Crosscompiling, cannot run test program to see whether "
"std::thread works. Assuming that the found configuration does indeed "
"work.")
endif(CMAKE_CROSSCOMPILING)
if(NOT DEFINED STDTHREAD_WORKS)
if(NOT CMAKE_CROSSCOMPILING)
# The value is not in the cache, so run check
cmake_push_check_state()
# tests seem to ignore CMAKE_EXE_LINKER_FLAGS
set(CMAKE_REQUIRED_LIBRARIES "${STDTHREAD_LINK_FLAGS} ${CMAKE_REQUIRED_LIBRARIES}")
check_cxx_source_runs("
#include <thread>
void dummy() {}
int main() {
std::thread t(dummy);
t.join();
}
" STDTHREAD_WORKS)
cmake_pop_check_state()
endif(NOT CMAKE_CROSSCOMPILING)
# put the found value into the cache. Put it there even if we're
# cross-compiling, so the user can find it. Use FORCE:
# check_cxx_source_runs() already puts the value in the cache but without
# documentation; also the "if(NOT DEFINED STDTHREAD_WORKS)" will prevent us
# from overwriting a value set by the user.
set(STDTHREAD_WORKS "${STDTHREAD_WORKS}"
CACHE BOOL "Whether std::thread works." FORCE)
endif(NOT DEFINED STDTHREAD_WORKS)
if(NOT STDTHREAD_WORKS)
# Working C++11 threading support is required for dune. In particular to
# make things like lazyly initialized caches thread safe
# (e.g. QuadratureRules::rule(), which needs std::call_once()). If we don't
# include the correct options during linking, there will be very funny
# errors at runtime, ranging from segfaults to
#
# terminate called after throwing an instance of 'std::system_error'
# what(): Unknown error 18446744073709551615
message(FATAL_ERROR "Your system does not seem to have a working "
"implementation of std::thread. If it does, please set the linker flags "
"required to get std::thread working in the cache variable "
"STDTHREAD_LINK_FLAGS. If you think this test is wrong, set the cache "
"variable STDTHREAD_WORKS.")
endif(NOT STDTHREAD_WORKS)
cmake_pop_check_state() cmake_pop_check_state()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment