]> https://gitweb.dealii.org/ - dealii.git/commitdiff
CMake: try to be more friendly and export DEAL_II_WITH_CXX17 in deal.IIConfig.cmake
authorMatthias Maier <tamiko@43-1.org>
Fri, 22 May 2020 14:37:20 +0000 (09:37 -0500)
committerMatthias Maier <tamiko@43-1.org>
Sat, 23 May 2020 14:56:50 +0000 (09:56 -0500)
cmake/checks/check_01_cxx_features.cmake
cmake/config/CMakeLists.txt
include/deal.II/base/config.h.in

index 324f1995a7bc21eeb0b084d2ff85b9099868370e..116c5f023c6b90a95172dac647c8dc8774201955 100644 (file)
@@ -18,6 +18,7 @@
 #
 # This file sets up
 #
+#   DEAL_II_HAVE_CXX14
 #   DEAL_II_HAVE_CXX17
 #
 #   DEAL_II_HAVE_FP_EXCEPTIONS
 #                                                                      #
 ########################################################################
 
-#
-# Some old compiler versions default to C++98/03 rather than C++14. Inject
-# -std=c++14 into the compiler flags in this case.
-#
-IF((CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
-     AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1")
-    OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
-     AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0")
-    OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
-     AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0"))
-  MESSAGE(STATUS "Old compiler detected, setting -std=c++14")
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-std=c++14")
-ENDIF()
 
 #
-# Use compile flags specified in ${DEAL_II_CXX_FLAGS} for the following
-# tests:
+# We need compiler flags specified in ${DEAL_II_CXX_FLAGS} for all the
+# tests. Create a small macro to easily set CMAKE_REQUIRED_FLAGS
 #
+MACRO(_set_up_cmake_required)
+  RESET_CMAKE_REQUIRED()
+  SET(CMAKE_REQUIRED_FLAGS "")
 
-IF(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
-  SET(_werror_flag "/WX /EHsc")
-ELSE()
-  SET(_werror_flag "-Werror")
-ENDIF()
+  IF(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+    SET(_werror_flag "/WX")
+  ELSE()
+    SET(_werror_flag "-Werror")
+  ENDIF()
 
-ADD_FLAGS(CMAKE_REQUIRED_FLAGS "${DEAL_II_CXX_FLAGS} ${_werror_flag}")
-IF(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
-  ADD_FLAGS(CMAKE_REQUIRED_FLAGS "-Wno-unused-command-line-argument")
-ENDIF()
+  ADD_FLAGS(CMAKE_REQUIRED_FLAGS "${DEAL_II_CXX_FLAGS} ${_werror_flag}")
+  ENABLE_IF_SUPPORTED(CMAKE_REQUIRED_FLAGS "-Wno-unused-command-line-argument")
 
-#
-# Rerun all checks if compile flags change:
-#
-UNSET_IF_CHANGED(CHECK_CXX_FEATURES_FLAGS_SAVED
-  "${CMAKE_REQUIRED_FLAGS}"
-  DEAL_II_HAVE_CXX17_FEATURES
-  DEAL_II_HAVE_CXX17_CONSTEXPR_LAMBDA_BUG_OK
-  DEAL_II_HAVE_CXX14_FEATURES
-  DEAL_II_HAVE_CXX14_CLANGAUTODEBUG_BUG_OK
-  DEAL_II_HAVE_CXX11_FEATURES
-  DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK
-  DEAL_II_HAVE_FP_EXCEPTIONS
-  DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS
-  DEAL_II_HAVE_CXX17_ATTRIBUTE_FALLTHROUGH
-  DEAL_II_HAVE_ATTRIBUTE_FALLTHROUGH
-  DEAL_II_CXX14_CONSTEXPR_BUG_OK
-  )
+  # Let's put the user supplied `DEAL_II_CXX_FLAGS_SAVED` last so that we
+  # never override a user supplied -std=c++XY flag in our tests.
+  ADD_FLAGS(CMAKE_REQUIRED_FLAGS "${DEAL_II_CXX_FLAGS_SAVED}")
+ENDMACRO()
 
 
 #
-# Test that the c++17 attributes are supported.
+# Wrap the following checks into a macro to make it easier to rerun them.
 #
-CHECK_CXX_SOURCE_COMPILES(
-  "
-  #include <iostream>
+MACRO(_test_cxx17_support)
 
-  #if __cplusplus < 201703L && !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
-  #  error \"insufficient support for C++17\"
-  #endif
-
-  [[nodiscard]] int test_nodiscard()
-  {
-    return 1;
-  }
+  UNSET_IF_CHANGED(CHECK_CXX17_FEATURES_FLAGS_SAVED
+    "${CMAKE_REQUIRED_FLAGS}"
+    DEAL_II_HAVE_CXX17_FEATURES
+    DEAL_II_HAVE_CXX17_CONSTEXPR_LAMBDA_BUG_OK
+    )
 
-  int main()
-  {
-    const unsigned int n=1;
-    switch (n)
-    {
-      case 1:
-        std::cout << n;
-        [[fallthrough]];
-      case 2:
-        std::cout << n;
-    }
+  # Test that the c++17 attributes are supported.
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    #include <iostream>
 
-    [[maybe_unused]] int i = test_nodiscard();
+    #if __cplusplus < 201703L && !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+    #  error \"insufficient support for C++17\"
+    #endif
 
-    constexpr bool flag = false;
-    if constexpr(flag)
+    [[nodiscard]] int test_nodiscard()
+    {
       return 1;
-    return 0;
-  }
-  "
-  DEAL_II_HAVE_CXX17_FEATURES)
-
-
-#
-# Some compilers treat lambdas as constexpr functions when compiling with
-# C++17 support even if they don't fulfill all the constexpr function
-# requirements. Consequently, these compilers don't allow try-blocks or
-# non-literal return types in lambdas. This is a bug.
-#
-CHECK_CXX_SOURCE_COMPILES(
-  "
-  #include <string>
+    }
 
-  int main()
-  {
-    auto c = []()
+    int main()
     {
-      return std::string{};
-    }();
-    (void) c;
+      const unsigned int n=1;
+      switch (n)
+      {
+        case 1:
+          std::cout << n;
+          [[fallthrough]];
+        case 2:
+          std::cout << n;
+      }
 
-    return []()
-    {
-      try
-      {}
-      catch(...)
-      {}
-      return 0;
-    }();
-  }
-  "
-  DEAL_II_HAVE_CXX17_CONSTEXPR_LAMBDA_BUG_OK)
+      [[maybe_unused]] int i = test_nodiscard();
 
+      constexpr bool flag = false;
+      if constexpr(flag)
+        return 1;
+      return 0;
+    }
+    "
+    DEAL_II_HAVE_CXX17_FEATURES)
 
-#
-# Check some generic C++14 features
-#
-CHECK_CXX_SOURCE_COMPILES(
-  "
-  #include <memory>
-  #include <algorithm>
+  # Some compilers treat lambdas as constexpr functions when compiling with
+  # C++17 support even if they don't fulfill all the constexpr function
+  # requirements. Consequently, these compilers don't allow try-blocks or
+  # non-literal return types in lambdas. This is a bug.
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    #include <string>
+    int main()
+    {
+      auto c = []()
+      {
+        return std::string{};
+      }();
+      (void) c;
 
-  // Check the version language macro, but skip MSVC because
-  // MSVC reports 199711 even in MSVC 2017.
-  #if __cplusplus < 201402L && !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
-  #  error \"insufficient support for C++14\"
-  #endif
+      return []()
+      {
+        try
+        {}
+        catch(...)
+        {}
+        return 0;
+      }();
+    }
+    "
+    DEAL_II_HAVE_CXX17_CONSTEXPR_LAMBDA_BUG_OK)
 
-  int main()
-  {
-    auto ptr = std::make_unique<int>(42);
-    constexpr int max = std::max(0, 1);
-    (void) ptr;
-    (void) max;
-    return 0;
-  }
-  "
-  DEAL_II_HAVE_CXX14_FEATURES)
+  IF(DEAL_II_HAVE_CXX17_FEATURES AND
+     DEAL_II_HAVE_CXX17_CONSTEXPR_LAMBDA_BUG_OK)
+    MESSAGE(STATUS "C++17 support is enabled.")
+    SET(DEAL_II_HAVE_CXX17 TRUE)
+  ELSE()
+    MESSAGE(STATUS "C++17 support is disabled.")
+    SET(DEAL_II_HAVE_CXX17 FALSE)
+  ENDIF()
+ENDMACRO()
 
 
 #
-# Clang-3.5* or older, bail out with a spurious error message in case
-# of an undeduced auto return type.
-#
-# https://llvm.org/bugs/show_bug.cgi?id=16876
+# Wrap the following checks into a macro to make it easier to rerun them.
 #
-SET(_flags "${DEAL_II_CXX_FLAGS_DEBUG}")
-STRIP_FLAG(_flags "-Wa,--compress-debug-sections")
-ADD_FLAGS(CMAKE_REQUIRED_FLAGS "${_flags}")
-CHECK_CXX_SOURCE_COMPILES(
-  "
-  struct foo
-  {
-    auto func();
-  };
-  int main()
-  {
-    foo bar;
-    (void) bar;
-  }
-  "
-  DEAL_II_HAVE_CXX14_CLANGAUTODEBUG_BUG_OK)
+MACRO(_test_cxx14_support)
+  UNSET_IF_CHANGED(CHECK_CXX14_FEATURES_FLAGS_SAVED
+    "${CMAKE_REQUIRED_FLAGS}"
+    DEAL_II_HAVE_CXX14_FEATURES
+    DEAL_II_HAVE_CXX14_CLANGAUTODEBUG_BUG_OK
+    DEAL_II_HAVE_CXX11_FEATURES
+    DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK
+    )
 
+  # Check some generic C++14 features
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    #include <memory>
+    #include <algorithm>
 
-#
-# Check some generic C++11 features
-#
-ADD_FLAGS(CMAKE_REQUIRED_FLAGS "${DEAL_II_CXX_VERSION_FLAG}")
-CHECK_CXX_SOURCE_COMPILES(
-  "
-  // common C++11 include files
-  #include <array>
-  #include <condition_variable>
-  #include <type_traits>
+    // Check the version language macro, but skip MSVC because
+    // MSVC reports 199711 even in MSVC 2017.
+    #if __cplusplus < 201402L && !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+    #  error \"insufficient support for C++14\"
+    #endif
 
-  // thread_local storage specification
-  static thread_local std::array<int,3> p;
+    int main()
+    {
+      auto ptr = std::make_unique<int>(42);
+      constexpr int max = std::max(0, 1);
+      (void) ptr;
+      (void) max;
+      return 0;
+    }
+    "
+    DEAL_II_HAVE_CXX14_FEATURES)
 
-  // Check the version language macro, but skip MSVC because
-  // MSVC reports 199711 even in MSVC 2017.
-  #if __cplusplus < 201103L && !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
-  #  error \"insufficient support for C++11\"
-  #endif
+  # Clang-3.5* or older, bail out with a spurious error message in case
+  # of an undeduced auto return type.
+  #
+  # https://llvm.org/bugs/show_bug.cgi?id=16876
+  SET(_flags "${DEAL_II_CXX_FLAGS_DEBUG}")
+  STRIP_FLAG(_flags "-Wa,--compress-debug-sections")
+  ADD_FLAGS(CMAKE_REQUIRED_FLAGS "${_flags}")
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    struct foo
+    {
+      auto func();
+    };
+    int main()
+    {
+      foo bar;
+      (void) bar;
+    }
+    "
+    DEAL_II_HAVE_CXX14_CLANGAUTODEBUG_BUG_OK)
 
-  int main()
-  {
-    std::condition_variable c;
-    p[0];
-    c.notify_all();
-
-   // type traits functionality
-   constexpr auto m0 = std::is_trivial<double>::value;
-   (void) m0;
-   constexpr auto m1 = std::is_standard_layout<double>::value;
-   (void) m1;
-   constexpr auto m2 = std::is_pod<double>::value;
-   (void) m2;
-  }
-  "
-  DEAL_II_HAVE_CXX11_FEATURES)
+  # Check some generic C++11 features
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    // common C++11 include files
+    #include <array>
+    #include <condition_variable>
+    #include <type_traits>
 
