Make INTERFACE determined properties readable in generator expressions.
The properties are evaluated as link-dependent interface properties when evaluating the generator expressions.
This commit is contained in:
parent
d9afacced3
commit
e98799105b
|
@ -106,3 +106,16 @@ cmGeneratorExpressionDAGChecker::checkGraph() const
|
||||||
}
|
}
|
||||||
return DAG;
|
return DAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
|
||||||
|
{
|
||||||
|
const cmGeneratorExpressionDAGChecker *top = this;
|
||||||
|
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
||||||
|
while (parent)
|
||||||
|
{
|
||||||
|
parent = parent->Parent;
|
||||||
|
top = parent;
|
||||||
|
}
|
||||||
|
return top->Property == "LINK_LIBRARIES";
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,9 @@ struct cmGeneratorExpressionDAGChecker
|
||||||
|
|
||||||
void reportError(cmGeneratorExpressionContext *context,
|
void reportError(cmGeneratorExpressionContext *context,
|
||||||
const std::string &expr);
|
const std::string &expr);
|
||||||
|
|
||||||
|
bool EvaluatingLinkLibraries();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result checkGraph() const;
|
Result checkGraph() const;
|
||||||
|
|
||||||
|
|
|
@ -442,6 +442,27 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
const char *prop = target->GetProperty(propertyName.c_str());
|
const char *prop = target->GetProperty(propertyName.c_str());
|
||||||
if (!prop)
|
if (!prop)
|
||||||
{
|
{
|
||||||
|
if (target->IsImported())
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
if (propertyName == "POSITION_INDEPENDENT_CODE")
|
||||||
|
{
|
||||||
|
return target->GetLinkInterfaceDependentBoolProperty(
|
||||||
|
"POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
|
||||||
|
}
|
||||||
|
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
|
||||||
|
context->Config))
|
||||||
|
{
|
||||||
|
return target->GetLinkInterfaceDependentBoolProperty(
|
||||||
|
propertyName,
|
||||||
|
context->Config) ? "1" : "0";
|
||||||
|
}
|
||||||
|
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4612,6 +4612,53 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||||
return propContent;
|
return propContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
|
||||||
|
const char *interfaceProperty,
|
||||||
|
const char *config)
|
||||||
|
{
|
||||||
|
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
||||||
|
|
||||||
|
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||||
|
|
||||||
|
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||||
|
deps.begin();
|
||||||
|
li != deps.end(); ++li)
|
||||||
|
{
|
||||||
|
if (!li->Target)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const char *prop = li->Target->GetProperty(interfaceProperty);
|
||||||
|
if (!prop)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> props;
|
||||||
|
cmSystemTools::ExpandListArgument(prop, props);
|
||||||
|
|
||||||
|
for(std::vector<std::string>::iterator pi = props.begin();
|
||||||
|
pi != props.end(); ++pi)
|
||||||
|
{
|
||||||
|
if (*pi == p)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||||
|
const char *config)
|
||||||
|
{
|
||||||
|
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
|
||||||
|
config);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -495,6 +495,8 @@ public:
|
||||||
void GetLinkDependentTargetsForProperty(const std::string &p,
|
void GetLinkDependentTargetsForProperty(const std::string &p,
|
||||||
std::set<std::string> &targets);
|
std::set<std::string> &targets);
|
||||||
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
||||||
|
bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||||
|
const char *config);
|
||||||
|
|
||||||
void AddLinkDependentTargetsForProperties(
|
void AddLinkDependentTargetsForProperties(
|
||||||
const std::map<cmStdString, cmStdString> &map);
|
const std::map<cmStdString, cmStdString> &map);
|
||||||
|
|
|
@ -216,6 +216,7 @@ if(BUILD_TESTING)
|
||||||
ADD_TEST_MACRO(PolicyScope PolicyScope)
|
ADD_TEST_MACRO(PolicyScope PolicyScope)
|
||||||
ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
|
ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
|
||||||
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
|
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
|
||||||
|
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
|
||||||
set_tests_properties(EmptyLibrary PROPERTIES
|
set_tests_properties(EmptyLibrary PROPERTIES
|
||||||
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test")
|
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test")
|
||||||
ADD_TEST_MACRO(CrossCompile CrossCompile)
|
ADD_TEST_MACRO(CrossCompile CrossCompile)
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
project(CompatibleInterface)
|
||||||
|
|
||||||
|
add_library(iface1 empty.cpp)
|
||||||
|
set_property(TARGET iface1 APPEND PROPERTY
|
||||||
|
COMPATIBLE_INTERFACE_BOOL
|
||||||
|
BOOL_PROP1
|
||||||
|
BOOL_PROP2
|
||||||
|
BOOL_PROP3
|
||||||
|
)
|
||||||
|
|
||||||
|
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
|
||||||
|
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
|
||||||
|
|
||||||
|
add_executable(CompatibleInterface main.cpp)
|
||||||
|
target_link_libraries(CompatibleInterface iface1)
|
||||||
|
|
||||||
|
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
|
||||||
|
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
|
||||||
|
|
||||||
|
target_compile_definitions(CompatibleInterface
|
||||||
|
PRIVATE
|
||||||
|
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
|
||||||
|
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
|
||||||
|
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
// no content
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
#ifndef BOOL_PROP1
|
||||||
|
#error Expected BOOL_PROP1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOL_PROP2
|
||||||
|
#error Expected BOOL_PROP2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOL_PROP3
|
||||||
|
#error Expected BOOL_PROP3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -165,7 +165,11 @@ target_compile_definitions(deps_iface PRIVATE testLibDepends)
|
||||||
add_executable(deps_shared_iface deps_shared_iface.cpp)
|
add_executable(deps_shared_iface deps_shared_iface.cpp)
|
||||||
target_link_libraries(deps_shared_iface testSharedLibDepends)
|
target_link_libraries(deps_shared_iface testSharedLibDepends)
|
||||||
target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends)
|
target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends)
|
||||||
target_compile_definitions(deps_shared_iface PRIVATE testSharedLibDepends)
|
target_compile_definitions(deps_shared_iface
|
||||||
|
PRIVATE
|
||||||
|
testSharedLibDepends
|
||||||
|
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||||
|
)
|
||||||
|
|
||||||
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
@ -194,4 +198,5 @@ target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
|
||||||
target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
|
target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
|
||||||
target_compile_definitions(deps_shared_iface2
|
target_compile_definitions(deps_shared_iface2
|
||||||
PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
|
PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
|
||||||
|
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PIC_PROPERTY_IS_ON
|
||||||
|
#error Expected PIC_PROPERTY_IS_ON
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TEST_SUBDIR_LIB
|
#ifdef TEST_SUBDIR_LIB
|
||||||
#include "subdir.h"
|
#include "subdir.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -53,6 +53,7 @@ add_RunCMake_test(ObjectLibrary)
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
add_RunCMake_test(PositionIndependentCode)
|
add_RunCMake_test(PositionIndependentCode)
|
||||||
endif()
|
endif()
|
||||||
|
add_RunCMake_test(CompatibleInterface)
|
||||||
|
|
||||||
add_RunCMake_test(build_command)
|
add_RunCMake_test(build_command)
|
||||||
add_RunCMake_test(find_package)
|
add_RunCMake_test(find_package)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(${RunCMake_TEST} CXX)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error in CMakeLists.txt:
|
||||||
|
Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
|
||||||
|
COMPATIBLE_INTERFACE_BOOL property. This is not allowed. Only
|
||||||
|
user-defined properties may appear listed in the COMPATIBLE_INTERFACE_BOOL
|
||||||
|
property.
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
add_library(foo UNKNOWN IMPORTED)
|
||||||
|
add_library(bar UNKNOWN IMPORTED)
|
||||||
|
|
||||||
|
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL INCLUDE_DIRECTORIES)
|
||||||
|
set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
|
||||||
|
set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
|
||||||
|
|
||||||
|
add_executable(user main.cpp)
|
||||||
|
set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES OFF)
|
||||||
|
target_link_libraries(user foo bar)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,3 @@
|
||||||
|
CMake Error: Property SOMEPROP on target "user" does
|
||||||
|
not match the INTERFACE_SOMEPROP property requirement
|
||||||
|
of dependency "foo".
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
add_library(foo UNKNOWN IMPORTED)
|
||||||
|
add_library(bar UNKNOWN IMPORTED)
|
||||||
|
|
||||||
|
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
|
||||||
|
set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
|
||||||
|
set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP ON)
|
||||||
|
|
||||||
|
add_executable(user main.cpp)
|
||||||
|
set_property(TARGET user PROPERTY SOMEPROP OFF)
|
||||||
|
target_link_libraries(user foo bar)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,3 @@
|
||||||
|
CMake Error: The INTERFACE_SOMEPROP property of "bar" does
|
||||||
|
not agree with the value of SOMEPROP already determined
|
||||||
|
for "user".
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
add_library(foo UNKNOWN IMPORTED)
|
||||||
|
add_library(bar UNKNOWN IMPORTED)
|
||||||
|
|
||||||
|
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
|
||||||
|
set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
|
||||||
|
set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP OFF)
|
||||||
|
|
||||||
|
add_executable(user main.cpp)
|
||||||
|
target_link_libraries(user foo bar)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error: Property SOMEPROP on target "user" is
|
||||||
|
implied to be FALSE because it was used to determine the link libraries
|
||||||
|
already. The INTERFACE_SOMEPROP property on
|
||||||
|
dependency "foo" is in conflict.
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
add_library(foo UNKNOWN IMPORTED)
|
||||||
|
add_library(bar UNKNOWN IMPORTED)
|
||||||
|
|
||||||
|
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
|
||||||
|
set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
|
||||||
|
|
||||||
|
add_executable(user main.cpp)
|
||||||
|
target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)
|
|
@ -0,0 +1,6 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(InterfaceBool-mismatch-depends)
|
||||||
|
run_cmake(InterfaceBool-mismatch-depend-self)
|
||||||
|
run_cmake(InterfaceBool-mismatched-use)
|
||||||
|
run_cmake(InterfaceBool-builtin-prop)
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue