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.
This commit is contained in:
parent
29e2b85171
commit
4a0485be7f
@ -118,14 +118,13 @@ as well as any dependents (that may include headers from ``mylib``).
|
||||
Availability of Compiler Extensions
|
||||
-----------------------------------
|
||||
|
||||
Because the :prop_tgt:`CXX_EXTENSIONS` target property is ``ON`` by default,
|
||||
CMake uses extended variants of language dialects by default, such as
|
||||
``-std=gnu++11`` instead of ``-std=c++11``. That target property may be
|
||||
set to ``OFF`` to use the non-extended variant of the dialect flag. Note
|
||||
that because most compilers enable extensions by default, this could
|
||||
expose cross-platform bugs in user code or in the headers of third-party
|
||||
The :prop_tgt:`<LANG>_EXTENSIONS` target property defaults to the compiler's
|
||||
efault. Note that because most compilers enable extensions by default, this
|
||||
may expose cross-platform bugs in user code or in the headers of third-party
|
||||
dependencies.
|
||||
|
||||
:prop_tgt:`<LANG>_EXTENSIONS` used to default to ``ON``. See :policy:`CMP0128`.
|
||||
|
||||
Optional Compile Features
|
||||
=========================
|
||||
|
||||
|
@ -57,6 +57,7 @@ Policies Introduced by CMake 3.22
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CMP0128: Selection of language standard and extension flags improved. </policy/CMP0128>
|
||||
CMP0127: cmake_dependent_option() supports full Condition Syntax. </policy/CMP0127>
|
||||
|
||||
Policies Introduced by CMake 3.21
|
||||
|
78
Help/policy/CMP0128.rst
Normal file
78
Help/policy/CMP0128.rst
Normal file
@ -0,0 +1,78 @@
|
||||
CMP0128
|
||||
-------
|
||||
|
||||
.. versionadded:: 3.22
|
||||
|
||||
When this policy is set to ``NEW``:
|
||||
|
||||
* :prop_tgt:`<LANG>_EXTENSIONS` is initialized to
|
||||
:variable:`CMAKE_<LANG>_EXTENSIONS_DEFAULT`.
|
||||
|
||||
* Extensions are correctly disabled/enabled if :prop_tgt:`<LANG>_STANDARD` is
|
||||
unset.
|
||||
|
||||
* Standard mode-affecting flags aren't added unless necessary to achieve the
|
||||
specified mode.
|
||||
|
||||
The ``OLD`` behavior:
|
||||
|
||||
* Initializes :prop_tgt:`<LANG>_EXTENSIONS` to ``ON``.
|
||||
|
||||
* Always adds a flag if :prop_tgt:`<LANG>_STANDARD` is set and
|
||||
:prop_tgt:`<LANG>_STANDARD_REQUIRED` is ``OFF``.
|
||||
|
||||
* If :prop_tgt:`<LANG>_STANDARD` is unset:
|
||||
|
||||
* Doesn't disable extensions even if :prop_tgt:`<LANG>_EXTENSIONS` is
|
||||
``OFF``.
|
||||
|
||||
* Fails to enable extensions if :prop_tgt:`<LANG>_EXTENSIONS` is ``ON``
|
||||
except for the ``IAR`` compiler.
|
||||
|
||||
Code may need to be updated for the ``NEW`` behavior in the following cases:
|
||||
|
||||
* If :prop_tgt:`<LANG>_EXTENSIONS` matches
|
||||
:variable:`CMAKE_<LANG>_EXTENSIONS_DEFAULT` or is unset and the compiler's
|
||||
default satisfies :prop_tgt:`<LANG>_STANDARD` but the compiled code requires
|
||||
the exact standard specified.
|
||||
Such code should set :prop_tgt:`<LANG>_STANDARD_REQUIRED` to ``ON``.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION |release|)
|
||||
project(example C)
|
||||
|
||||
add_executable(exe main.c)
|
||||
set_property(TARGET exe PROPERTY C_STANDARD 99)
|
||||
|
||||
If the compiler defaults to C11 then the standard specification for C99 is
|
||||
satisfied and CMake will pass no flags. ``main.c`` will no longer compile if
|
||||
it is incompatible with C11.
|
||||
|
||||
* If a standard mode flag previously overridden by CMake's and not used during
|
||||
compiler detection now takes effect due to CMake no longer adding one as the
|
||||
default detected is appropriate.
|
||||
|
||||
Such code should be converted to either:
|
||||
|
||||
* Use :prop_tgt:`<LANG>_STANDARD` and :prop_tgt:`<LANG>_EXTENSIONS` instead
|
||||
of manually adding flags.
|
||||
|
||||
* Or ensure the manually-specified flags are used during compiler detection.
|
||||
|
||||
If compiler flags affecting the standard mode are used during compiler
|
||||
detection (for example in :manual:`a toolchain file <cmake-toolchains(7)>`
|
||||
using :variable:`CMAKE_<LANG>_FLAGS_INIT`) then they will affect the detected
|
||||
default :variable:`standard <CMAKE_<LANG>_STANDARD_DEFAULT>` and
|
||||
:variable:`extensions <CMAKE_<LANG>_EXTENSIONS_DEFAULT>`.
|
||||
|
||||
Unlike many policies, CMake version |release| does *not* warn when the policy
|
||||
is not set and simply uses the ``OLD`` behavior. Use the
|
||||
:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
|
||||
See documentation of the
|
||||
:variable:`CMAKE_POLICY_WARNING_CMP0128 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
|
||||
variable to control the warning.
|
||||
|
||||
.. include:: DEPRECATED.txt
|
10
Help/release/dev/compile-features-standard-logic-rework.rst
Normal file
10
Help/release/dev/compile-features-standard-logic-rework.rst
Normal file
@ -0,0 +1,10 @@
|
||||
compile-features-standard-logic-rework
|
||||
--------------------------------------
|
||||
|
||||
* The :manual:`Compile Features <cmake-compile-features(7)>` functionality now
|
||||
correctly disables or enables compiler extensions when no standard level is
|
||||
specified and avoids unnecessarily adding language standard flags if the
|
||||
requested settings match the compiler's defaults. See :policy:`CMP0128`.
|
||||
|
||||
* :prop_tgt:`<LANG>_EXTENSIONS` is initialized to
|
||||
:variable:`CMAKE_<LANG>_EXTENSIONS_DEFAULT`. See :policy:`CMP0128`.
|
@ -32,6 +32,8 @@ only for the policies that do not warn by default:
|
||||
policy :policy:`CMP0116`.
|
||||
* ``CMAKE_POLICY_WARNING_CMP0126`` controls the warning for
|
||||
policy :policy:`CMP0126`.
|
||||
* ``CMAKE_POLICY_WARNING_CMP0128`` controls the warning for
|
||||
policy :policy:`CMP0128`.
|
||||
|
||||
This variable should not be set by a project in CMake code. Project
|
||||
developers running CMake may set this variable in their cache to
|
||||
|
@ -14,6 +14,7 @@ if(NOT DEFINED CMAKE_C_COMPILER_VERSION)
|
||||
message(FATAL_ERROR "CMAKE_C_COMPILER_VERSION not detected. This should be automatic.")
|
||||
endif()
|
||||
|
||||
# Unused after CMP0128
|
||||
set(CMAKE_C_EXTENSION_COMPILE_OPTION -e)
|
||||
|
||||
if(CMAKE_C_COMPILER_VERSION_INTERNAL VERSION_GREATER 7)
|
||||
|
@ -27,7 +27,7 @@ if(NOT CMAKE_IAR_CXX_FLAG)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX_EXTENSION_COMPILE_OPTION -e)
|
||||
set(CMAKE_CXX_EXTENSION_COMPILE_OPTION -e) # Unused after CMP0128
|
||||
|
||||
set(CMAKE_CXX${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT}_STANDARD_COMPILE_OPTION "")
|
||||
set(CMAKE_CXX${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT}_EXTENSION_COMPILE_OPTION -e)
|
||||
|
@ -382,7 +382,10 @@ class cmMakefile;
|
||||
21, 0, cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0127, \
|
||||
"cmake_dependent_option() supports full Condition Syntax.", 3, 22, \
|
||||
0, cmPolicies::WARN)
|
||||
0, cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0128, \
|
||||
"Selection of language standard and extension flags improved.", 3, \
|
||||
22, 0, cmPolicies::WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmValue.h"
|
||||
@ -83,25 +84,62 @@ struct StandardLevelComputer
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
cmPolicies::PolicyStatus const cmp0128{ makefile->GetPolicyStatus(
|
||||
cmPolicies::CMP0128) };
|
||||
bool const defaultExt{ cmIsOn(*makefile->GetDefinition(
|
||||
cmStrCat("CMAKE_", this->Language, "_EXTENSIONS_DEFAULT"))) };
|
||||
bool ext = true;
|
||||
if (cmValue extPropValue = target->GetLanguageExtensions(this->Language)) {
|
||||
if (cmIsOff(*extPropValue)) {
|
||||
ext = false;
|
||||
}
|
||||
|
||||
if (cmp0128 == cmPolicies::NEW) {
|
||||
ext = defaultExt;
|
||||
}
|
||||
|
||||
if (cmValue extPropValue = target->GetLanguageExtensions(this->Language)) {
|
||||
ext = cmIsOn(*extPropValue);
|
||||
}
|
||||
|
||||
std::string const type{ ext ? "EXTENSION" : "STANDARD" };
|
||||
|
||||
cmValue standardProp = target->GetLanguageStandard(this->Language, config);
|
||||
if (!standardProp) {
|
||||
if (ext) {
|
||||
// No language standard is specified and extensions are not disabled.
|
||||
// Check if this compiler needs a flag to enable extensions.
|
||||
return cmStrCat("CMAKE_", this->Language, "_EXTENSION_COMPILE_OPTION");
|
||||
if (cmp0128 == cmPolicies::NEW) {
|
||||
// Add extension flag if compiler's default doesn't match.
|
||||
if (ext != defaultExt) {
|
||||
return cmStrCat("CMAKE_", this->Language, *defaultStd, "_", type,
|
||||
"_COMPILE_OPTION");
|
||||
}
|
||||
} else {
|
||||
if (cmp0128 == cmPolicies::WARN &&
|
||||
makefile->PolicyOptionalWarningEnabled(
|
||||
"CMAKE_POLICY_WARNING_CMP0128") &&
|
||||
ext != defaultExt) {
|
||||
const char* state{};
|
||||
if (ext) {
|
||||
if (!makefile->GetDefinition(cmStrCat(
|
||||
"CMAKE_", this->Language, "_EXTENSION_COMPILE_OPTION"))) {
|
||||
state = "enabled";
|
||||
}
|
||||
} else {
|
||||
state = "disabled";
|
||||
}
|
||||
if (state) {
|
||||
makefile->IssueMessage(
|
||||
MessageType::AUTHOR_WARNING,
|
||||
cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0128),
|
||||
"\nFor compatibility with older versions of CMake, "
|
||||
"compiler extensions won't be ",
|
||||
state, "."));
|
||||
}
|
||||
}
|
||||
|
||||
if (ext) {
|
||||
return cmStrCat("CMAKE_", this->Language,
|
||||
"_EXTENSION_COMPILE_OPTION");
|
||||
}
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
std::string const type = ext ? "EXTENSION" : "STANDARD";
|
||||
|
||||
if (target->GetLanguageStandardRequired(this->Language)) {
|
||||
std::string option_flag = cmStrCat(
|
||||
"CMAKE_", this->Language, *standardProp, "_", type, "_COMPILE_OPTION");
|
||||
@ -121,6 +159,25 @@ struct StandardLevelComputer
|
||||
return option_flag;
|
||||
}
|
||||
|
||||
// If the request matches the compiler's defaults we don't need to add
|
||||
// anything.
|
||||
if (*standardProp == *defaultStd && ext == defaultExt) {
|
||||
if (cmp0128 == cmPolicies::NEW) {
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
if (cmp0128 == cmPolicies::WARN &&
|
||||
makefile->PolicyOptionalWarningEnabled(
|
||||
"CMAKE_POLICY_WARNING_CMP0128")) {
|
||||
makefile->IssueMessage(
|
||||
MessageType::AUTHOR_WARNING,
|
||||
cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0128),
|
||||
"\nFor compatibility with older versions of CMake, "
|
||||
"unnecessary flags for language standard or compiler "
|
||||
"extensions may be added."));
|
||||
}
|
||||
}
|
||||
|
||||
std::string standardStr(*standardProp);
|
||||
if (this->Language == "CUDA" && standardStr == "98") {
|
||||
standardStr = "03";
|
||||
@ -147,17 +204,17 @@ struct StandardLevelComputer
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
// If the standard requested is older than the compiler's default
|
||||
// then we need to use a flag to change it.
|
||||
if (stdIt <= defaultStdIt) {
|
||||
// If the standard requested is older than the compiler's default or the
|
||||
// extension mode doesn't match then we need to use a flag.
|
||||
if (stdIt < defaultStdIt) {
|
||||
auto offset = std::distance(cm::cbegin(stds), stdIt);
|
||||
return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
|
||||
"_COMPILE_OPTION");
|
||||
}
|
||||
|
||||
// The standard requested is at least as new as the compiler's default,
|
||||
// and the standard request is not required. Decay to the newest standard
|
||||
// for which a flag is defined.
|
||||
// The compiler's default is at least as new as the requested standard,
|
||||
// and the requested standard is not required. Decay to the newest
|
||||
// standard for which a flag is defined.
|
||||
for (; defaultStdIt < stdIt; --stdIt) {
|
||||
auto offset = std::distance(cm::cbegin(stds), stdIt);
|
||||
std::string option_flag =
|
||||
|
@ -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\.
|
7
Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake
Normal file
7
Tests/RunCMake/CompileFeatures/CMP0128WarnMatch.cmake
Normal file
@ -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@")
|
@ -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\.
|
6
Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake
Normal file
6
Tests/RunCMake/CompileFeatures/CMP0128WarnUnset.cmake
Normal file
@ -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@")
|
@ -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()
|
9
Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake
Normal file
9
Tests/RunCMake/CompileFeatures/NoUnnecessaryFlag.cmake
Normal file
@ -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@")
|
@ -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()
|
||||
|
@ -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()
|
8
Tests/RunCMake/CompileFeatures/UnsetStandard.cmake
Normal file
8
Tests/RunCMake/CompileFeatures/UnsetStandard.cmake
Normal file
@ -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@")
|
@ -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})
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int empty()
|
||||
int empty(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user