Add the COMPATIBLE_INTERFACE_STRING property.

This commit is contained in:
Stephen Kelly 2013-01-06 13:49:20 +01:00
parent cd66b9131d
commit 2fb2c32f9b
22 changed files with 186 additions and 1 deletions

View File

@ -217,6 +217,9 @@ void getCompatibleInterfaceProperties(cmTarget *target,
getPropertyContents(li->Target,
"COMPATIBLE_INTERFACE_BOOL",
ifaceProperties);
getPropertyContents(li->Target,
"COMPATIBLE_INTERFACE_STRING",
ifaceProperties);
}
}
@ -227,10 +230,13 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
{
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
target, properties);
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
target, properties);
std::set<std::string> ifaceProperties;
getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
getCompatibleInterfaceProperties(target, ifaceProperties, 0);

View File

@ -462,6 +462,13 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
propertyName,
context->Config) ? "1" : "0";
}
if (target->IsLinkInterfaceDependentStringProperty(propertyName,
context->Config))
{
return target->GetLinkInterfaceDependentStringProperty(
propertyName,
context->Config);
}
return std::string();
}

View File

@ -907,6 +907,17 @@ void cmTarget::DefineProperties(cmake *cm)
"then it must have the same boolean value as all others, and if the "
"property is not set, then it is ignored.");
cm->DefineProperty
("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET,
"Properties which must be string-compatible with their link interface",
"The COMPATIBLE_INTERFACE_STRING property may contain a list of "
"properties for this target which must be the same when evaluated as "
"a string in the INTERFACE of all linked dependencies. For example, "
"if a property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
"property content in all dependencies must be equal with each "
"other, and with the \"FOO\" property in this target. If the "
"property is not set, then it is ignored.");
cm->DefineProperty
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
"Deprecated install support.",
@ -4511,6 +4522,14 @@ bool getTypedProperty<bool>(cmTarget *tgt, const char *prop, bool *)
return tgt->GetPropertyAsBool(prop);
}
//----------------------------------------------------------------------------
template<>
const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
const char **)
{
return tgt->GetProperty(prop);
}
//----------------------------------------------------------------------------
template<typename PropertyType>
bool consistentProperty(PropertyType lhs, PropertyType rhs);
@ -4522,6 +4541,17 @@ bool consistentProperty(bool lhs, bool rhs)
return lhs == rhs;
}
//----------------------------------------------------------------------------
template<>
bool consistentProperty(const char *lhs, const char *rhs)
{
if (!lhs && !rhs)
return true;
if (!lhs || !rhs)
return false;
return strcmp(lhs, rhs) == 0;
}
//----------------------------------------------------------------------------
template<typename PropertyType>
PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
@ -4667,6 +4697,17 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
0);
}
//----------------------------------------------------------------------------
const char * cmTarget::GetLinkInterfaceDependentStringProperty(
const std::string &p,
const char *config)
{
return checkInterfacePropertyCompatibility<const char *>(this,
p,
config,
"empty", 0);
}
//----------------------------------------------------------------------------
bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
const char *interfaceProperty,
@ -4714,6 +4755,14 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
config);
}
//----------------------------------------------------------------------------
bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
const char *config)
{
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
config);
}
//----------------------------------------------------------------------------
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
{
@ -5468,6 +5517,15 @@ bool getLinkInterfaceDependentProperty(cmTarget *tgt,
return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
}
template<>
const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
const std::string prop,
const char *config,
const char **)
{
return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
}
//----------------------------------------------------------------------------
template<typename PropertyType>
void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
@ -5536,6 +5594,13 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
{
return;
}
checkPropertyConsistency<const char *>(this, li->Target,
"COMPATIBLE_INTERFACE_STRING",
emitted, config, 0);
if (cmSystemTools::GetErrorOccuredFlag())
{
return;
}
}
}

View File

@ -501,12 +501,17 @@ public:
bool IsNullImpliedByLinkLibraries(const std::string &p);
bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
const char *config);
bool IsLinkInterfaceDependentStringProperty(const std::string &p,
const char *config);
void AddLinkDependentTargetsForProperties(
const std::map<cmStdString, cmStdString> &map);
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
const char *config);
const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
const char *config);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.

