summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-01-19 10:21:14 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-01-20 16:06:47 (GMT)
commite98799105bdb296e8d9f5b3ef5cf99bcebcafc40 (patch)
tree3cc97cedcc2bac471a9868e95a9982d35de6258c
parentd9afacced34b2ef17a6c3ca2f66975272cf8473f (diff)
downloadCMake-e98799105bdb296e8d9f5b3ef5cf99bcebcafc40.zip
CMake-e98799105bdb296e8d9f5b3ef5cf99bcebcafc40.tar.gz
CMake-e98799105bdb296e8d9f5b3ef5cf99bcebcafc40.tar.bz2
Make INTERFACE determined properties readable in generator expressions.
The properties are evaluated as link-dependent interface properties when evaluating the generator expressions.
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx13
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h3
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx21
-rw-r--r--Source/cmTarget.cxx47
-rw-r--r--Source/cmTarget.h2
-rw-r--r--Tests/CMakeLists.txt1
-rw-r--r--Tests/CompatibleInterface/CMakeLists.txt28
-rw-r--r--Tests/CompatibleInterface/empty.cpp1
-rw-r--r--Tests/CompatibleInterface/main.cpp17
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt7
-rw-r--r--Tests/ExportImport/Import/A/deps_shared_iface.cpp4
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt5
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake11
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake11
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake10
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt4
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake9
-rw-r--r--Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/CompatibleInterface/main.cpp5
27 files changed, 218 insertions, 1 deletions
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 2e5b5ae..057f4c3 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 48f26ed..3169291 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 8e40815a..e842880 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 7a2ead3..c1c484b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4613,6 +4613,53 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
}
//----------------------------------------------------------------------------
+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
{
for(std::vector<cmSourceFile*>::const_iterator
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 69a00c1..b3e17b2 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -495,6 +495,8 @@ public:
void GetLinkDependentTargetsForProperty(const std::string &p,
std::set<std::string> &targets);
bool IsNullImpliedByLinkLibraries(const std::string &p);
+ bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
+ const char *config);
void AddLinkDependentTargetsForProperties(
const std::map<cmStdString, cmStdString> &map);
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2f7df01..0c75892 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 0000000..d0eb60f
--- /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:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
+ $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
+ $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
+)
diff --git a/Tests/CompatibleInterface/empty.cpp b/Tests/CompatibleInterface/empty.cpp
new file mode 100644
index 0000000..0032329
--- /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 0000000..b7c6638
--- /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 4812e7e..83331cf 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
+ $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>: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
+ $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>: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 43f832a..8ed032e 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 9b133b2..fc1960f 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 0000000..68dd8d6
--- /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 0000000..d00491f
--- /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 0000000..1a925b6
--- /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 0000000..5feb4d5
--- /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 0000000..d00491f
--- /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 0000000..0476da9
--- /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 0000000..90543e8
--- /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 0000000..d00491f
--- /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 0000000..d885c09
--- /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 0000000..69be796
--- /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 0000000..d00491f
--- /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 0000000..8556ee0
--- /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 0000000..ccfad0a
--- /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 $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)
diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
new file mode 100644
index 0000000..ba8917b
--- /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 0000000..65eddcf
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/main.cpp
@@ -0,0 +1,5 @@
+
+int main(int argc, char **argv)
+{
+ return 0;
+}