diff options
author | Raul Tambre <raul@tambre.ee> | 2021-05-29 15:34:18 (GMT) |
---|---|---|
committer | Raul Tambre <raul@tambre.ee> | 2021-09-29 19:28:40 (GMT) |
commit | 4a0485be7f4ab06201c478f5a46111ab1e8e773e (patch) | |
tree | a4a89916f051e70a7fac32fbba0daaefbcc4ac0d /Tests/RunCMake/CompileFeatures | |
parent | 29e2b8517126389b2c4b2f3479c4634a8260bea3 (diff) | |
download | CMake-4a0485be7f4ab06201c478f5a46111ab1e8e773e.zip CMake-4a0485be7f4ab06201c478f5a46111ab1e8e773e.tar.gz CMake-4a0485be7f4ab06201c478f5a46111ab1e8e773e.tar.bz2 |
cmStandardLevelResolver: Avoid unnecessary flags, fix unset level logic
The changes are part of CMP0128.
When the standard level is unset:
* Flags are added if extension mode doesn't match the compiler's default.
Previously logic only worked if LANG_EXTENSIONS was ON. Fixes #22224.
* The full flag is used. Previously CMAKE_LANG_EXTENSION_COMPILE_OPTION was
used. This was only supported for IAR.
Otherwise:
* Avoid adding flags if not necessary per the detected compiler defaults.
* Fixed check for when the requested standard is older. It now matches the
nearby comments.
I reworded the fallback comment as its logic was a bit difficult to wrap my
head around.
Diffstat (limited to 'Tests/RunCMake/CompileFeatures')
11 files changed, 201 insertions, 1 deletions
diff --git a/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch-stderr.txt b/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch-stderr.txt new file mode 100644 index 0000000..320c2ba --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch-stderr.txt @@ -0,0 +1,8 @@ +CMake Warning \(dev\) in CMakeLists\.txt: + Policy CMP0128 is not set: Selection of language standard and extension + flags improved\. Run "cmake --help-policy CMP0128" for policy details\. Use + the cmake_policy command to set the policy and suppress this warning\. + + For compatibility with older versions of CMake, unnecessary flags for + language standard or compiler extensions may be added. +This warning is for project developers\. Use -Wno-dev to suppress it\. diff --git a/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake b/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake new file mode 100644 index 0000000..0a5606a --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake @@ -0,0 +1,7 @@ +enable_language(@lang@) +cmake_policy(SET CMP0128 OLD) +set(CMAKE_POLICY_WARNING_CMP0128 ON) + +set(CMAKE_@lang@_EXTENSIONS @extensions_default@) +set(CMAKE_@lang@_STANDARD @standard_default@) +add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset-stderr.txt b/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset-stderr.txt new file mode 100644 index 0000000..068cba9 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset-stderr.txt @@ -0,0 +1,8 @@ +CMake Warning \(dev\) in CMakeLists\.txt: + Policy CMP0128 is not set: Selection of language standard and extension + flags improved\. Run "cmake --help-policy CMP0128" for policy details\. Use + the cmake_policy command to set the policy and suppress this warning\. + + For compatibility with older versions of CMake, compiler extensions won't + be @opposite@\. +This warning is for project developers\. Use -Wno-dev to suppress it\. diff --git a/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake b/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake new file mode 100644 index 0000000..cd7af2c --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake @@ -0,0 +1,6 @@ +enable_language(@lang@) +cmake_policy(SET CMP0128 OLD) +set(CMAKE_POLICY_WARNING_CMP0128 ON) + +set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@) +add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag-build-check.cmake b/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag-build-check.cmake new file mode 100644 index 0000000..4f767fa --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag-build-check.cmake @@ -0,0 +1,8 @@ +foreach(flag @flags@) + string(FIND "${actual_stdout}" "${flag}" position) + + if(NOT position EQUAL -1) + set(RunCMake_TEST_FAILED "\"${flag}\" compile flag found.") + break() + endif() +endforeach() diff --git a/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake b/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake new file mode 100644 index 0000000..8ef3a72 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake @@ -0,0 +1,9 @@ +enable_language(@lang@) + +# Make sure the compile command is not hidden. +string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") +string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") + +set(CMAKE_@lang@_EXTENSIONS @extensions_default@) +set(CMAKE_@lang@_STANDARD @standard_default@) +add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake index 934d8ca..3bfd211 100644 --- a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake @@ -34,6 +34,120 @@ elseif (cxx_std_98 IN_LIST CXX_FEATURES AND cxx_std_11 IN_LIST CXX_FEATURES) unset(RunCMake_TEST_OPTIONS) endif() +configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt" "${RunCMake_BINARY_DIR}/CMakeLists.txt" COPYONLY) + +macro(test_build) + set(test ${name}-${lang}) + + configure_file("${RunCMake_SOURCE_DIR}/${name}.cmake" "${RunCMake_BINARY_DIR}/${test}.cmake" @ONLY) + if(EXISTS "${RunCMake_SOURCE_DIR}/${name}-build-check.cmake") + configure_file("${RunCMake_SOURCE_DIR}/${name}-build-check.cmake" "${RunCMake_BINARY_DIR}/${test}-build-check.cmake" @ONLY) + endif() + if(EXISTS "${RunCMake_SOURCE_DIR}/${name}-stderr.txt") + configure_file("${RunCMake_SOURCE_DIR}/${name}-stderr.txt" "${RunCMake_BINARY_DIR}/${test}-stderr.txt" @ONLY) + endif() + + set(RunCMake_SOURCE_DIR "${RunCMake_BINARY_DIR}") + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test}-build") + run_cmake(${test}) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . ${ARGN}) +endmacro() + +# Mangle flags such as they're in verbose build output. +macro(mangle_flags variable) + set(result "${${variable}}") + + if(RunCMake_GENERATOR MATCHES "Visual Studio" AND MSVC_TOOLSET_VERSION GREATER_EQUAL 141) + string(REPLACE "-" "/" result "${result}") + elseif(RunCMake_GENERATOR STREQUAL "Xcode" AND CMAKE_XCODE_BUILD_SYSTEM GREATER_EQUAL 12) + string(REPLACE "=" [[\\=]] result "${result}") + endif() + + string(REPLACE ";" " " result "${result}") + list(APPEND flags "${result}") +endmacro() + +function(test_unset_standard) + if(extensions_opposite) + set(flag_ext "_EXT") + endif() + + set(flag "${${lang}${${lang}_STANDARD_DEFAULT}${flag_ext}_FLAG}") + + if(NOT flag) + return() + endif() + + mangle_flags(flag) + + set(name UnsetStandard) + set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW) + test_build(--verbose) +endfunction() + +function(test_no_unnecessary_flag) + set(standard_flag "${${lang}${${lang}_STANDARD_DEFAULT}_FLAG}") + set(extension_flag "${${lang}${${lang}_STANDARD_DEFAULT}_EXT_FLAG}") + + if(NOT standard_flag AND NOT extension_flag) + return() + endif() + + mangle_flags(standard_flag) + mangle_flags(extension_flag) + + set(name NoUnnecessaryFlag) + set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW) + test_build(--verbose) +endfunction() + +function(test_cmp0128_warn_match) + set(name CMP0128WarnMatch) + test_build() +endfunction() + +function(test_cmp0128_warn_unset) + # For compilers that had CMAKE_<LANG>_EXTENSION_COMPILE_OPTION (only IAR) + # there is no behavioural change and thus no warning. + if(NOT "${${lang}_EXT_FLAG}" STREQUAL "") + return() + endif() + + if(extensions_opposite) + set(opposite "enabled") + else() + set(opposite "disabled") + endif() + + set(name CMP0128WarnUnset) + test_build() +endfunction() + +function(test_lang lang ext) + if(CMake_NO_${lang}_STANDARD) + return() + endif() + + set(extensions_default "${${lang}_EXTENSIONS_DEFAULT}") + set(standard_default "${${lang}_STANDARD_DEFAULT}") + + if(extensions_default) + set(extensions_opposite OFF) + else() + set(extensions_opposite ON) + endif() + + test_unset_standard() + test_no_unnecessary_flag() + test_cmp0128_warn_match() + test_cmp0128_warn_unset() +endfunction() + +if(C_STANDARD_DEFAULT) + test_lang(C c) +endif() + if(CXX_STANDARD_DEFAULT) run_cmake(NotAStandard) @@ -47,4 +161,6 @@ if(CXX_STANDARD_DEFAULT) run_cmake(RequireCXX${standard}ExtVariable) endif() endforeach() + + test_lang(CXX cpp) endif() diff --git a/Tests/RunCMake/CompileFeatures/UnsetStandard-build-check.cmake b/Tests/RunCMake/CompileFeatures/UnsetStandard-build-check.cmake new file mode 100644 index 0000000..abe293c --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/UnsetStandard-build-check.cmake @@ -0,0 +1,12 @@ +foreach(flag @flags@) + string(FIND "${actual_stdout}" "${flag}" position) + + if(NOT position EQUAL -1) + set(found TRUE) + break() + endif() +endforeach() + +if(NOT found) + set(RunCMake_TEST_FAILED "No compile flags from \"@flags@\" found for CMAKE_@lang@_EXTENSIONS=@extensions_opposite@.") +endif() diff --git a/Tests/RunCMake/CompileFeatures/UnsetStandard.cmake b/Tests/RunCMake/CompileFeatures/UnsetStandard.cmake new file mode 100644 index 0000000..99bb3f0 --- /dev/null +++ b/Tests/RunCMake/CompileFeatures/UnsetStandard.cmake @@ -0,0 +1,8 @@ +enable_language(@lang@) + +# Make sure the compile command is not hidden. +string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") +string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}") + +set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@) +add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@") diff --git a/Tests/RunCMake/CompileFeatures/compiler_introspection.cmake b/Tests/RunCMake/CompileFeatures/compiler_introspection.cmake index c42324b..5691344 100644 --- a/Tests/RunCMake/CompileFeatures/compiler_introspection.cmake +++ b/Tests/RunCMake/CompileFeatures/compiler_introspection.cmake @@ -1,10 +1,28 @@ enable_language(C CXX) +set(info "") + +if(MSVC_TOOLSET_VERSION) + string(APPEND info " +set(MSVC_TOOLSET_VERSION ${MSVC_TOOLSET_VERSION}) + +") +endif() + +if(CMAKE_XCODE_BUILD_SYSTEM) + string(APPEND info " +set(CMAKE_XCODE_BUILD_SYSTEM ${CMAKE_XCODE_BUILD_SYSTEM}) + +") +endif() + macro(info lang) string(APPEND info "\ set(${lang}_STANDARD_DEFAULT ${CMAKE_${lang}_STANDARD_DEFAULT}) set(${lang}_EXTENSIONS_DEFAULT ${CMAKE_${lang}_EXTENSIONS_DEFAULT}) set(${lang}_FEATURES ${CMAKE_${lang}_COMPILE_FEATURES}) + +set(${lang}_EXT_FLAG ${CMAKE_${lang}_EXTENSION_COMPILE_OPTION}) ") foreach(standard ${ARGN}) diff --git a/Tests/RunCMake/CompileFeatures/empty.c b/Tests/RunCMake/CompileFeatures/empty.c index 11ec041..8d91e77 100644 --- a/Tests/RunCMake/CompileFeatures/empty.c +++ b/Tests/RunCMake/CompileFeatures/empty.c @@ -1,7 +1,7 @@ #ifdef _WIN32 __declspec(dllexport) #endif - int empty() + int empty(void) { return 0; } |