summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2019-10-17 10:49:44 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2019-10-17 16:57:25 +0000
commit2fa23e46c0b79a065d92a95033bfc3ae10b707cf (patch)
treeab13778363b9719fbf6bb055608ae88fcd614642
parent4df389eb4f1ae10284c03023e923ce2164d46753 (diff)
Fix C++ standard detection
We cannot use a generator expression in an if statement, it does not work. Instead, we could inspect the CMAKE_C/CXX_COMPILE_FEATURES list, but unfortunately that's not reliable. For example it detects that ICPC supports C++17 when in fact that depends on the installed libstdc++. Therefore this patch revives our own configure tests. Change-Id: Ic3bc5762fbe81837722523e3881ac16e84628519 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r--cmake/QtFeature.cmake16
-rw-r--r--configure.cmake55
-rwxr-xr-xutil/cmake/configurejson2cmake.py24
3 files changed, 78 insertions, 17 deletions
diff --git a/cmake/QtFeature.cmake b/cmake/QtFeature.cmake
index 3a8a04c253..e3fb9c4232 100644
--- a/cmake/QtFeature.cmake
+++ b/cmake/QtFeature.cmake
@@ -472,7 +472,7 @@ function(qt_feature_copy_global_config_features_to_core target)
endfunction()
function(qt_config_compile_test name)
- cmake_parse_arguments(arg "" "LABEL;PROJECT_PATH" "LIBRARIES;CODE" ${ARGN})
+ cmake_parse_arguments(arg "" "LABEL;PROJECT_PATH;C_STANDARD;CXX_STANDARD" "LIBRARIES;CODE" ${ARGN})
if(arg_PROJECT_PATH)
message(STATUS "Performing Test ${arg_LABEL}")
@@ -499,10 +499,24 @@ function(qt_config_compile_test name)
endforeach()
if(NOT DEFINED HAVE_${name})
+ set(_save_CMAKE_C_STANDARD "${CMAKE_C_STANDARD}")
+ set(_save_CMAKE_CXX_STANDARD "${CMAKE_CXX_STANDARD}")
+
+ if(arg_C_STANDARD)
+ set(CMAKE_C_STANDARD "${arg_C_STANDARD}")
+ endif()
+
+ if(arg_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD "${arg_CXX_STANDARD}")
+ endif()
+
set(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
set(CMAKE_REQUIRED_LIBRARIES "${arg_LIBRARIES}")
check_cxx_source_compiles("${arg_UNPARSED_ARGUMENTS} ${arg_CODE}" HAVE_${name})
set(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}")
+
+ set(CMAKE_C_STANDARD "${_save_CMAKE_C_STANDARD}")
+ set(CMAKE_CXX_STANDARD "${_save_CMAKE_CXX_STANDARD}")
endif()
endif()
diff --git a/configure.cmake b/configure.cmake
index 55c2d6b73c..f6fba22731 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -15,6 +15,54 @@ qt_find_package(Libudev PROVIDED_TARGETS PkgConfig::Libudev)
#### Tests
+# c++14
+qt_config_compile_test(cxx14
+ LABEL "C++14 support"
+"#if __cplusplus > 201103L
+// Compiler claims to support C++14, trust it
+#else
+# error __cplusplus must be > 201103L (the value of C++11)
+#endif
+
+
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ /* BEGIN TEST: */
+
+ /* END TEST: */
+ return 0;
+}
+"
+ CXX_STANDARD 14
+)
+
+# c++17
+qt_config_compile_test(cxx17
+ LABEL "C++17 support"
+"#if __cplusplus > 201402L
+// Compiler claims to support C++17, trust it
+#else
+# error __cplusplus must be > 201402L (the value for C++14)
+#endif
+#include <map> // https://bugs.llvm.org//show_bug.cgi?id=33117
+#include <variant>
+
+
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ /* BEGIN TEST: */
+std::variant<int> v(42);
+int i = std::get<int>(v);
+std::visit([](const auto &) { return 1; }, v);
+ /* END TEST: */
+ return 0;
+}
+"
+ CXX_STANDARD 17
+)
+
# c++2a
qt_config_compile_test(cxx2a
LABEL "C++2a support"
@@ -33,7 +81,8 @@ int main(int argc, char **argv)
/* END TEST: */
return 0;
}
-"# FIXME: qmake: CONFIG += c++11 c++14 c++17 c++2a
+"
+ CXX_STANDARD 20
)
# precompile_header
@@ -294,11 +343,11 @@ qt_feature("cxx11" PUBLIC
)
qt_feature("cxx14" PUBLIC
LABEL "C++14"
- CONDITION QT_FEATURE_cxx11 AND $<COMPILE_FEATURES:cxx_std_14>
+ CONDITION QT_FEATURE_cxx11 AND TEST_cxx14
)
qt_feature("cxx17" PUBLIC
LABEL "C++17"
- CONDITION QT_FEATURE_cxx14 AND $<COMPILE_FEATURES:cxx_std_17>
+ CONDITION QT_FEATURE_cxx14 AND TEST_cxx17
)
qt_feature("cxx1z" PUBLIC
LABEL "C++17"
diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py
index 11918f1a32..ba6c85af28 100755
--- a/util/cmake/configurejson2cmake.py
+++ b/util/cmake/configurejson2cmake.py
@@ -54,13 +54,8 @@ class LibraryMapping:
def map_tests(test: str) -> Optional[str]:
testmap = {
- "c++11": "$<COMPILE_FEATURES:cxx_std_11>",
- "c++14": "$<COMPILE_FEATURES:cxx_std_14>",
- "c++1z": "$<COMPILE_FEATURES:cxx_std_17>",
- "c++17": "$<COMPILE_FEATURES:cxx_std_17>",
- "c++20": "$<COMPILE_FEATURES:cxx_std_20>",
- "c99": "$<COMPILE_FEATURES:c_std_99>",
- "c11": "$<COMPILE_FEATURES:c_std_11>",
+ "c99": "c_std_99 IN_LIST CMAKE_C_COMPILE_FEATURES",
+ "c11": "c_std_11 IN_LIST CMAKE_C_COMPILE_FEATURES",
"x86SimdAlways": "ON", # FIXME: Make this actually do a compile test.
"aesni": "TEST_subarch_aes",
"avx": "TEST_subarch_avx",
@@ -489,12 +484,6 @@ def parseInput(ctx, sinput, data, cm_fh):
# },
def parseTest(ctx, test, data, cm_fh):
skip_tests = {
- "c++11",
- "c++14",
- "c++17",
- "c++20",
- "c++1y",
- "c++1z",
"c11",
"c99",
"gc_binaries",
@@ -572,6 +561,7 @@ endif()
sourceCode = sourceCode.replace('"', '\\"')
librariesCmakeName = ""
+ languageStandard = ""
qmakeFixme = ""
cm_fh.write(f"# {test}\n")
@@ -594,6 +584,12 @@ endif()
elif details["qmake"] == "CONFIG += c++11":
# do nothing we're always in c++11 mode
pass
+ elif details["qmake"] == "CONFIG += c++11 c++14":
+ languageStandard = "CXX_STANDARD 14"
+ elif details["qmake"] == "CONFIG += c++11 c++14 c++17":
+ languageStandard = "CXX_STANDARD 17"
+ elif details["qmake"] == "CONFIG += c++11 c++14 c++17 c++2a":
+ languageStandard = "CXX_STANDARD 20"
else:
qmakeFixme = f"# FIXME: qmake: {details['qmake']}\n"
@@ -614,6 +610,8 @@ endif()
cm_fh.write('"' + sourceCode + '"')
if qmakeFixme != "":
cm_fh.write(qmakeFixme)
+ if languageStandard != "":
+ cm_fh.write(f"\n {languageStandard}\n")
cm_fh.write(")\n\n")
elif data["type"] == "libclang":