+    // thread_local storage specification
+    static thread_local std::array<int,3> p;
 
-#
-# 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 the version language macro, but skip MSVC because
+    // MSVC reports 199711 even in MSVC 2017.
+    #if __cplusplus < 201103L && !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+    #  error \"insufficient support for C++11\"
+    #endif
 
-IF(DEAL_II_HAVE_CXX17_FEATURES AND
-   DEAL_II_HAVE_CXX17_CONSTEXPR_LAMBDA_BUG_OK)
-  MESSAGE(STATUS "C++17 support is enabled.")
-  SET(DEAL_II_HAVE_CXX17 TRUE)
-ELSE()
-  MESSAGE(STATUS "C++17 support is disabled.")
-  SET(DEAL_II_HAVE_CXX17 FALSE)
+    int main()
+    {
+      std::condition_variable c;
+      p[0];
+      c.notify_all();
+
+     // type traits functionality
+     constexpr auto m0 = std::is_trivial<double>::value;
+     (void) m0;
+     constexpr auto m1 = std::is_standard_layout<double>::value;
+     (void) m1;
+     constexpr auto m2 = std::is_pod<double>::value;
+     (void) m2;
+    }
+    "
+    DEAL_II_HAVE_CXX11_FEATURES)
+
+  # 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)
+
+  IF(DEAL_II_HAVE_CXX14_FEATURES AND
+     DEAL_II_HAVE_CXX14_CLANGAUTODEBUG_BUG_OK AND
+     DEAL_II_HAVE_CXX11_FEATURES AND
+     DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK)
+    MESSAGE(STATUS "C++14 support is enabled.")
+    SET(DEAL_II_HAVE_CXX14 TRUE)
+  ELSE()
+    MESSAGE(STATUS "C++14 support is disabled.")
+    SET(DEAL_II_HAVE_CXX14 FALSE)
+  ENDIF()
+ENDMACRO()
+
+_set_up_cmake_required()
+_test_cxx14_support()
+_test_cxx17_support()
+
+IF(NOT DEAL_II_HAVE_CXX14)
+  MESSAGE(STATUS "C++14 support not available. Try to set -std=c++14 explicitly")
+  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-std=c++14")
+  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "/std:c++14")
+  _set_up_cmake_required()
+  _test_cxx14_support()
+  _test_cxx17_support()
 ENDIF()
 
