mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
Merge topic 'file-GENERATE-CMP0189'
deb7b4b658
file(GENERATE): Record CMP0189 at each call site9b862e7013
cmGeneratorTarget: Pass genex evaluation context to IsTransitiveProperty Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Merge-request: !11234
This commit is contained in:
@@ -18,7 +18,9 @@ target properties transitively because they are among the
|
||||
This policy provides compatibility for projects that have not been updated to
|
||||
expect the new behavior. It takes effect during buildsystem generation.
|
||||
Generator expressions are evaluated in each directory using the policy setting
|
||||
as of the end of its ``CMakeLists.txt``.
|
||||
as of the end of its ``CMakeLists.txt``. As an exception, generator
|
||||
expressions evaluated by the :command:`file(GENERATE)` command use the
|
||||
policy setting as of its call site.
|
||||
|
||||
The ``OLD`` behavior of this policy is for :genex:`TARGET_PROPERTY` to not
|
||||
evaluate :prop_tgt:`LINK_LIBRARIES` and :prop_tgt:`INTERFACE_LINK_LIBRARIES`
|
||||
|
@@ -234,3 +234,12 @@ Changes made since CMake 4.1.0 include the following.
|
||||
* This version made no changes to documented features or interfaces.
|
||||
Some implementation updates were made to support ecosystem changes
|
||||
and/or fix regressions.
|
||||
|
||||
4.1.2
|
||||
-----
|
||||
|
||||
* The :command:`file(GENERATE)` command, when evaluating generator
|
||||
expressions, now uses the value of policy :policy:`CMP0189` as of
|
||||
each call site. Previously, it used the value as of the end of the
|
||||
directory's ``CMakeLists.txt``, as all other generator expression
|
||||
evaluations do.
|
||||
|
@@ -4,6 +4,11 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmPolicies.h"
|
||||
|
||||
namespace cm {
|
||||
namespace GenEx {
|
||||
|
||||
@@ -15,5 +20,18 @@ Context::Context(cmLocalGenerator const* lg, std::string config,
|
||||
{
|
||||
}
|
||||
|
||||
void Context::SetCMP0189(cmPolicies::PolicyStatus cmp0189)
|
||||
{
|
||||
this->CMP0189 = cmp0189;
|
||||
}
|
||||
|
||||
cmPolicies::PolicyStatus Context::GetCMP0189() const
|
||||
{
|
||||
if (this->CMP0189.has_value()) {
|
||||
return *this->CMP0189;
|
||||
}
|
||||
return this->LG->GetPolicyStatus(cmPolicies::CMP0189);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,10 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmPolicies.h"
|
||||
|
||||
class cmLocalGenerator;
|
||||
|
||||
namespace cm {
|
||||
@@ -17,6 +21,12 @@ struct Context final
|
||||
cmLocalGenerator const* LG;
|
||||
std::string Config;
|
||||
std::string Language;
|
||||
|
||||
void SetCMP0189(cmPolicies::PolicyStatus cmp0189);
|
||||
cmPolicies::PolicyStatus GetCMP0189() const;
|
||||
|
||||
private:
|
||||
cm::optional<cmPolicies::PolicyStatus> CMP0189;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -35,9 +35,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
|
||||
this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
|
||||
} else {
|
||||
this->TopIsTransitiveProperty =
|
||||
this->Target
|
||||
->IsTransitiveProperty(this->Property, context.LG, context.Config,
|
||||
this)
|
||||
this->Target->IsTransitiveProperty(this->Property, context, this)
|
||||
.has_value();
|
||||
}
|
||||
|
||||
|
@@ -23,7 +23,8 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
||||
bool inputIsContent, std::string newLineCharacter, mode_t permissions,
|
||||
cmPolicies::PolicyStatus policyStatusCMP0070)
|
||||
cmPolicies::PolicyStatus policyStatusCMP0070,
|
||||
cmPolicies::PolicyStatus policyStatusCMP0189)
|
||||
: Input(std::move(input))
|
||||
, Target(std::move(target))
|
||||
, OutputFileExpr(std::move(outputFileExpr))
|
||||
@@ -31,6 +32,7 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
|
||||
, InputIsContent(inputIsContent)
|
||||
, NewLineCharacter(std::move(newLineCharacter))
|
||||
, PolicyStatusCMP0070(policyStatusCMP0070)
|
||||
, PolicyStatusCMP0189(policyStatusCMP0189)
|
||||
, Permissions(permissions)
|
||||
{
|
||||
}
|
||||
@@ -41,6 +43,7 @@ void cmGeneratorExpressionEvaluationFile::Generate(
|
||||
std::map<std::string, std::string>& outputFiles, mode_t perm)
|
||||
{
|
||||
cm::GenEx::Context context(lg, config, lang);
|
||||
context.SetCMP0189(this->PolicyStatusCMP0189);
|
||||
std::string rawCondition = this->Condition->GetInput();
|
||||
cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
|
||||
if (!rawCondition.empty()) {
|
||||
@@ -126,6 +129,7 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
|
||||
|
||||
for (std::string const& lang : enabledLanguages) {
|
||||
cm::GenEx::Context context(lg, config, lang);
|
||||
context.SetCMP0189(this->PolicyStatusCMP0189);
|
||||
std::string const name = this->GetOutputFileName(context, target);
|
||||
cmSourceFile* sf = lg->GetMakefile()->GetOrCreateGeneratedSource(name);
|
||||
|
||||
|
@@ -31,7 +31,8 @@ public:
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
||||
bool inputIsContent, std::string newLineCharacter, mode_t permissions,
|
||||
cmPolicies::PolicyStatus policyStatusCMP0070);
|
||||
cmPolicies::PolicyStatus policyStatusCMP0070,
|
||||
cmPolicies::PolicyStatus policyStatusCMP0189);
|
||||
|
||||
void Generate(cmLocalGenerator* lg);
|
||||
|
||||
@@ -64,5 +65,6 @@ private:
|
||||
bool const InputIsContent;
|
||||
std::string const NewLineCharacter;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0070;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0189;
|
||||
mode_t Permissions;
|
||||
};
|
||||
|
@@ -3097,8 +3097,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||
cmGeneratorTarget::UseTo usage = cmGeneratorTarget::UseTo::Compile;
|
||||
|
||||
if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
|
||||
target->IsTransitiveProperty(propertyName, eval->Context.LG,
|
||||
eval->Context.Config,
|
||||
target->IsTransitiveProperty(propertyName, eval->Context,
|
||||
dagCheckerParent)) {
|
||||
interfacePropertyName = std::string(transitiveProp->InterfaceName);
|
||||
isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
|
||||
|
@@ -1032,8 +1032,7 @@ public:
|
||||
BuiltinTransitiveProperties;
|
||||
|
||||
cm::optional<TransitiveProperty> IsTransitiveProperty(
|
||||
cm::string_view prop, cmLocalGenerator const* lg,
|
||||
std::string const& config,
|
||||
cm::string_view prop, cm::GenEx::Context const& context,
|
||||
cmGeneratorExpressionDAGChecker const* dagChecker) const;
|
||||
|
||||
bool HaveInstallTreeRPATH(std::string const& config) const;
|
||||
|
@@ -177,7 +177,7 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
|
||||
|
||||
cm::optional<cmGeneratorTarget::TransitiveProperty>
|
||||
cmGeneratorTarget::IsTransitiveProperty(
|
||||
cm::string_view prop, cmLocalGenerator const* lg, std::string const& config,
|
||||
cm::string_view prop, cm::GenEx::Context const& context,
|
||||
cmGeneratorExpressionDAGChecker const* dagChecker) const
|
||||
{
|
||||
cm::optional<TransitiveProperty> result;
|
||||
@@ -192,15 +192,14 @@ cmGeneratorTarget::IsTransitiveProperty(
|
||||
if (i != BuiltinTransitiveProperties.end() &&
|
||||
// Look up CMP0189 in the context where evaluation occurs,
|
||||
// not where the target was created.
|
||||
lg->GetPolicyStatus(cmPolicies::CMP0189) != cmPolicies::NEW &&
|
||||
prop == "LINK_LIBRARIES"_s) {
|
||||
context.GetCMP0189() != cmPolicies::NEW && prop == "LINK_LIBRARIES"_s) {
|
||||
i = BuiltinTransitiveProperties.end();
|
||||
}
|
||||
if (i != BuiltinTransitiveProperties.end()) {
|
||||
result = i->second;
|
||||
if (result->Usage != cmGeneratorTarget::UseTo::Compile) {
|
||||
cmPolicies::PolicyStatus cmp0166 =
|
||||
lg->GetPolicyStatus(cmPolicies::CMP0166);
|
||||
context.LG->GetPolicyStatus(cmPolicies::CMP0166);
|
||||
if ((cmp0166 == cmPolicies::WARN || cmp0166 == cmPolicies::OLD) &&
|
||||
(prop == "LINK_DIRECTORIES"_s || prop == "LINK_DEPENDS"_s ||
|
||||
prop == "LINK_OPTIONS"_s)) {
|
||||
@@ -211,7 +210,7 @@ cmGeneratorTarget::IsTransitiveProperty(
|
||||
// Honor TRANSITIVE_COMPILE_PROPERTIES and TRANSITIVE_LINK_PROPERTIES
|
||||
// from the link closure when we are not evaluating the closure itself.
|
||||
CustomTransitiveProperties const& ctp =
|
||||
this->GetCustomTransitiveProperties(config, propertyFor);
|
||||
this->GetCustomTransitiveProperties(context.Config, propertyFor);
|
||||
auto ci = ctp.find(std::string(prop));
|
||||
if (ci != ctp.end()) {
|
||||
result = ci->second;
|
||||
|
@@ -942,7 +942,8 @@ void cmMakefile::AddEvaluationFile(
|
||||
cm::make_unique<cmGeneratorExpressionEvaluationFile>(
|
||||
inputFile, targetName, std::move(outputName), std::move(condition),
|
||||
inputIsContent, newLineCharacter, permissions,
|
||||
this->GetPolicyStatus(cmPolicies::CMP0070)));
|
||||
this->GetPolicyStatus(cmPolicies::CMP0070),
|
||||
this->GetPolicyStatus(cmPolicies::CMP0189)));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>> const&
|
||||
|
@@ -1,10 +1,18 @@
|
||||
set(out "${CMAKE_CURRENT_BINARY_DIR}/out-OLD-$<CONFIG>.txt")
|
||||
file(GENERATE OUTPUT "${out}" CONTENT "# file(GENERATE) produced:
|
||||
${in_LINK_LIBRARIES}
|
||||
")
|
||||
add_custom_target(check-CMP0189-OLD ALL VERBATIM
|
||||
COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> -Dout=${out} -P${CMAKE_CURRENT_SOURCE_DIR}/check-OLD.cmake
|
||||
)
|
||||
|
||||
cmake_policy(SET CMP0189 NEW)
|
||||
set(out "${CMAKE_CURRENT_BINARY_DIR}/out-$<CONFIG>.txt")
|
||||
set(out "${CMAKE_CURRENT_BINARY_DIR}/out-NEW-$<CONFIG>.txt")
|
||||
file(GENERATE OUTPUT "${out}" CONTENT "# file(GENERATE) produced:
|
||||
${in_LINK_LIBRARIES}
|
||||
")
|
||||
add_custom_target(check-CMP0189-NEW ALL VERBATIM
|
||||
COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> -Dout=${out} -P${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
|
||||
COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> -Dout=${out} -P${CMAKE_CURRENT_SOURCE_DIR}/check-NEW.cmake
|
||||
COMMAND check-args
|
||||
"$<TARGET_PROPERTY:iface1,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface1,INTERFACE_LINK_LIBRARIES>" ""
|
||||
|
32
Tests/CustomTransitiveProperties/CMP0189/check-OLD.cmake
Normal file
32
Tests/CustomTransitiveProperties/CMP0189/check-OLD.cmake
Normal file
@@ -0,0 +1,32 @@
|
||||
set(expect [[
|
||||
# file\(GENERATE\) produced:
|
||||
iface1 LINK_LIBRARIES: ''
|
||||
iface1 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface2 LINK_LIBRARIES: ''
|
||||
iface2 INTERFACE_LINK_LIBRARIES: 'iface1'
|
||||
static1 LINK_LIBRARIES: 'iface2'
|
||||
static1 INTERFACE_LINK_LIBRARIES: '\$<LINK_ONLY:iface2>'
|
||||
main LINK_LIBRARIES: 'static1;object1'
|
||||
main INTERFACE_LINK_LIBRARIES: ''
|
||||
iface10 LINK_LIBRARIES: ''
|
||||
iface10 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface11 LINK_LIBRARIES: ''
|
||||
iface11 INTERFACE_LINK_LIBRARIES: 'iface10'
|
||||
static10 LINK_LIBRARIES: 'iface11;iface10'
|
||||
static10 INTERFACE_LINK_LIBRARIES: 'iface11;iface10'
|
||||
static11 LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||
static11 INTERFACE_LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||
main10 LINK_LIBRARIES: 'static11;static10;static10;iface11;iface11;iface10'
|
||||
main10 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface20 LINK_LIBRARIES: ''
|
||||
iface20 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface21 LINK_LIBRARIES: ''
|
||||
iface21 INTERFACE_LINK_LIBRARIES: 'iface20'
|
||||
static20 LINK_LIBRARIES: 'iface21'
|
||||
static20 INTERFACE_LINK_LIBRARIES: '\$<LINK_ONLY:iface21>'
|
||||
static21 LINK_LIBRARIES: 'static20;iface21'
|
||||
static21 INTERFACE_LINK_LIBRARIES: '\$<LINK_ONLY:static20>;\$<LINK_ONLY:iface21>'
|
||||
main20 LINK_LIBRARIES: 'static21;static20'
|
||||
main20 INTERFACE_LINK_LIBRARIES: ''
|
||||
]])
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../check-common.cmake)
|
Reference in New Issue
Block a user