try_compile: Add policy CMP0066 to honor CMAKE_<LANG>_FLAGS_<CONFIG>
In the `try_compile` source file signature we propagate the caller's value of `CMAKE_<LANG>_FLAGS` into the test project. Extend this to propagate `CMAKE_<LANG>_FLAGS_<CONFIG>` too instead of always using the default value in the test project. This will be useful, for example, to allow the MSVC runtime library to be changed (e.g. `-MDd` => `-MTd`). However, some projects may currently depend on this not being done, so we need to activate the behavior using a policy. This change was originally made by commit v3.6.0-rc1~160^2 (try_compile: Honor CMAKE_<LANG>_FLAGS_<CONFIG> changes, 2016-04-11) but without the policy and so had to be reverted during the 3.6 release candidate cycle. Fixes #16174.
This commit is contained in:
parent
8d79375818
commit
d582c23a47
|
@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
|
||||||
to determine whether to report an error on use of deprecated macros or
|
to determine whether to report an error on use of deprecated macros or
|
||||||
functions.
|
functions.
|
||||||
|
|
||||||
|
Policies Introduced by CMake 3.7
|
||||||
|
================================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
CMP0066: Honor per-config flags in try_compile() source-file signature. </policy/CMP0066>
|
||||||
|
|
||||||
Policies Introduced by CMake 3.4
|
Policies Introduced by CMake 3.4
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
CMP0066
|
||||||
|
-------
|
||||||
|
|
||||||
|
Honor per-config flags in :command:`try_compile` source-file signature.
|
||||||
|
|
||||||
|
The source file signature of the :command:`try_compile` command uses the value
|
||||||
|
of the :variable:`CMAKE_<LANG>_FLAGS` variable in the test project so that the
|
||||||
|
test compilation works as it would in the main project. However, CMake 3.6 and
|
||||||
|
below do not also honor config-specific compiler flags such as those in the
|
||||||
|
:variable:`CMAKE_<LANG>_FLAGS_DEBUG` variable. CMake 3.7 and above prefer to
|
||||||
|
honor config-specific compiler flags too. This policy provides compatibility
|
||||||
|
for projects that do not expect config-specific compiler flags to be used.
|
||||||
|
|
||||||
|
The ``OLD`` behavior of this policy is to ignore config-specific flag
|
||||||
|
variables like :variable:`CMAKE_<LANG>_FLAGS_DEBUG` and only use CMake's
|
||||||
|
built-in defaults for the current compiler and platform.
|
||||||
|
|
||||||
|
The ``NEW`` behavior of this policy is to honor config-specific flag
|
||||||
|
variabldes like :variable:`CMAKE_<LANG>_FLAGS_DEBUG`.
|
||||||
|
|
||||||
|
This policy was introduced in CMake version 3.7. Unlike most policies,
|
||||||
|
CMake version |release| does *not* warn by default when this policy
|
||||||
|
is not set and simply uses OLD behavior. See documentation of the
|
||||||
|
:variable:`CMAKE_POLICY_WARNING_CMP0066 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
|
||||||
|
variable to control the warning.
|
||||||
|
|
||||||
|
.. include:: DEPRECATED.txt
|
|
@ -0,0 +1,7 @@
|
||||||
|
try_compile-config-flags
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
* The :command:`try_compile` command source file signature now honors
|
||||||
|
configuration-specific flags (e.g. :variable:`CMAKE_<LANG>_FLAGS_DEBUG`)
|
||||||
|
in the generated test project. Previously only the default such flags
|
||||||
|
for the current toolchain were used. See policy :policy:`CMP0066`.
|
|
@ -15,6 +15,8 @@ warn by default:
|
||||||
policy :policy:`CMP0060`.
|
policy :policy:`CMP0060`.
|
||||||
* ``CMAKE_POLICY_WARNING_CMP0065`` controls the warning for
|
* ``CMAKE_POLICY_WARNING_CMP0065`` controls the warning for
|
||||||
policy :policy:`CMP0065`.
|
policy :policy:`CMP0065`.
|
||||||
|
* ``CMAKE_POLICY_WARNING_CMP0066`` controls the warning for
|
||||||
|
policy :policy:`CMP0066`.
|
||||||
|
|
||||||
This variable should not be set by a project in CMake code. Project
|
This variable should not be set by a project in CMake code. Project
|
||||||
developers running CMake may set this variable in their cache to
|
developers running CMake may set this variable in their cache to
|
||||||
|
|
|
@ -334,6 +334,43 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
|
||||||
" ${COMPILE_DEFINITIONS}\")\n",
|
" ${COMPILE_DEFINITIONS}\")\n",
|
||||||
li->c_str(), li->c_str());
|
li->c_str(), li->c_str());
|
||||||
}
|
}
|
||||||
|
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0066)) {
|
||||||
|
case cmPolicies::WARN:
|
||||||
|
if (this->Makefile->PolicyOptionalWarningEnabled(
|
||||||
|
"CMAKE_POLICY_WARNING_CMP0066")) {
|
||||||
|
std::ostringstream w;
|
||||||
|
/* clang-format off */
|
||||||
|
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0066) << "\n"
|
||||||
|
"For compatibility with older versions of CMake, try_compile "
|
||||||
|
"is not honoring caller config-specific compiler flags "
|
||||||
|
"(e.g. CMAKE_C_FLAGS_DEBUG) in the test project."
|
||||||
|
;
|
||||||
|
/* clang-format on */
|
||||||
|
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
||||||
|
}
|
||||||
|
case cmPolicies::OLD:
|
||||||
|
// OLD behavior is to do nothing.
|
||||||
|
break;
|
||||||
|
case cmPolicies::REQUIRED_IF_USED:
|
||||||
|
case cmPolicies::REQUIRED_ALWAYS:
|
||||||
|
this->Makefile->IssueMessage(
|
||||||
|
cmake::FATAL_ERROR,
|
||||||
|
cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0066));
|
||||||
|
case cmPolicies::NEW: {
|
||||||
|
// NEW behavior is to pass config-specific compiler flags.
|
||||||
|
static std::string const cfgDefault = "DEBUG";
|
||||||
|
std::string const cfg =
|
||||||
|
!tcConfig.empty() ? cmSystemTools::UpperCase(tcConfig) : cfgDefault;
|
||||||
|
for (std::set<std::string>::iterator li = testLangs.begin();
|
||||||
|
li != testLangs.end(); ++li) {
|
||||||
|
std::string const langFlagsCfg = "CMAKE_" + *li + "_FLAGS_" + cfg;
|
||||||
|
const char* flagsCfg = this->Makefile->GetDefinition(langFlagsCfg);
|
||||||
|
fprintf(fout, "set(%s %s)\n", langFlagsCfg.c_str(),
|
||||||
|
cmOutputConverter::EscapeForCMake(flagsCfg ? flagsCfg : "")
|
||||||
|
.c_str());
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0056)) {
|
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0056)) {
|
||||||
case cmPolicies::WARN:
|
case cmPolicies::WARN:
|
||||||
if (this->Makefile->PolicyOptionalWarningEnabled(
|
if (this->Makefile->PolicyOptionalWarningEnabled(
|
||||||
|
|
|
@ -203,7 +203,10 @@ class cmPolicy;
|
||||||
SELECT(POLICY, CMP0065, \
|
SELECT(POLICY, CMP0065, \
|
||||||
"Do not add flags to export symbols from executables without " \
|
"Do not add flags to export symbols from executables without " \
|
||||||
"the ENABLE_EXPORTS target property.", \
|
"the ENABLE_EXPORTS target property.", \
|
||||||
3, 4, 0, cmPolicies::WARN)
|
3, 4, 0, cmPolicies::WARN) \
|
||||||
|
SELECT(POLICY, CMP0066, \
|
||||||
|
"Honor per-config flags in try_compile() source-file signature.", 3, \
|
||||||
|
7, 0, cmPolicies::WARN)
|
||||||
|
|
||||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||||
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
before try_compile with CMP0066 WARN-default
|
||||||
|
after try_compile with CMP0066 WARN-default
|
||||||
|
*
|
||||||
|
CMake Warning \(dev\) at CMP0066.cmake:[0-9]+ \(try_compile\):
|
||||||
|
Policy CMP0066 is not set: Honor per-config flags in try_compile\(\)
|
||||||
|
source-file signature. Run "cmake --help-policy CMP0066" for policy
|
||||||
|
details. Use the cmake_policy command to set the policy and suppress this
|
||||||
|
warning.
|
||||||
|
|
||||||
|
For compatibility with older versions of CMake, try_compile is not honoring
|
||||||
|
caller config-specific compiler flags \(e.g. CMAKE_C_FLAGS_DEBUG\) in the
|
||||||
|
test project.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:[0-9]+ \(include\)
|
||||||
|
This warning is for project developers. Use -Wno-dev to suppress it.$
|
|
@ -0,0 +1,4 @@
|
||||||
|
-- try_compile with CMP0066 WARN-default worked as expected
|
||||||
|
-- try_compile with CMP0066 WARN-enabled worked as expected
|
||||||
|
-- try_compile with CMP0066 OLD worked as expected
|
||||||
|
-- try_compile with CMP0066 NEW worked as expected
|
|
@ -0,0 +1,58 @@
|
||||||
|
enable_language(C)
|
||||||
|
set(CMAKE_C_FLAGS_RELEASE "-DPP_ERROR ${CMAKE_C_FLAGS_DEBUG}")
|
||||||
|
set(CMAKE_TRY_COMPILE_CONFIGURATION Release)
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
message("before try_compile with CMP0066 WARN-default")
|
||||||
|
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||||
|
OUTPUT_VARIABLE out
|
||||||
|
)
|
||||||
|
string(REPLACE "\n" "\n " out " ${out}")
|
||||||
|
if(NOT RESULT)
|
||||||
|
message(FATAL_ERROR "try_compile with CMP0066 WARN-default failed but should have passed:\n${out}")
|
||||||
|
else()
|
||||||
|
message(STATUS "try_compile with CMP0066 WARN-default worked as expected")
|
||||||
|
endif()
|
||||||
|
message("after try_compile with CMP0066 WARN-default")
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
set(CMAKE_POLICY_WARNING_CMP0066 ON)
|
||||||
|
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||||
|
OUTPUT_VARIABLE out
|
||||||
|
)
|
||||||
|
string(REPLACE "\n" "\n " out " ${out}")
|
||||||
|
if(NOT RESULT)
|
||||||
|
message(FATAL_ERROR "try_compile with CMP0066 WARN-enabled failed but should have passed:\n${out}")
|
||||||
|
else()
|
||||||
|
message(STATUS "try_compile with CMP0066 WARN-enabled worked as expected")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
cmake_policy(SET CMP0066 OLD)
|
||||||
|
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||||
|
OUTPUT_VARIABLE out
|
||||||
|
)
|
||||||
|
string(REPLACE "\n" "\n " out " ${out}")
|
||||||
|
if(NOT RESULT)
|
||||||
|
message(FATAL_ERROR "try_compile with CMP0066 OLD failed but should have passed:\n${out}")
|
||||||
|
else()
|
||||||
|
message(STATUS "try_compile with CMP0066 OLD worked as expected")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
cmake_policy(SET CMP0066 NEW)
|
||||||
|
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||||
|
OUTPUT_VARIABLE out
|
||||||
|
)
|
||||||
|
string(REPLACE "\n" "\n " out " ${out}")
|
||||||
|
if(RESULT)
|
||||||
|
message(FATAL_ERROR "try_compile with CMP0066 NEW passed but should have failed:\n${out}")
|
||||||
|
elseif(NOT "x${out}" MATCHES "PP_ERROR is defined")
|
||||||
|
message(FATAL_ERROR "try_compile with CMP0066 NEW did not fail with PP_ERROR:\n${out}")
|
||||||
|
else()
|
||||||
|
message(STATUS "try_compile with CMP0066 NEW worked as expected")
|
||||||
|
endif()
|
|
@ -25,6 +25,7 @@ run_cmake(TargetTypeInvalid)
|
||||||
run_cmake(TargetTypeStatic)
|
run_cmake(TargetTypeStatic)
|
||||||
|
|
||||||
run_cmake(CMP0056)
|
run_cmake(CMP0056)
|
||||||
|
run_cmake(CMP0066)
|
||||||
|
|
||||||
if(RunCMake_GENERATOR MATCHES "Make|Ninja")
|
if(RunCMake_GENERATOR MATCHES "Make|Ninja")
|
||||||
# Use a single build tree for a few tests without cleaning.
|
# Use a single build tree for a few tests without cleaning.
|
||||||
|
|
|
@ -2,3 +2,6 @@ int main(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef PP_ERROR
|
||||||
|
#error PP_ERROR is defined
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue