From 655e98bf7149eb3757a0587409076326edeb9c04 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 7 Feb 2013 00:47:31 +0100 Subject: [PATCH] Ensure type specific compatible interface properties do not intersect. Before, the boolean version would always win, and the string one would be ignored. --- Source/cmTarget.cxx | 34 ++++++++++++++++--- .../InterfaceString-Bool-Conflict-result.txt | 1 + .../InterfaceString-Bool-Conflict-stderr.txt | 5 +++ .../InterfaceString-Bool-Conflict.cmake | 9 +++++ .../CompatibleInterface/RunCMakeTest.cmake | 1 + 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 4109929ca..b92bf775c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -906,7 +906,10 @@ void cmTarget::DefineProperties(cmake *cm) "consistent with each other, and with the \"FOO\" property in the " "dependee. Consistency in this sense has the meaning that if the " "property is set, then it must have the same boolean value as all " - "others, and if the property is not set, then it is ignored."); + "others, and if the property is not set, then it is ignored. Note that " + "for each dependee, the set of properties from this property must not " + "intersect with the set of properties from the " + "COMPATIBLE_INTERFACE_STRING property."); cm->DefineProperty ("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET, @@ -917,7 +920,10 @@ void cmTarget::DefineProperties(cmake *cm) "if a property \"FOO\" appears in the list, then for each dependee, the " "\"INTERFACE_FOO\" property content in all of its dependencies must be " "equal with each other, and with the \"FOO\" property in the dependee. " - "If the property is not set, then it is ignored."); + "If the property is not set, then it is ignored. Note that for each " + "dependee, the set of properties from this property must not intersect " + "with the set of properties from the COMPATIBLE_INTERFACE_BOOL " + "property."); cm->DefineProperty ("POST_INSTALL_SCRIPT", cmProperty::TARGET, @@ -5616,7 +5622,8 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, { const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); - std::set emitted; + std::set emittedBools; + std::set emittedStrings; for(cmComputeLinkInformation::ItemVector::const_iterator li = deps.begin(); @@ -5629,19 +5636,36 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, checkPropertyConsistency(this, li->Target, "COMPATIBLE_INTERFACE_BOOL", - emitted, config, 0); + emittedBools, config, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } checkPropertyConsistency(this, li->Target, "COMPATIBLE_INTERFACE_STRING", - emitted, config, 0); + emittedStrings, config, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } } + + for(std::set::const_iterator li = emittedBools.begin(); + li != emittedBools.end(); ++li) + { + const std::set::const_iterator si = emittedStrings.find(*li); + if (si != emittedStrings.end()) + { + cmOStringStream e; + e << "Property \"" << *li << "\" appears in both the " + "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING " + "property in the dependencies of target \"" << this->GetName() << + "\". This is not allowed. A property may only require compatibility " + "in a boolean interpretation or a string interpretation, but not both."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + break; + } + } } //---------------------------------------------------------------------------- diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt new file mode 100644 index 000000000..5a8f99df2 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt @@ -0,0 +1,5 @@ +CMake Error in CMakeLists.txt: + Property "SOMETHING" appears in both the COMPATIBLE_INTERFACE_BOOL and the + COMPATIBLE_INTERFACE_STRING property in the dependencies of target "user". + This is not allowed. A property may only require compatibility in a + boolean interpretation or a string interpretation, but not both. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake new file mode 100644 index 000000000..711368a80 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake @@ -0,0 +1,9 @@ + +add_library(foo UNKNOWN IMPORTED) +add_library(bar UNKNOWN IMPORTED) + +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMETHING) +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMETHING) + +add_executable(user main.cpp) +target_link_libraries(user foo bar) diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake index 922ad7fc7..976815111 100644 --- a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake @@ -8,3 +8,4 @@ run_cmake(InterfaceString-mismatch-depends) run_cmake(InterfaceString-mismatch-depend-self) run_cmake(InterfaceString-mismatched-use) run_cmake(InterfaceString-builtin-prop) +run_cmake(InterfaceString-Bool-Conflict)