View File

@ -14,21 +14,34 @@ set_property(TARGET iface1 APPEND PROPERTY
BOOL_PROP3
BOOL_PROP4
)
set_property(TARGET iface1 APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING
STRING_PROP1
STRING_PROP2
STRING_PROP3
)
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
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)
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
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>
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
)

View File

@ -11,6 +11,18 @@
#error Expected BOOL_PROP3
#endif
#ifndef STRING_PROP1
#error Expected STRING_PROP1
#endif
#ifndef STRING_PROP2
#error Expected STRING_PROP2
#endif
#ifndef STRING_PROP3
#error Expected STRING_PROP3
#endif
#include "iface2.h"
int main(int argc, char **argv)

View File

@ -181,7 +181,14 @@ set_property(TARGET testSharedLibRequired
PROPERTY
INTERFACE_CUSTOM_PROP ON
)
set_property(TARGET testSharedLibRequired
APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING CUSTOM_STRING
)
set_property(TARGET testSharedLibRequired
PROPERTY
INTERFACE_CUSTOM_STRING testcontent
)
add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
set_property(TARGET testSharedLibDepends APPEND PROPERTY

View File

@ -170,6 +170,7 @@ target_compile_definitions(deps_shared_iface
testSharedLibDepends
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
)
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
@ -201,4 +202,5 @@ target_compile_definitions(deps_shared_iface2
PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
)

View File

@ -16,6 +16,10 @@
#error Expected CUSTOM_PROPERTY_IS_ON
#endif
#ifndef CUSTOM_STRING_IS_MATCH
#error Expected CUSTOM_STRING_IS_MATCH
#endif
#ifdef TEST_SUBDIR_LIB
#include "subdir.h"
#endif

View File

@ -0,0 +1,5 @@
CMake Error in CMakeLists.txt:
Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
COMPATIBLE_INTERFACE_STRING property. This is not allowed. Only
user-defined properties may appear listed in the
COMPATIBLE_INTERFACE_STRING property.

View File

@ -0,0 +1,11 @@
add_library(foo UNKNOWN IMPORTED)
add_library(bar UNKNOWN IMPORTED)
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES foo_inc)
set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES bar_inc)
add_executable(user main.cpp)
set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
target_link_libraries(user foo bar)

View File

@ -0,0 +1,3 @@
CMake Error: Property SOMEPROP on target "user" does
not match the INTERFACE_SOMEPROP property requirement
of dependency "foo".

View File

@ -0,0 +1,11 @@
add_library(foo UNKNOWN IMPORTED)
add_library(bar UNKNOWN IMPORTED)
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP prop)
add_executable(user main.cpp)
set_property(TARGET user PROPERTY SOMEPROP different)
target_link_libraries(user foo bar)

View File

@ -0,0 +1,3 @@
CMake Error: The INTERFACE_SOMEPROP property of "bar" does
not agree with the value of SOMEPROP already determined
for "user".

View File

@ -0,0 +1,10 @@
add_library(foo UNKNOWN IMPORTED)
add_library(bar UNKNOWN IMPORTED)
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP foo)
set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP bar)
add_executable(user main.cpp)
target_link_libraries(user foo bar)

View File

@ -0,0 +1,4 @@
CMake Error: Property SOMEPROP on target "user" is
implied to be empty because it was used to determine the link libraries
already. The INTERFACE_SOMEPROP property on
dependency "foo" is in conflict.

View File

@ -0,0 +1,9 @@
add_library(foo UNKNOWN IMPORTED)
add_library(bar UNKNOWN IMPORTED)
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
add_executable(user main.cpp)
target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)

View File

@ -4,3 +4,7 @@ run_cmake(InterfaceBool-mismatch-depends)
run_cmake(InterfaceBool-mismatch-depend-self)
run_cmake(InterfaceBool-mismatched-use)
run_cmake(InterfaceBool-builtin-prop)
run_cmake(InterfaceString-mismatch-depends)
run_cmake(InterfaceString-mismatch-depend-self)
run_cmake(InterfaceString-mismatched-use)
run_cmake(InterfaceString-builtin-prop)