-IF(DEAL_II_HAVE_CXX14_FEATURES AND
-   DEAL_II_HAVE_CXX14_CLANGAUTODEBUG_BUG_OK AND
-   DEAL_II_HAVE_CXX11_FEATURES AND
-   DEAL_II_HAVE_CXX11_FUNCTIONAL_LLVMBUG20084_OK)
-  # we require C++14 so this is fine
-ELSE()
+IF(NOT DEAL_II_HAVE_CXX14)
   MESSAGE(FATAL_ERROR
     "\nThe current version of deal.II requires a compiler with enabled "
     "C++14 support. Make sure to use a modern enough compiler (GCC version "
@@ -284,6 +286,16 @@ ENDIF()
 ########################################################################
 
 
+UNSET_IF_CHANGED(CHECK_CXX_FEATURES_FLAGS_SAVED
+  "${CMAKE_REQUIRED_FLAGS}"
+  DEAL_II_HAVE_FP_EXCEPTIONS
+  DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS
+  DEAL_II_HAVE_CXX17_ATTRIBUTE_FALLTHROUGH
+  DEAL_II_HAVE_ATTRIBUTE_FALLTHROUGH
+  DEAL_II_CXX14_CONSTEXPR_BUG_OK
+  )
+
+
 #
 # Check that we can use feenableexcept through the C++11 header file cfenv:
 #
index 550bb8735186ab6ab6d4e2361119a2b5d4010915..3c697150a4c02b901480e278aa4643e3f5c6552e 100644 (file)
@@ -197,6 +197,7 @@ FOREACH(_file ${_files})
   FILE(APPEND ${_file} "\n\n#\n# Feature configuration:\n#\n\n")
   FILE(APPEND ${_file} "SET(DEAL_II_WITH_CXX11 ON)\n")
   FILE(APPEND ${_file} "SET(DEAL_II_WITH_CXX14 ON)\n")
+  FILE(APPEND ${_file} "SET(DEAL_II_WITH_CXX17 ${DEAL_II_HAVE_CXX17})\n")
 ENDFOREACH()
 
 GET_CMAKE_PROPERTY(_res VARIABLES)
index 8facabf5fde5081bbd9f1fcf4cfaca9d78435e89..0d6e2db5dfff35e0582e6719bfd7eb3b3327dc46 100644 (file)
  * For documentation see cmake/checks/check_01_cxx_features.cmake
  */
 
+#cmakedefine DEAL_II_HAVE_CXX14
 #cmakedefine DEAL_II_HAVE_CXX17
 
 #cmakedefine DEAL_II_HAVE_FP_EXCEPTIONS

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.