diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2019-10-17 10:49:44 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-10-17 16:57:25 +0000 |
commit | 2fa23e46c0b79a065d92a95033bfc3ae10b707cf (patch) | |
tree | ab13778363b9719fbf6bb055608ae88fcd614642 | |
parent | 4df389eb4f1ae10284c03023e923ce2164d46753 (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.cmake | 16 | ||||
-rw-r--r-- | configure.cmake | 55 | ||||
-rwxr-xr-x | util/cmake/configurejson2cmake.py | 24 |
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": |