From 2fb2c32f9b304bc71b039754f9b9170fd6f27a6f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 6 Jan 2013 13:49:20 +0100 Subject: [PATCH] Add the COMPATIBLE_INTERFACE_STRING property. --- Source/cmExportFileGenerator.cxx | 6 ++ Source/cmGeneratorExpressionEvaluator.cxx | 7 ++ Source/cmTarget.cxx | 65 +++++++++++++++++++ Source/cmTarget.h | 5 ++ Tests/CompatibleInterface/CMakeLists.txt | 13 ++++ Tests/CompatibleInterface/main.cpp | 12 ++++ Tests/ExportImport/Export/CMakeLists.txt | 9 ++- Tests/ExportImport/Import/A/CMakeLists.txt | 2 + .../Import/A/deps_shared_iface.cpp | 4 ++ .../InterfaceString-builtin-prop-result.txt | 1 + .../InterfaceString-builtin-prop-stderr.txt | 5 ++ .../InterfaceString-builtin-prop.cmake | 11 ++++ ...faceString-mismatch-depend-self-result.txt | 1 + ...faceString-mismatch-depend-self-stderr.txt | 3 + ...InterfaceString-mismatch-depend-self.cmake | 11 ++++ ...nterfaceString-mismatch-depends-result.txt | 1 + ...nterfaceString-mismatch-depends-stderr.txt | 3 + .../InterfaceString-mismatch-depends.cmake | 10 +++ .../InterfaceString-mismatched-use-result.txt | 1 + .../InterfaceString-mismatched-use-stderr.txt | 4 ++ .../InterfaceString-mismatched-use.cmake | 9 +++ .../CompatibleInterface/RunCMakeTest.cmake | 4 ++ 22 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index ef1fc5f3b..96e0aea0e 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -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 ifaceProperties; getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties); + getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); getCompatibleInterfaceProperties(target, ifaceProperties, 0); diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index c468c3934..0c61a122f 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -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(); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d2839c542..e3be51034 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -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(cmTarget *tgt, const char *prop, bool *) return tgt->GetPropertyAsBool(prop); } +//---------------------------------------------------------------------------- +template<> +const char *getTypedProperty(cmTarget *tgt, const char *prop, + const char **) +{ + return tgt->GetProperty(prop); +} + //---------------------------------------------------------------------------- template 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 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(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& 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 void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee, @@ -5536,6 +5594,13 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, { return; } + checkPropertyConsistency(this, li->Target, + "COMPATIBLE_INTERFACE_STRING", + emitted, config, 0); + if (cmSystemTools::GetErrorOccuredFlag()) + { + return; + } } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 9909bae60..4457becdf 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -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 &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. diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt index 728065231..259b5a186 100644 --- a/Tests/CompatibleInterface/CMakeLists.txt +++ b/Tests/CompatibleInterface/CMakeLists.txt @@ -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_PROP1> $<$>:BOOL_PROP2> $<$>:BOOL_PROP3> + $<$,prop1>:STRING_PROP1> + $<$,prop2>:STRING_PROP2> + $<$,prop3>:STRING_PROP3> ) diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp index ae0e985c8..f5e6e3891 100644 --- a/Tests/CompatibleInterface/main.cpp +++ b/Tests/CompatibleInterface/main.cpp @@ -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) diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index 599229340..eecfd6a31 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -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 diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 4df57715b..187c48ae0 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -170,6 +170,7 @@ target_compile_definitions(deps_shared_iface testSharedLibDepends $<$>:PIC_PROPERTY_IS_ON> $<$>:CUSTOM_PROPERTY_IS_ON> + $<$,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 $<$>:PIC_PROPERTY_IS_ON> $<$>:CUSTOM_PROPERTY_IS_ON> + $<$,testcontent>:CUSTOM_STRING_IS_MATCH> ) diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp index a33f200ec..2f0e74a07 100644 --- a/Tests/ExportImport/Import/A/deps_shared_iface.cpp +++ b/Tests/ExportImport/Import/A/deps_shared_iface.cpp @@ -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 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt new file mode 100644 index 000000000..6a293b4f1 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake new file mode 100644 index 000000000..5221a129c --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake @@ -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) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt new file mode 100644 index 000000000..0476da97d --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt @@ -0,0 +1,3 @@ +CMake Error: Property SOMEPROP on target "user" does +not match the INTERFACE_SOMEPROP property requirement +of dependency "foo". diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake new file mode 100644 index 000000000..187f29f79 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake @@ -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) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt new file mode 100644 index 000000000..d885c09d9 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt @@ -0,0 +1,3 @@ +CMake Error: The INTERFACE_SOMEPROP property of "bar" does +not agree with the value of SOMEPROP already determined +for "user". diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake new file mode 100644 index 000000000..73cc3fc55 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake @@ -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) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt new file mode 100644 index 000000000..723daec09 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake new file mode 100644 index 000000000..af3ce8fbc --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake @@ -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 $<$,prop>:bar>) diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake index ba8917b86..922ad7fc7 100644 --- a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake @@ -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)