#
# This file sets up
#
-# DEAL_II_WITH_CXX11
# DEAL_II_WITH_CXX14
#
# DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE
#
SET_IF_EMPTY(DEAL_II_CXX_VERSION_FLAG "${DEAL_II_CXX11_FLAG}")
-IF(DEAL_II_WITH_CXX14 AND DEFINED DEAL_II_WITH_CXX11 AND NOT DEAL_II_WITH_CXX11)
- MESSAGE(FATAL_ERROR
- "Compiling deal.II with C++14 support (i.e., DEAL_II_WITH_CXX14=ON) requires"
- " that C++11 support not be explicitly disabled (i.e., DEAL_II_WITH_CXX11 may"
- " not be set to a logically false value)."
- )
-ENDIF()
-
-IF(DEFINED DEAL_II_WITH_CXX11 AND NOT DEAL_II_WITH_CXX11)
- SET(DEAL_II_WITH_CXX14 OFF CACHE STRING "" FORCE)
-ENDIF()
-
-
#
# Check the user supplied DEAL_II_CXX_VERSION_FLAG
#
)
ENDIF()
+ #
+ # A quick check that may, hopefully, give a more useful error message
+ #
+ IF("${DEAL_II_CXX_VERSION_FLAG}" STREQUAL "-std=c++98" OR
+ "${DEAL_II_CXX_VERSION_FLAG}" STREQUAL "-std=c++03")
+ MESSAGE(FATAL_ERROR
+ "\ndeal.II no longer supports compilation under the C++98 or C++03 "
+ "standards: please either specify a value for DEAL_II_CXX_VERSION_FLAG "
+ "corresponding to C++11 or leave the field blank (so that CMake may "
+ "automatically determine a valid version flag).\n"
+ )
+ ENDIF()
+
SET(_user_provided_cxx_version_flag TRUE)
+ELSE()
+ SET(_user_provided_cxx_version_flag FALSE)
ENDIF()
#
-# A macro to check for various C++11 and C++14 flags
+# A macro to check for various C++ version flags
#
MACRO(_check_cxx_flag _suffix)
IF(NOT "${DEAL_II_CXX_VERSION_FLAG}" STREQUAL "")
# Set CMAKE_REQUIRED_FLAGS for the unit tests
- MESSAGE(STATUS "Using C++ version flag \"${DEAL_II_CXX_VERSION_FLAG}\"")
PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
#
ENDIF()
ENDIF()
-
#
-# Check for proper C++11 support and set up DEAL_II_HAVE_CXX11:
+# Check for proper C++11 support.
#
-IF(NOT DEFINED DEAL_II_WITH_CXX11 OR DEAL_II_WITH_CXX11)
-
- IF("${DEAL_II_CXX_VERSION_FLAG}" STREQUAL "")
- _check_version("11" "0x")
- ENDIF()
-
- IF(NOT "${DEAL_II_CXX_VERSION_FLAG}" STREQUAL "")
- # Set CMAKE_REQUIRED_FLAGS for the unit tests
- MESSAGE(STATUS "Using C++ version flag \"${DEAL_II_CXX_VERSION_FLAG}\"")
- PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
-
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <array>
- std::array<int,3> p;
- int main(){ p[0]; return 0; }
- "
- DEAL_II_HAVE_CXX11_ARRAY)
-
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <condition_variable>
- std::condition_variable c;
- int main(){ c.notify_all(); return 0; }
- "
- DEAL_II_HAVE_CXX11_CONDITION_VARIABLE)
-
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <functional>
- void f(int, double){}
- std::function<void (int)> g = std::bind (f, std::placeholders::_1,1.1);
- int main(){ return 0; }
- "
- DEAL_II_HAVE_CXX11_FUNCTIONAL)
-
- # Make sure we don't run into GCC bug 35569
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <functional>
- void f(int){}
- using namespace std;
- using namespace std::placeholders;
- int main(){ bind(multiplies<int>(),4,_1)(5); return 0; }
- "
- DEAL_II_HAVE_CXX11_FUNCTIONAL_GCCBUG35569_OK)
- # clang libc++ bug, see https://llvm.org/bugs/show_bug.cgi?id=20084
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <functional>
- struct A { void foo() const {} };
- int main() { A a; std::bind(&A::foo,a)(); return 0; }
- "
- DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK)
-
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <memory>
- std::shared_ptr<int> p(new int(3));
- int main(){ return 0; }
- "
- DEAL_II_HAVE_CXX11_SHARED_PTR)
-
- PUSH_CMAKE_REQUIRED("-pthread")
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <thread>
- void f(int){}
- int main(){ std::thread t(f,1); t.join(); return 0; }
- "
- DEAL_II_HAVE_CXX11_THREAD)
- RESET_CMAKE_REQUIRED()
- PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
+#
+# Set up a default C++11 flag in case both C++14 detection failed and the user
+# did not specify a flag:
+#
+IF("${DEAL_II_CXX_VERSION_FLAG}" STREQUAL "")
+ _check_version("11" "0x")
+ENDIF()
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <mutex>
- std::mutex m;
- int main(){ m.lock(); return 0; }
- "
- DEAL_II_HAVE_CXX11_MUTEX)
+PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
+CHECK_CXX_SOURCE_COMPILES(
+ "
+ // common C++11 include files
+ #include <array>
+ #include <condition_variable>
+ #include <type_traits>
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <tuple>],
- std::tuple<int,double,char> p(1,1.1,'a');
- int main(){ return 0; }
- "
- DEAL_II_HAVE_CXX11_TUPLE)
+ // type traits functionality
+ constexpr auto m0 = std::is_trivial<double>::value;
+ constexpr auto m1 = std::is_standard_layout<double>::value;
+ constexpr auto m2 = std::is_pod<double>::value;
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <type_traits>
- const bool m0 = std::is_trivial<double>::value;
- const bool m1 = std::is_standard_layout<double>::value;
- const bool m2 = std::is_pod<double>::value;
- int main(){ return 0; }
- "
- DEAL_II_HAVE_CXX11_TYPE_TRAITS)
+ // thread_local storage specification
+ thread_local std::array<int,3> p;
+ std::condition_variable c;
- #
- # On Mac OS-X 10.9 with recent gcc compilers in C++11 mode linking to
- # some standard C library functions, notably toupper and tolower, fail
- # due to unresolved references to these functions.
- #
- # Thanks to Denis Davydov for the testcase.
- #
- # Matthias Maier, 2013
- #
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <ctype.h>
- int main ()
- {
- char c = toupper('a');
- }
- "
- DEAL_II_HAVE_CXX11_MACOSXC99BUG_OK)
+ // check the version language macro
+ #if !(__cplusplus >= 201103L)
+ # error \"insufficient support for C++11\"
+ #endif
+ int main()
+ {
+ p[0];
+ c.notify_all();
+ }
+ "
+ DEAL_II_HAVE_CXX11_FEATURES)
- #
- # icc-13 triggers an internal compiler error when compiling
- # std::numeric_limits<...>::min() with -std=c++0x [1].
- #
- # Reported by Ted Kord.
- #
- # - Matthias Maier, 2013
- #
- # [1] http://software.intel.com/en-us/forums/topic/328902
- #
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <limits>
- struct Integer
- {
- static const int min_int_value;
- static const int max_int_value;
- };
- const int Integer::min_int_value = std::numeric_limits<int>::min();
- const int Integer::max_int_value = std::numeric_limits<int>::max();
- int main() { return 0; }
- "
- DEAL_II_HAVE_CXX11_ICCNUMERICLIMITSBUG_OK)
-
+# clang libc++ bug, see https://llvm.org/bugs/show_bug.cgi?id=20084
+CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <functional>
+ struct A { void foo() const {} };
+ int main() { A a; std::bind(&A::foo,a)(); return 0; }
+ "
+ DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK)
- #
- # icc-14.0.0 has an astonishing bug [1] where it hits an internal compiler
- # error when run in C++11 mode with libstdc++-4.7 (from gcc).
- #
- # We just disable C++11 mode in this case
- #
- # [1] http://software.intel.com/en-us/forums/topic/472385
- #
- # - Matthias Maier, 2013
- #
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <vector>
- template<typename T> void foo()
- {
- std::vector<double> data(100);
- }
- int main()
- {
- foo<int>();
- }
- "
- DEAL_II_HAVE_CXX11_ICCLIBSTDCPP47CXX11BUG_OK)
+#
+# On Mac OS-X 10.9 with recent gcc compilers in C++11 mode linking to
+# some standard C library functions, notably toupper and tolower, fail
+# due to unresolved references to these functions.
+#
+# Thanks to Denis Davydov for the testcase.
+#
+# Matthias Maier, 2013
+#
+CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <ctype.h>
+ int main ()
+ {
+ char c = toupper('a');
+ }
+ "
+ DEAL_II_HAVE_CXX11_MACOSXC99BUG_OK)
- RESET_CMAKE_REQUIRED()
- ENDIF()
- IF( DEAL_II_HAVE_CXX11_ARRAY AND
- DEAL_II_HAVE_CXX11_CONDITION_VARIABLE AND
- DEAL_II_HAVE_CXX11_FUNCTIONAL AND
- DEAL_II_HAVE_CXX11_FUNCTIONAL_GCCBUG35569_OK AND
- DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK AND
- DEAL_II_HAVE_CXX11_SHARED_PTR AND
- DEAL_II_HAVE_CXX11_THREAD AND
- DEAL_II_HAVE_CXX11_MUTEX AND
- DEAL_II_HAVE_CXX11_TUPLE AND
- DEAL_II_HAVE_CXX11_TYPE_TRAITS AND
- DEAL_II_HAVE_CXX11_MACOSXC99BUG_OK AND
- DEAL_II_HAVE_CXX11_ICCNUMERICLIMITSBUG_OK AND
- DEAL_II_HAVE_CXX11_ICCLIBSTDCPP47CXX11BUG_OK )
- SET(DEAL_II_HAVE_CXX11 TRUE)
- ENDIF()
-ENDIF()
+#
+# icc-13 triggers an internal compiler error when compiling
+# std::numeric_limits<...>::min() with -std=c++0x [1].
+#
+# Reported by Ted Kord.
+#
+# - Matthias Maier, 2013
+#
+# [1] http://software.intel.com/en-us/forums/topic/328902
+#
+CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <limits>
+ struct Integer
+ {
+ static const int min_int_value;
+ static const int max_int_value;
+ };
+ const int Integer::min_int_value = std::numeric_limits<int>::min();
+ const int Integer::max_int_value = std::numeric_limits<int>::max();
+ int main() { return 0; }
+ "
+ DEAL_II_HAVE_CXX11_ICCNUMERICLIMITSBUG_OK)
#
-# Finally disable cxx14 if cxx11 detection failed for whatever reason. This
-# can happen if any of our compile checks above fails, for example threading
-# support.
-#
-IF (DEAL_II_HAVE_CXX14 AND NOT DEAL_II_HAVE_CXX11)
- MESSAGE(STATUS "Disabling CXX14 support because CXX11 detection failed.")
- SET(DEAL_II_HAVE_CXX14 FALSE)
+# icc-14.0.0 has an astonishing bug [1] where it hits an internal compiler
+# error when run in C++11 mode with libstdc++-4.7 (from gcc).
+#
+# [1] http://software.intel.com/en-us/forums/topic/472385
+#
+# - Matthias Maier, 2013
+#
+CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <vector>
+ template<typename T> void foo()
+ {
+ std::vector<double> data(100);
+ }
+ int main()
+ {
+ foo<int>();
+ }
+ "
+ DEAL_II_HAVE_CXX11_ICCLIBSTDCPP47CXX11BUG_OK)
+RESET_CMAKE_REQUIRED()
+
+IF( DEAL_II_HAVE_CXX11_FEATURES AND
+ DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK AND
+ DEAL_II_HAVE_CXX11_MACOSXC99BUG_OK AND
+ DEAL_II_HAVE_CXX11_ICCNUMERICLIMITSBUG_OK AND
+ DEAL_II_HAVE_CXX11_ICCLIBSTDCPP47CXX11BUG_OK )
+ # we require C++11 so this is fine
+ELSE()
+ MESSAGE(FATAL_ERROR "\n"
+ "The current combination of compiler and C++ version flag is missing some "
+ "features of the C++11 version of the language necessary for compiling "
+ "deal.II. Please ensure that the CMake variable DEAL_II_CXX_VERSION_FLAG is "
+ "set to the correct flag to enable C++11 support; if it is already set and "
+ "you still see this message then you will need to upgrade your compiler.\n")
ENDIF()
+
#
-# Set up a configuration options for C++11 and C++14 support:
+# Set up a configuration option for C++14 support:
#
-OPTION(DEAL_II_WITH_CXX11
- "Compile deal.II using C++11 language standard."
- ${DEAL_II_HAVE_CXX11}
- )
-LIST(APPEND DEAL_II_FEATURES CXX11)
-SET(FEATURE_CXX11_PROCESSED TRUE)
-
OPTION(DEAL_II_WITH_CXX14
"Compile deal.II using C++14 language standard."
${DEAL_II_HAVE_CXX14}
SET(FEATURE_CXX14_PROCESSED TRUE)
#
-# Bail out if user requested C++11 support (DEAL_II_WITH_CXX11) but support
-# is not available due to above tests (DEAL_II_HAVE_CXX11):
+# Bail out if user requested support for a certain C++ version (e.g.,
+# DEAL_II_WITH_CXX14) but support is not available due to above tests
#
MACRO(_bailout _version)
ENDIF()
ENDMACRO()
-_bailout("11")
_bailout("14")
-IF (DEAL_II_WITH_CXX14)
- ADD_FLAGS(DEAL_II_CXX_FLAGS "${DEAL_II_CXX_VERSION_FLAG}")
- MESSAGE(STATUS "DEAL_II_WITH_CXX11 successfully set up")
- MESSAGE(STATUS "DEAL_II_WITH_CXX14 successfully set up")
-ELSEIF(DEAL_II_WITH_CXX11)
+#
+# Some compilers (notably GCC6 and up) default to C++14 (more exactly, GNU++14,
+# which contains some extensions) but most compilers default to C++98. Hence,
+# try to avoid adding an extra flag by doing one last test:
+#
+RESET_CMAKE_REQUIRED()
+CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <memory>
+ int main()
+ {
+ std::unique_ptr<int> p0;
+ auto p1 = std::move(p0);
+ }
+ "
+ DEAL_II_COMPILER_DEFAULTS_TO_CXX11_OR_NEWER)
+
+IF(_user_provided_cxx_version_flag OR
+ NOT DEAL_II_COMPILER_DEFAULTS_TO_CXX11_OR_NEWER OR
+ (DEAL_II_COMPILER_DEFAULTS_TO_CXX11_OR_NEWER AND NOT DEAL_II_WITH_CXX14))
ADD_FLAGS(DEAL_II_CXX_FLAGS "${DEAL_II_CXX_VERSION_FLAG}")
- MESSAGE(STATUS "DEAL_II_WITH_CXX11 successfully set up")
-ELSE()
- MESSAGE(STATUS "DEAL_II_WITH_CXX14 and DEAL_II_WITH_CXX11 are both disabled")
+ MESSAGE(STATUS "Using C++ version flag \"${DEAL_II_CXX_VERSION_FLAG}\"")
ENDIF()
# #
########################################################################
-#
-# Some compilers (such as Intel 15.3 and GCC 4.9.2) support the flags
-# "-std=c++11" and "-std=c++14" but do not support
-# 'std::is_trivially_copyable', so check for support in C++11 or newer.
-#
-IF(DEAL_II_WITH_CXX11)
- PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
- CHECK_CXX_SOURCE_COMPILES(
- "
+PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
+CHECK_CXX_SOURCE_COMPILES(
+ "
#include <type_traits>
int main(){ std::is_trivially_copyable<int> bob; }
"
- DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE)
- RESET_CMAKE_REQUIRED()
-ELSE()
- SET(DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE FALSE)
-ENDIF()
+ DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE)
CHECK_CXX_SOURCE_COMPILES(
"
# - Timo Heister, 2015
#
-# This test requires C++11
-IF(DEAL_II_WITH_CXX11)
- PUSH_CMAKE_REQUIRED("${DEAL_II_CXX_VERSION_FLAG}")
- IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
- CHECK_CXX_SOURCE_RUNS(
- "
- #include <cfenv>
- #include <limits>
- #include <sstream>
+IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
+ CHECK_CXX_SOURCE_RUNS(
+ "
+ #include <cfenv>
+ #include <limits>
+ #include <sstream>
- int main()
- {
- feenableexcept(FE_DIVBYZERO|FE_INVALID);
- std::ostringstream description;
- const double lower_bound = -std::numeric_limits<double>::max();
+ int main()
+ {
+ feenableexcept(FE_DIVBYZERO|FE_INVALID);
+ std::ostringstream description;
+ const double lower_bound = -std::numeric_limits<double>::max();
- description << lower_bound;
+ description << lower_bound;
- return 0;
- }
- "
- DEAL_II_HAVE_FP_EXCEPTIONS)
- ELSE()
- #
- # If we are not allowed to do platform introspection, just test whether
- # we can compile above code.
- #
- CHECK_CXX_SOURCE_COMPILES(
- "
- #include <cfenv>
- #include <limits>
- #include <sstream>
+ return 0;
+ }
+ "
+ DEAL_II_HAVE_FP_EXCEPTIONS)
+ELSE()
+ #
+ # If we are not allowed to do platform introspection, just test whether
+ # we can compile above code.
+ #
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <cfenv>
+ #include <limits>
+ #include <sstream>
- int main()
- {
- feenableexcept(FE_DIVBYZERO|FE_INVALID);
- std::ostringstream description;
- const double lower_bound = -std::numeric_limits<double>::max();
+ int main()
+ {
+ feenableexcept(FE_DIVBYZERO|FE_INVALID);
+ std::ostringstream description;
+ const double lower_bound = -std::numeric_limits<double>::max();
- description << lower_bound;
+ description << lower_bound;
- return 0;
- }
- "
- DEAL_II_HAVE_FP_EXCEPTIONS)
- ENDIF()
- RESET_CMAKE_REQUIRED()
-ELSE()
- SET(DEAL_II_HAVE_FP_EXCEPTIONS FALSE)
+ return 0;
+ }
+ "
+ DEAL_II_HAVE_FP_EXCEPTIONS)
ENDIF()
#
}
"
DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS)
-
+RESET_CMAKE_REQUIRED()