From 1800f702a056b2eb25eb35daf9ed8d6474ecd0f9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 16 Jan 2013 17:54:30 +0100 Subject: [PATCH 1/5] Populate the link information cache before checking dependent properties. The dependent properties check can require the link information. --- Source/cmTarget.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 815da408c..45862fb93 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -5422,14 +5422,14 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head) info = 0; } + // Store the information for this configuration. + cmTargetLinkInformationMap::value_type entry(key, info); + i = this->LinkInformation.insert(entry).first; + if (info) { this->CheckPropertyCompatibility(info, config); } - - // Store the information for this configuration. - cmTargetLinkInformationMap::value_type entry(key, info); - i = this->LinkInformation.insert(entry).first; } return i->second; } From d9afacced34b2ef17a6c3ca2f66975272cf8473f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 18 Jan 2013 16:10:20 +0100 Subject: [PATCH 2/5] Exit early if we find an inconsistent property. Further messages about inconsistency are distracting. --- Source/cmTarget.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 45862fb93..7a2ead34c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4533,6 +4533,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, "INTERFACE_" << p << " property requirement\nof " "dependency \"" << li->Target->GetName() << "\".\n"; cmSystemTools::Error(e.str().c_str()); + break; } else { @@ -4559,6 +4560,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, "INTERFACE_" << p << " property on\ndependency \"" << li->Target->GetName() << "\" is in conflict.\n"; cmSystemTools::Error(e.str().c_str()); + break; } else { @@ -4586,6 +4588,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, "of " << p << " already determined\nfor \"" << this->GetName() << "\".\n"; cmSystemTools::Error(e.str().c_str()); + break; } else { From e98799105bdb296e8d9f5b3ef5cf99bcebcafc40 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 19 Jan 2013 11:21:14 +0100 Subject: [PATCH 3/5] Make INTERFACE determined properties readable in generator expressions. The properties are evaluated as link-dependent interface properties when evaluating the generator expressions. --- Source/cmGeneratorExpressionDAGChecker.cxx | 13 +++++ Source/cmGeneratorExpressionDAGChecker.h | 3 ++ Source/cmGeneratorExpressionEvaluator.cxx | 21 +++++++++ Source/cmTarget.cxx | 47 +++++++++++++++++++ Source/cmTarget.h | 2 + Tests/CMakeLists.txt | 1 + Tests/CompatibleInterface/CMakeLists.txt | 28 +++++++++++ Tests/CompatibleInterface/empty.cpp | 1 + Tests/CompatibleInterface/main.cpp | 17 +++++++ Tests/ExportImport/Import/A/CMakeLists.txt | 7 ++- .../Import/A/deps_shared_iface.cpp | 4 ++ Tests/RunCMake/CMakeLists.txt | 1 + .../CompatibleInterface/CMakeLists.txt | 3 ++ .../InterfaceBool-builtin-prop-result.txt | 1 + .../InterfaceBool-builtin-prop-stderr.txt | 5 ++ .../InterfaceBool-builtin-prop.cmake | 11 +++++ ...erfaceBool-mismatch-depend-self-result.txt | 1 + ...erfaceBool-mismatch-depend-self-stderr.txt | 3 ++ .../InterfaceBool-mismatch-depend-self.cmake | 11 +++++ .../InterfaceBool-mismatch-depends-result.txt | 1 + .../InterfaceBool-mismatch-depends-stderr.txt | 3 ++ .../InterfaceBool-mismatch-depends.cmake | 10 ++++ .../InterfaceBool-mismatched-use-result.txt | 1 + .../InterfaceBool-mismatched-use-stderr.txt | 4 ++ .../InterfaceBool-mismatched-use.cmake | 9 ++++ .../CompatibleInterface/RunCMakeTest.cmake | 6 +++ Tests/RunCMake/CompatibleInterface/main.cpp | 5 ++ 27 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 Tests/CompatibleInterface/CMakeLists.txt create mode 100644 Tests/CompatibleInterface/empty.cpp create mode 100644 Tests/CompatibleInterface/main.cpp create mode 100644 Tests/RunCMake/CompatibleInterface/CMakeLists.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt create mode 100644 Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/CompatibleInterface/main.cpp diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 2e5b5ae11..057f4c3d5 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -106,3 +106,16 @@ cmGeneratorExpressionDAGChecker::checkGraph() const } 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"; +} diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 48f26ed38..31692910d 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -35,6 +35,9 @@ struct cmGeneratorExpressionDAGChecker void reportError(cmGeneratorExpressionContext *context, const std::string &expr); + + bool EvaluatingLinkLibraries(); + private: Result checkGraph() const; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 8e40815af..e84288016 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -442,6 +442,27 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode const char *prop = target->GetProperty(propertyName.c_str()); 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(); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 7a2ead34c..c1c484b1e 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4612,6 +4612,53 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, 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 props; + cmSystemTools::ExpandListArgument(prop, props); + + for(std::vector::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& languages) const { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 69a00c14c..b3e17b242 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -495,6 +495,8 @@ public: void GetLinkDependentTargetsForProperty(const std::string &p, std::set &targets); bool IsNullImpliedByLinkLibraries(const std::string &p); + bool IsLinkInterfaceDependentBoolProperty(const std::string &p, + const char *config); void AddLinkDependentTargetsForProperties( const std::map &map); diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2f7df01cf..0c7589238 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -216,6 +216,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(PolicyScope PolicyScope) ADD_TEST_MACRO(EmptyLibrary EmptyLibrary) ADD_TEST_MACRO(CompileDefinitions CompileDefinitions) + ADD_TEST_MACRO(CompatibleInterface CompatibleInterface) set_tests_properties(EmptyLibrary PROPERTIES PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test") ADD_TEST_MACRO(CrossCompile CrossCompile) diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt new file mode 100644 index 000000000..d0eb60f25 --- /dev/null +++ b/Tests/CompatibleInterface/CMakeLists.txt @@ -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_PROP1> + $<$>:BOOL_PROP2> + $<$>:BOOL_PROP3> +) diff --git a/Tests/CompatibleInterface/empty.cpp b/Tests/CompatibleInterface/empty.cpp new file mode 100644 index 000000000..00323299c --- /dev/null +++ b/Tests/CompatibleInterface/empty.cpp @@ -0,0 +1 @@ +// no content diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp new file mode 100644 index 000000000..b7c66386c --- /dev/null +++ b/Tests/CompatibleInterface/main.cpp @@ -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; +} diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 4812e7e1f..83331cfcb 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -165,7 +165,11 @@ target_compile_definitions(deps_iface PRIVATE testLibDepends) add_executable(deps_shared_iface deps_shared_iface.cpp) target_link_libraries(deps_shared_iface 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 + $<$>:PIC_PROPERTY_IS_ON> +) if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") 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_compile_definitions(deps_shared_iface2 PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB + $<$>:PIC_PROPERTY_IS_ON> ) diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp index 43f832a1e..8ed032e15 100644 --- a/Tests/ExportImport/Import/A/deps_shared_iface.cpp +++ b/Tests/ExportImport/Import/A/deps_shared_iface.cpp @@ -8,6 +8,10 @@ #endif #endif +#ifndef PIC_PROPERTY_IS_ON +#error Expected PIC_PROPERTY_IS_ON +#endif + #ifdef TEST_SUBDIR_LIB #include "subdir.h" #endif diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 9b133b299..fc1960fbd 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -53,6 +53,7 @@ add_RunCMake_test(ObjectLibrary) if(NOT WIN32) add_RunCMake_test(PositionIndependentCode) endif() +add_RunCMake_test(CompatibleInterface) add_RunCMake_test(build_command) add_RunCMake_test(find_package) diff --git a/Tests/RunCMake/CompatibleInterface/CMakeLists.txt b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt new file mode 100644 index 000000000..68dd8d6a1 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt new file mode 100644 index 000000000..1a925b602 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake new file mode 100644 index 000000000..5feb4d5cc --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-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_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) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt new file mode 100644 index 000000000..0476da97d --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-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/InterfaceBool-mismatch-depend-self.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake new file mode 100644 index 000000000..90543e8d3 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-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_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) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt new file mode 100644 index 000000000..d885c09d9 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-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/InterfaceBool-mismatch-depends.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake new file mode 100644 index 000000000..69be79632 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-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_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) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt new file mode 100644 index 000000000..8556ee0b6 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake new file mode 100644 index 000000000..ccfad0ac7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-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_BOOL SOMEPROP) +set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON) + +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 new file mode 100644 index 000000000..ba8917b86 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake @@ -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) diff --git a/Tests/RunCMake/CompatibleInterface/main.cpp b/Tests/RunCMake/CompatibleInterface/main.cpp new file mode 100644 index 000000000..65eddcf84 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/main.cpp @@ -0,0 +1,5 @@ + +int main(int argc, char **argv) +{ + return 0; +} From bd82bb4787410a0bdd6120b8c449f5d31ecc4c28 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 20 Jan 2013 17:18:23 +0100 Subject: [PATCH 4/5] Clear the link information in ClearLinkMaps. The cache here needs to be cleared if GetLinkInformation is called at configure-time, such as during an export(). The next commit does exactly that, and without this patch, the LinkLanguage test would fail. --- Source/cmTarget.cxx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c1c484b1e..2600db5c4 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1520,6 +1520,13 @@ void cmTarget::ClearLinkMaps() this->Internal->LinkImplMap.clear(); this->Internal->LinkInterfaceMap.clear(); this->Internal->LinkClosureMap.clear(); + for (cmTargetLinkInformationMap::const_iterator it + = this->LinkInformation.begin(); + it != this->LinkInformation.end(); ++it) + { + delete it->second; + } + this->LinkInformation.clear(); } //---------------------------------------------------------------------------- From 830246e841d24cc9513c857859a4327ffb1d3da5 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 20 Jan 2013 17:09:29 +0100 Subject: [PATCH 5/5] Export the COMPATIBLE_INTERFACE_BOOL content properties --- Source/cmExportBuildFileGenerator.cxx | 1 + Source/cmExportFileGenerator.cxx | 74 +++++++++++++++++++ Source/cmExportFileGenerator.h | 2 + Source/cmExportInstallFileGenerator.cxx | 1 + Tests/ExportImport/Export/CMakeLists.txt | 9 +++ Tests/ExportImport/Import/A/CMakeLists.txt | 2 + .../Import/A/deps_shared_iface.cpp | 4 + 7 files changed, 93 insertions(+) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 61e130d52..7147f86be 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -74,6 +74,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); + this->PopulateCompatibleInterfaceProperties(te, properties); this->GenerateInterfaceProperties(te, os, properties); } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 4a7c6f929..3a6294ad9 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -21,6 +21,7 @@ #include "cmTarget.h" #include "cmTargetExport.h" #include "cmVersion.h" +#include "cmComputeLinkInformation.h" #include @@ -177,6 +178,79 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, properties, missingTargets); } + +//---------------------------------------------------------------------------- +void getPropertyContents(cmTarget *tgt, const char *prop, + std::set &ifaceProperties) +{ + const char *p = tgt->GetProperty(prop); + if (!p) + { + return; + } + std::vector content; + cmSystemTools::ExpandListArgument(p, content); + for (std::vector::const_iterator ci = content.begin(); + ci != content.end(); ++ci) + { + ifaceProperties.insert(*ci); + } +} + +//---------------------------------------------------------------------------- +void getCompatibleInterfaceProperties(cmTarget *target, + std::set &ifaceProperties, + const char *config) +{ + cmComputeLinkInformation *info = target->GetLinkInformation(config); + + const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); + + for(cmComputeLinkInformation::ItemVector::const_iterator li = + deps.begin(); + li != deps.end(); ++li) + { + if (!li->Target) + { + continue; + } + getPropertyContents(li->Target, + "COMPATIBLE_INTERFACE_BOOL", + ifaceProperties); + } +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::PopulateCompatibleInterfaceProperties( + cmTarget *target, + ImportPropertyMap &properties) +{ + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL", + target, properties); + + std::set ifaceProperties; + + getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties); + + getCompatibleInterfaceProperties(target, ifaceProperties, 0); + + std::vector configNames; + target->GetMakefile()->GetConfigurations(configNames); + + for (std::vector::const_iterator ci = configNames.begin(); + ci != configNames.end(); ++ci) + { + getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str()); + } + + for (std::set::const_iterator it = ifaceProperties.begin(); + it != ifaceProperties.end(); ++it) + { + this->PopulateInterfaceProperty(("INTERFACE_" + *it).c_str(), + target, properties); + } +} + //---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target, std::ostream& os, diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index eb3f3c34c..b39df0f8b 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -103,6 +103,8 @@ protected: std::vector &missingTargets); void PopulateInterfaceProperty(const char *propName, cmTarget *target, ImportPropertyMap &properties); + void PopulateCompatibleInterfaceProperties(cmTarget *target, + ImportPropertyMap &properties); void GenerateInterfaceProperties(cmTarget *target, std::ostream& os, const ImportPropertyMap &properties); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 965f63d09..526a6bea3 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -91,6 +91,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); + this->PopulateCompatibleInterfaceProperties(te, properties); this->GenerateInterfaceProperties(te, os, properties); } diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index dd615d135..599229340 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -173,6 +173,15 @@ set_property(TARGET testSharedLibRequired APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" ) +set_property(TARGET testSharedLibRequired + APPEND PROPERTY + COMPATIBLE_INTERFACE_BOOL CUSTOM_PROP +) +set_property(TARGET testSharedLibRequired + PROPERTY + INTERFACE_CUSTOM_PROP ON +) + 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 83331cfcb..4df57715b 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -169,6 +169,7 @@ target_compile_definitions(deps_shared_iface PRIVATE testSharedLibDepends $<$>:PIC_PROPERTY_IS_ON> + $<$>:CUSTOM_PROPERTY_IS_ON> ) if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") @@ -199,4 +200,5 @@ target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends b target_compile_definitions(deps_shared_iface2 PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB $<$>:PIC_PROPERTY_IS_ON> + $<$>:CUSTOM_PROPERTY_IS_ON> ) diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp index 8ed032e15..a33f200ec 100644 --- a/Tests/ExportImport/Import/A/deps_shared_iface.cpp +++ b/Tests/ExportImport/Import/A/deps_shared_iface.cpp @@ -12,6 +12,10 @@ #error Expected PIC_PROPERTY_IS_ON #endif +#ifndef CUSTOM_PROPERTY_IS_ON +#error Expected CUSTOM_PROPERTY_IS_ON +#endif + #ifdef TEST_SUBDIR_LIB #include "subdir.h" #endif