summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/FindQt4.cmake24
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmDocumentVariables.cxx7
-rw-r--r--Source/cmExportFileGenerator.cxx10
-rw-r--r--Source/cmExportInstallFileGenerator.h3
-rw-r--r--Source/cmGeneratorExpression.cxx28
-rw-r--r--Source/cmGeneratorExpression.h8
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx4
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx41
-rw-r--r--Source/cmLocalGenerator.cxx5
-rw-r--r--Source/cmLocalGenerator.h3
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx27
-rw-r--r--Source/cmMakefile.cxx21
-rw-r--r--Source/cmMakefile.h2
-rw-r--r--Source/cmTarget.cxx129
-rw-r--r--Source/cmTarget.h7
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx10
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx17
-rw-r--r--Source/cmTargetPropCommandBase.cxx9
-rw-r--r--Tests/CMakeCommands/target_link_libraries/CMakeLists.txt5
-rw-r--r--Tests/CompatibleInterface/CMakeLists.txt15
-rw-r--r--Tests/ObjectLibrary/A/CMakeLists.txt2
-rw-r--r--Tests/ObjectLibrary/B/CMakeLists.txt6
-rw-r--r--Tests/ObjectLibrary/B/b.h7
-rw-r--r--Tests/ObjectLibrary/CMakeLists.txt8
-rw-r--r--Tests/ObjectLibrary/mainAB.c8
-rw-r--r--Tests/QtAutomoc/Adir/CMakeLists.txt8
-rw-r--r--Tests/QtAutomoc/Adir/libA.cpp13
-rw-r--r--Tests/QtAutomoc/Adir/libA.h18
-rw-r--r--Tests/QtAutomoc/Bdir/CMakeLists.txt10
-rw-r--r--Tests/QtAutomoc/Bdir/libB.cpp13
-rw-r--r--Tests/QtAutomoc/Bdir/libB.h21
-rw-r--r--Tests/QtAutomoc/CMakeLists.txt16
-rw-r--r--Tests/QtAutomoc/libC.cpp13
-rw-r--r--Tests/QtAutomoc/libC.h22
-rw-r--r--Tests/QtAutomoc/main.cpp4
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt5
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake9
-rw-r--r--Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget.cmake7
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp1
-rw-r--r--Tests/RunCMake/include_directories/DebugIncludes-stderr.txt14
-rw-r--r--Tests/RunCMake/include_directories/DebugIncludes.cmake5
-rw-r--r--Tests/RunCMake/include_directories/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/include_directories/TID-bad-target-result.txt1
-rw-r--r--Tests/RunCMake/include_directories/TID-bad-target-stderr.txt4
-rw-r--r--Tests/RunCMake/include_directories/TID-bad-target.cmake6
51 files changed, 435 insertions, 176 deletions
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 35420b4..5baee01 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -985,11 +985,19 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
endmacro()
macro(_qt4_add_target_depends _QT_MODULE)
- _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_INTERFACE_LIBRARIES ${ARGN})
+ get_target_property(_configs Qt4::${_QT_MODULE} IMPORTED_CONFIGURATIONS)
+ foreach(_config ${_configs})
+ _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_INTERFACE_LIBRARIES_${_config} ${ARGN})
+ endforeach()
+ set(_configs)
endmacro()
macro(_qt4_add_target_private_depends _QT_MODULE)
- _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_DEPENDENT_LIBRARIES ${ARGN})
+ get_target_property(_configs ${_QT_MODULE} IMPORTED_CONFIGURATIONS)
+ foreach(_config ${_configs})
+ _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_DEPENDENT_LIBRARIES_${_config} ${ARGN})
+ endforeach()
+ set(_configs)
endmacro()
@@ -1067,10 +1075,14 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
set(_isWin32 $<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>)
set(_isNotExcluded $<NOT:$<BOOL:$<TARGET_PROPERTY:QT4_NO_LINK_QTMAIN>>>)
set(_isPolicyNEW $<TARGET_POLICY:CMP0020>)
- set_property(TARGET Qt4::QtCore APPEND PROPERTY
- IMPORTED_LINK_INTERFACE_LIBRARIES
- $<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt4::qtmain>
- )
+ get_target_property(_configs Qt4::QtCore IMPORTED_CONFIGURATIONS)
+ foreach(_config ${_configs})
+ set_property(TARGET Qt4::QtCore APPEND PROPERTY
+ IMPORTED_LINK_INTERFACE_LIBRARIES_${_config}
+ $<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt4::qtmain>
+ )
+ endforeach()
+ unset(_configs)
unset(_isExe)
unset(_isWin32)
unset(_isNotExcluded)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 1b33cde..fa1354c 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -2,5 +2,5 @@
set(CMake_VERSION_MAJOR 2)
set(CMake_VERSION_MINOR 8)
set(CMake_VERSION_PATCH 10)
-set(CMake_VERSION_TWEAK 20130208)
+set(CMake_VERSION_TWEAK 20130212)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index 9f7c0c1..1826f42 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -1167,9 +1167,10 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
("CMAKE_BUILD_INTERFACE_INCLUDES", cmProperty::VARIABLE,
"Automatically add the current source- and build directories "
"to the INTERFACE_INCLUDE_DIRECTORIES.",
- "If this variable is enabled, CMake automatically adds for each "
- "target ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} "
- "to the INTERFACE_INCLUDE_DIRECTORIES."
+ "If this variable is enabled, CMake automatically adds for each shared "
+ "library target, static library target, module target and executable "
+ "target, ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} to "
+ "the INTERFACE_INCLUDE_DIRECTORIES."
"By default CMAKE_BUILD_INTERFACE_INCLUDES is OFF.",
false,
"Variables that Control the Build");
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 7e4c3df..fbed95a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -315,14 +315,6 @@ cmExportFileGenerator::AddTargetNamespace(std::string &input,
}
//----------------------------------------------------------------------------
-static bool isGeneratorExpression(const std::string &lib)
-{
- const std::string::size_type openpos = lib.find("$<");
- return (openpos != std::string::npos)
- && (lib.find(">", openpos) != std::string::npos);
-}
-
-//----------------------------------------------------------------------------
void
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string &input,
@@ -344,7 +336,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
for(std::vector<std::string>::iterator li = parts.begin();
li != parts.end(); ++li)
{
- if (!isGeneratorExpression(*li))
+ if (cmGeneratorExpression::Find(*li) == std::string::npos)
{
this->AddTargetNamespace(*li, target, missingTargets);
}
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 7a70431..20dd57a 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -15,10 +15,7 @@
#include "cmExportFileGenerator.h"
class cmInstallExportGenerator;
-class cmInstallFilesGenerator;
class cmInstallTargetGenerator;
-class cmTargetExport;
-class cmExportSet;
/** \class cmExportInstallFileGenerator
* \brief Generate a file exporting targets from an install tree.
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 7add1bf..5d162fe 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -95,14 +95,13 @@ const char *cmCompiledGeneratorExpression::Evaluate(
for ( ; it != end; ++it)
{
- const std::string result = (*it)->Evaluate(&context, dagChecker);
- this->Output += result;
+ this->Output += (*it)->Evaluate(&context, dagChecker);
for(std::set<cmStdString>::const_iterator
p = context.SeenTargetProperties.begin();
p != context.SeenTargetProperties.end(); ++p)
{
- this->SeenTargetProperties[*p] += result + ";";
+ this->SeenTargetProperties.insert(*p);
}
if (context.HadError)
{
@@ -365,3 +364,26 @@ std::string cmGeneratorExpression::Preprocess(const std::string &input,
assert(!"cmGeneratorExpression::Preprocess called with invalid args");
return std::string();
}
+
+//----------------------------------------------------------------------------
+std::string::size_type cmGeneratorExpression::Find(const std::string &input)
+{
+ const std::string::size_type openpos = input.find("$<");
+ if (openpos != std::string::npos
+ && input.find(">", openpos) != std::string::npos)
+ {
+ return openpos;
+ }
+ return std::string::npos;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpression::IsValidTargetName(const std::string &input)
+{
+ cmsys::RegularExpression targetNameValidator;
+ // The ':' is supported to allow use with IMPORTED targets. At least
+ // Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter.
+ targetNameValidator.compile("^[A-Za-z0-9_.:-]+$");
+
+ return targetNameValidator.find(input.c_str());
+}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 700fe03..489b052 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -62,6 +62,10 @@ public:
static void Split(const std::string &input,
std::vector<std::string> &output);
+ static std::string::size_type Find(const std::string &input);
+
+ static bool IsValidTargetName(const std::string &input);
+
private:
cmGeneratorExpression(const cmGeneratorExpression &);
void operator=(const cmGeneratorExpression &);
@@ -86,7 +90,7 @@ public:
std::set<cmTarget*> const& GetTargets() const
{ return this->Targets; }
- std::map<cmStdString, cmStdString> const& GetSeenTargetProperties() const
+ std::set<cmStdString> const& GetSeenTargetProperties() const
{ return this->SeenTargetProperties; }
~cmCompiledGeneratorExpression();
@@ -120,7 +124,7 @@ private:
bool NeedsParsing;
mutable std::set<cmTarget*> Targets;
- mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
+ mutable std::set<cmStdString> SeenTargetProperties;
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
};
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index b9069ef..0ac1a48 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -148,8 +148,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
return (strcmp(prop, "LINK_LIBRARIES") == 0
|| strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
|| strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
- || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 26) == 0
- || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 35) == 0);
+ || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 25) == 0
+ || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 5d94718..98e0ada 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -333,10 +333,6 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
"$<TARGET_PROPERTY:...> expression requires one or two parameters");
return std::string();
}
- cmsys::RegularExpression targetNameValidator;
- // The ':' is supported to allow use with IMPORTED targets. At least
- // Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter.
- targetNameValidator.compile("^[A-Za-z0-9_.:-]+$");
cmsys::RegularExpression propertyNameValidator;
propertyNameValidator.compile("^[A-Za-z0-9_]+$");
@@ -372,7 +368,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
std::string targetName = parameters.front();
propertyName = parameters[1];
- if (!targetNameValidator.find(targetName.c_str()))
+ if (!cmGeneratorExpression::IsValidTargetName(targetName))
{
if (!propertyNameValidator.find(propertyName.c_str()))
{
@@ -402,7 +398,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
// Keep track of the properties seen while processing.
// The evaluation of the LINK_LIBRARIES generator expressions
- // will check this to ensure that properties form a DAG.
+ // will check this to ensure that properties have one consistent
+ // value for all evaluations.
context->SeenTargetProperties.insert(propertyName);
}
@@ -438,8 +435,17 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
// No error. We just skip cyclic references.
return std::string();
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
- // No error. We're not going to find anything new here.
- return std::string();
+ for (size_t i = 0;
+ i < (sizeof(targetPropertyTransitiveWhitelist) /
+ sizeof(*targetPropertyTransitiveWhitelist));
+ ++i)
+ {
+ if (targetPropertyTransitiveWhitelist[i] == propertyName)
+ {
+ // No error. We're not going to find anything new here.
+ return std::string();
+ }
+ }
case cmGeneratorExpressionDAGChecker::DAG:
break;
}
@@ -455,12 +461,6 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
return std::string();
}
- if (propertyName == "POSITION_INDEPENDENT_CODE")
- {
- context->HadContextSensitiveCondition = true;
- return target->GetLinkInterfaceDependentBoolProperty(
- "POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
- }
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
context->Config))
{
@@ -702,6 +702,14 @@ private:
{
return std::string();
}
+ if(target->GetType() >= cmTarget::UTILITY &&
+ target->GetType() != cmTarget::UNKNOWN_LIBRARY)
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "Target \"" + item
+ + "\" is not an executable or library.");
+ return std::string();
+ }
std::string propertyName = "INTERFACE_" + prop;
const char *propContent = target->GetProperty(propertyName.c_str());
if (!propContent)
@@ -867,10 +875,7 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
// Lookup the referenced target.
std::string name = *parameters.begin();
- cmsys::RegularExpression targetValidator;
- // The ':' is supported to allow use with IMPORTED targets.
- targetValidator.compile("^[A-Za-z0-9_.:-]+$");
- if (!targetValidator.find(name.c_str()))
+ if (!cmGeneratorExpression::IsValidTargetName(name))
{
::reportError(context, content->GetOriginalExpression(),
"Expression syntax not recognized.");
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index ecf6b41..dc39fdc 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1212,7 +1212,8 @@ cmLocalGenerator::ConvertToIncludeReference(std::string const& path)
//----------------------------------------------------------------------------
std::string cmLocalGenerator::GetIncludeFlags(
const std::vector<std::string> &includes,
- const char* lang, bool forResponseFile)
+ const char* lang, bool forResponseFile,
+ const char *config)
{
if(!lang)
{
@@ -1285,7 +1286,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
if(!flagUsed || repeatFlag)
{
if(sysIncludeFlag &&
- this->Makefile->IsSystemIncludeDirectory(i->c_str()))
+ this->Makefile->IsSystemIncludeDirectory(i->c_str(), config))
{
includeFlags << sysIncludeFlag;
}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index b2ff0c4..84cf6ca 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -149,7 +149,8 @@ public:
virtual void AppendFlags(std::string& flags, const char* newFlags);
///! Get the include flags for the current makefile and language
std::string GetIncludeFlags(const std::vector<std::string> &includes,
- const char* lang, bool forResponseFile = false);
+ const char* lang, bool forResponseFile = false,
+ const char *config = 0);
/**
* Encode a list of preprocessor definitions for the compiler
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index d629e71..f6ab0d0 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1961,34 +1961,17 @@ void cmLocalUnixMakefileGenerator3
}
// Build a list of preprocessor definitions for the target.
- std::vector<std::string> defines;
- {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(this->ConfigurationName);
- if(const char* ddefs = this->Makefile->GetProperty("COMPILE_DEFINITIONS"))
- {
- cmSystemTools::ExpandListArgument(ddefs, defines);
- }
- if(const char* cdefs = target.GetProperty("COMPILE_DEFINITIONS"))
- {
- cmSystemTools::ExpandListArgument(cdefs, defines);
- }
- if(const char* dcdefs = this->Makefile->GetProperty(defPropName.c_str()))
- {
- cmSystemTools::ExpandListArgument(dcdefs, defines);
- }
- if(const char* ccdefs = target.GetProperty(defPropName.c_str()))
- {
- cmSystemTools::ExpandListArgument(ccdefs, defines);
- }
- }
+ std::set<std::string> defines;
+ this->AppendDefines(defines, target.GetCompileDefinitions());
+ this->AppendDefines(defines, target.GetCompileDefinitions(
+ this->ConfigurationName.c_str()));
if(!defines.empty())
{
cmakefileStream
<< "\n"
<< "# Preprocessor definitions for this target.\n"
<< "SET(CMAKE_TARGET_DEFINITIONS\n";
- for(std::vector<std::string>::const_iterator di = defines.begin();
+ for(std::set<std::string>::const_iterator di = defines.begin();
di != defines.end(); ++di)
{
cmakefileStream
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index dbd0c36..299e564 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -23,6 +23,7 @@
#include "cmListFileCache.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmDocumentCompileDefinitions.h"
+#include "cmGeneratorExpression.h"
#include "cmTest.h"
#ifdef CMAKE_BUILD_WITH_CMAKE
# include "cmVariableWatch.h"
@@ -1665,10 +1666,24 @@ cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
}
//----------------------------------------------------------------------------
-bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
+bool cmMakefile::IsSystemIncludeDirectory(const char* dir, const char *config)
{
- return (this->SystemIncludeDirectories.find(dir) !=
- this->SystemIncludeDirectories.end());
+ for (std::set<cmStdString>::const_iterator
+ it = this->SystemIncludeDirectories.begin();
+ it != this->SystemIncludeDirectories.end(); ++it)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+
+ std::vector<std::string> incs;
+ cmSystemTools::ExpandListArgument(ge.Parse(*it)
+ ->Evaluate(this, config, false), incs);
+ if (std::find(incs.begin(), incs.end(), dir) != incs.end())
+ {
+ return true;
+ }
+ }
+ return false;
}
void cmMakefile::AddDefinition(const char* name, const char* value)
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index a2783f2..c0020bf 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -547,7 +547,7 @@ public:
* Mark include directories as system directories.
*/
void AddSystemIncludeDirectories(const std::set<cmStdString> &incs);
- bool IsSystemIncludeDirectory(const char* dir);
+ bool IsSystemIncludeDirectory(const char* dir, const char *config);
/** Expand out any arguements in the vector that have ; separated
* strings into multiple arguements. A new vector is created
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index ca0e24b..bf918d5 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -900,24 +900,30 @@ void cmTarget::DefineProperties(cmake *cm)
"Properties which must be compatible with their link interface",
"The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties"
"for this target which must be consistent when evaluated as a boolean "
- "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 consistent with each "
- "other, and with the \"FOO\" property in this target. "
- "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.");
+ "in the INTERFACE of all linked dependees. For example, if a "
+ "property \"FOO\" appears in the list, then for each dependee, the "
+ "\"INTERFACE_FOO\" property content in all of its dependencies must be "
+ "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. 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,
"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.");
+ "a string in the INTERFACE of all linked dependees. For example, "
+ "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. 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,
@@ -2227,7 +2233,15 @@ void cmTarget::GetDirectLinkLibraries(const char *config,
&dagChecker),
libs);
- this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties());
+ std::set<cmStdString> seenProps = cge->GetSeenTargetProperties();
+ for (std::set<cmStdString>::const_iterator it = seenProps.begin();
+ it != seenProps.end(); ++it)
+ {
+ if (!this->GetProperty(it->c_str()))
+ {
+ this->LinkImplicitNullProperties.insert(*it);
+ }
+ }
}
}
@@ -2270,14 +2284,6 @@ static std::string targetNameGenex(const char *lib)
}
//----------------------------------------------------------------------------
-static bool isGeneratorExpression(const std::string &lib)
-{
- const std::string::size_type openpos = lib.find("$<");
- return (openpos != std::string::npos)
- && (lib.find(">", openpos) != std::string::npos);
-}
-
-//----------------------------------------------------------------------------
void cmTarget::AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib,
LinkLibraryType llt)
@@ -2300,7 +2306,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
llt).c_str());
}
- if (isGeneratorExpression(lib))
+ if (cmGeneratorExpression::Find(lib) != std::string::npos)
{
return;
}
@@ -2708,6 +2714,13 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
//----------------------------------------------------------------------------
void cmTarget::AppendBuildInterfaceIncludes()
{
+ if(this->GetType() != cmTarget::SHARED_LIBRARY &&
+ this->GetType() != cmTarget::STATIC_LIBRARY &&
+ this->GetType() != cmTarget::MODULE_LIBRARY &&
+ !this->IsExecutableWithExports())
+ {
+ return;
+ }
if (this->BuildInterfaceIncludesAppended)
{
return;
@@ -2754,6 +2767,7 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
this->GetName(),
"INCLUDE_DIRECTORIES", 0, 0);
+ this->AppendBuildInterfaceIncludes();
std::vector<std::string> debugProperties;
const char *debugProp =
@@ -2795,7 +2809,8 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
this,
&dagChecker),
entryIncludes);
- if (!(*it)->ge->GetHadContextSensitiveCondition())
+ if (this->Makefile->IsGeneratingBuildSystem()
+ && !(*it)->ge->GetHadContextSensitiveCondition())
{
cacheIncludes = true;
}
@@ -4522,18 +4537,6 @@ const char* cmTarget::GetExportMacro()
}
//----------------------------------------------------------------------------
-void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p,
- std::set<std::string> &targets)
-{
- const std::map<cmStdString, std::set<std::string> >::const_iterator findIt
- = this->LinkDependentProperties.find(p);
- if (findIt != this->LinkDependentProperties.end())
- {
- targets = findIt->second;
- }
-}
-
-//----------------------------------------------------------------------------
bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p)
{
return this->LinkImplicitNullProperties.find(p)
@@ -4541,24 +4544,6 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p)
}
//----------------------------------------------------------------------------
-void cmTarget::AddLinkDependentTargetsForProperties(
- const std::map<cmStdString, cmStdString> &map)
-{
- for (std::map<cmStdString, cmStdString>::const_iterator it = map.begin();
- it != map.end(); ++it)
- {
- std::vector<std::string> targets;
- cmSystemTools::ExpandListArgument(it->second.c_str(), targets);
- this->LinkDependentProperties[it->first].insert(targets.begin(),
- targets.end());
- if (!this->GetProperty(it->first.c_str()))
- {
- this->LinkImplicitNullProperties.insert(it->first);
- }
- }
-}
-
-//----------------------------------------------------------------------------
template<typename PropertyType>
PropertyType getTypedProperty(cmTarget *tgt, const char *prop,
PropertyType *);
@@ -4613,9 +4598,6 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
const bool explicitlySet = tgt->GetProperties()
.find(p.c_str())
!= tgt->GetProperties().end();
- std::set<std::string> dependentTargets;
- tgt->GetLinkDependentTargetsForProperty(p,
- dependentTargets);
const bool impliedByUse =
tgt->IsNullImpliedByLinkLibraries(p);
assert((impliedByUse ^ explicitlySet)
@@ -4799,7 +4781,12 @@ bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
const char *config)
{
- return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
+ if (this->TargetTypeValue == OBJECT_LIBRARY)
+ {
+ return false;
+ }
+ return (p == "POSITION_INDEPENDENT_CODE") ||
+ isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
config);
}
@@ -4807,6 +4794,10 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
const char *config)
{
+ if (this->TargetTypeValue == OBJECT_LIBRARY)
+ {
+ return false;
+ }
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
config);
}
@@ -5624,7 +5615,8 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
{
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
- std::set<cmStdString> emitted;
+ std::set<cmStdString> emittedBools;
+ std::set<cmStdString> emittedStrings;
for(cmComputeLinkInformation::ItemVector::const_iterator li =
deps.begin();
@@ -5637,19 +5629,36 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
checkPropertyConsistency<bool>(this, li->Target,
"COMPATIBLE_INTERFACE_BOOL",
- emitted, config, 0);
+ emittedBools, config, 0);
if (cmSystemTools::GetErrorOccuredFlag())
{
return;
}
checkPropertyConsistency<const char *>(this, li->Target,
"COMPATIBLE_INTERFACE_STRING",
- emitted, config, 0);
+ emittedStrings, config, 0);
if (cmSystemTools::GetErrorOccuredFlag())
{
return;
}
}
+
+ for(std::set<cmStdString>::const_iterator li = emittedBools.begin();
+ li != emittedBools.end(); ++li)
+ {
+ const std::set<cmStdString>::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/Source/cmTarget.h b/Source/cmTarget.h
index 7577a59..fb1496f 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -498,17 +498,12 @@ public:
void AppendBuildInterfaceIncludes();
- 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);
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);
@@ -627,8 +622,6 @@ private:
bool IsApple;
bool IsImportedTarget;
bool DebugIncludesDone;
- mutable std::map<cmStdString, std::set<std::string> >
- LinkDependentProperties;
mutable std::set<std::string> LinkImplicitNullProperties;
bool BuildInterfaceIncludesAppended;
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index eaacfa9..808806a 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -41,14 +41,6 @@ void cmTargetIncludeDirectoriesCommand
}
//----------------------------------------------------------------------------
-static bool isGeneratorExpression(const std::string &lib)
-{
- const std::string::size_type openpos = lib.find("$<");
- return (openpos != std::string::npos)
- && (lib.find(">", openpos) != std::string::npos);
-}
-
-//----------------------------------------------------------------------------
std::string cmTargetIncludeDirectoriesCommand
::Join(const std::vector<std::string> &content)
{
@@ -59,7 +51,7 @@ std::string cmTargetIncludeDirectoriesCommand
it != content.end(); ++it)
{
if (cmSystemTools::FileIsFullPath(it->c_str())
- || isGeneratorExpression(*it))
+ || cmGeneratorExpression::Find(*it) != std::string::npos)
{
dirs += sep + *it;
}
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index cb913f5..9dd0e5b 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -11,6 +11,8 @@
============================================================================*/
#include "cmTargetLinkLibrariesCommand.h"
+#include "cmGeneratorExpression.h"
+
const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] =
{
"general",
@@ -265,23 +267,14 @@ static std::string compileProperty(cmTarget *tgt, const std::string &lib,
}
//----------------------------------------------------------------------------
-static bool isGeneratorExpression(const std::string &lib)
-{
- const std::string::size_type openpos = lib.find("$<");
- return (openpos != std::string::npos)
- && (lib.find(">", openpos) != std::string::npos);
-}
-
-//----------------------------------------------------------------------------
void
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
cmTarget::LinkLibraryType llt)
{
- const bool isGenex = isGeneratorExpression(lib);
+ const bool isGenex = cmGeneratorExpression::Find(lib) != std::string::npos;
- cmsys::RegularExpression targetNameValidator;
- targetNameValidator.compile("^[A-Za-z0-9_.:-]+$");
- const bool potentialTargetName = targetNameValidator.find(lib);
+ const bool potentialTargetName
+ = cmGeneratorExpression::IsValidTargetName(lib);
if (potentialTargetName || isGenex)
{
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 18a1d2a..771097c 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -38,6 +38,15 @@ bool cmTargetPropCommandBase
this->HandleMissingTarget(args[0]);
return false;
}
+ if ((this->Target->GetType() != cmTarget::SHARED_LIBRARY)
+ && (this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ && (this->Target->GetType() != cmTarget::OBJECT_LIBRARY)
+ && (this->Target->GetType() != cmTarget::MODULE_LIBRARY)
+ && (this->Target->GetType() != cmTarget::EXECUTABLE))
+ {
+ this->SetError("called with non-compilable target type");
+ return false;
+ }
unsigned int argIndex = 1;
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index cd0fe11..19ee59f 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -103,4 +103,7 @@ target_compile_definitions(depG INTERFACE
)
add_executable(targetC targetC.cpp)
-target_link_libraries(targetC depG)
+# Creates a generator expression for include directories like
+# $<$<TARGET_DEFINED:$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:depG>>:\
+# $<TARGET_PROPERTY:$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:depG>,INTERFACE_INCLUDE_DIRECTORIES>>
+target_link_libraries(targetC $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:depG>)
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
index 329510b..cd0a37d 100644
--- a/Tests/CompatibleInterface/CMakeLists.txt
+++ b/Tests/CompatibleInterface/CMakeLists.txt
@@ -67,3 +67,18 @@ target_compile_definitions(CompatibleInterface
PRIVATE
$<$<BOOL:$<TARGET_PROPERTY:Iface2_PROP>>:SOME_DEFINE>
)
+
+# The COMPATIBLE_INTERFACE_* properties are only read from dependencies
+# in the interface. Populating it on the CompatibleInterface target does
+# not have any affect on the interpretation of the INTERFACE variants
+# in dependencies.
+set_property(TARGET iface1 PROPERTY
+ INTERFACE_NON_RELEVANT_PROP ON
+)
+set_property(TARGET iface2 PROPERTY
+ INTERFACE_NON_RELEVANT_PROP ON
+)
+set_property(TARGET CompatibleInterface APPEND PROPERTY
+ COMPATIBLE_INTERFACE_BOOL
+ NON_RELEVANT_PROP
+)
diff --git a/Tests/ObjectLibrary/A/CMakeLists.txt b/Tests/ObjectLibrary/A/CMakeLists.txt
index 36c86e7..55778ea 100644
--- a/Tests/ObjectLibrary/A/CMakeLists.txt
+++ b/Tests/ObjectLibrary/A/CMakeLists.txt
@@ -13,6 +13,6 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/a1.c.in
${CMAKE_CURRENT_BINARY_DIR}/a1.c
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_library(A OBJECT a1.c a2.c)
+target_include_directories(A PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/Tests/ObjectLibrary/B/CMakeLists.txt b/Tests/ObjectLibrary/B/CMakeLists.txt
index 32d8ceb..a567f96 100644
--- a/Tests/ObjectLibrary/B/CMakeLists.txt
+++ b/Tests/ObjectLibrary/B/CMakeLists.txt
@@ -10,7 +10,11 @@ if(CMAKE_SHARED_LIBRARY_C_FLAGS AND NOT WATCOM)
set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
endif()
-add_definitions(-DB_DEF)
add_library(B OBJECT b1.c b2.c)
+target_include_directories(B PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(B PUBLIC B_DEF)
+
add_library(Bexport OBJECT b1${vs6}.c b2${vs6}.c)
set_property(TARGET Bexport PROPERTY COMPILE_DEFINITIONS Bexport)
+target_include_directories(Bexport PRIVATE $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(Bexport PRIVATE $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
diff --git a/Tests/ObjectLibrary/B/b.h b/Tests/ObjectLibrary/B/b.h
index 11b22f4..3489c71 100644
--- a/Tests/ObjectLibrary/B/b.h
+++ b/Tests/ObjectLibrary/B/b.h
@@ -4,8 +4,15 @@
#ifndef B_DEF
# error "B_DEF not defined"
#endif
+
#if defined(_WIN32) && defined(Bexport)
# define EXPORT_B __declspec(dllexport)
#else
# define EXPORT_B
#endif
+
+#if defined(_WIN32) && defined(SHARED_B)
+# define IMPORT_B __declspec(dllimport)
+#else
+# define IMPORT_B
+#endif
diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt
index 8723415..13a07b4 100644
--- a/Tests/ObjectLibrary/CMakeLists.txt
+++ b/Tests/ObjectLibrary/CMakeLists.txt
@@ -26,6 +26,9 @@ endif()
# Test static library without its own sources.
add_library(ABstatic STATIC ${dummy} $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+target_include_directories(ABstatic PUBLIC $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(ABstatic PUBLIC $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
+
add_executable(UseABstatic mainAB.c)
target_link_libraries(UseABstatic ABstatic)
@@ -41,12 +44,17 @@ endif()
# Test shared library without its own sources.
add_library(ABshared SHARED ${dummy} ${ABshared_SRCS})
+target_include_directories(ABshared PUBLIC $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(ABshared PUBLIC $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
+
add_executable(UseABshared mainAB.c)
set_property(TARGET UseABshared PROPERTY COMPILE_DEFINITIONS SHARED_B ${NO_A})
target_link_libraries(UseABshared ABshared)
# Test executable without its own sources.
add_library(ABmain OBJECT mainAB.c)
+target_include_directories(ABmain PUBLIC $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(ABmain PUBLIC $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
add_executable(UseABinternal ${dummy}
$<TARGET_OBJECTS:ABmain> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>
)
diff --git a/Tests/ObjectLibrary/mainAB.c b/Tests/ObjectLibrary/mainAB.c
index 556898b..38db205 100644
--- a/Tests/ObjectLibrary/mainAB.c
+++ b/Tests/ObjectLibrary/mainAB.c
@@ -1,8 +1,6 @@
-#if defined(_WIN32) && defined(SHARED_B)
-# define IMPORT_B __declspec(dllimport)
-#else
-# define IMPORT_B
-#endif
+
+#include "b.h"
+
extern IMPORT_B int b1(void);
extern IMPORT_B int b2(void);
#ifndef NO_A
diff --git a/Tests/QtAutomoc/Adir/CMakeLists.txt b/Tests/QtAutomoc/Adir/CMakeLists.txt
new file mode 100644
index 0000000..abd328e
--- /dev/null
+++ b/Tests/QtAutomoc/Adir/CMakeLists.txt
@@ -0,0 +1,8 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_BUILD_INTERFACE_INCLUDES ON)
+
+add_library(libA SHARED libA.cpp)
+target_link_libraries(libA LINK_PUBLIC Qt4::QtCore)
+generate_export_header(libA)
diff --git a/Tests/QtAutomoc/Adir/libA.cpp b/Tests/QtAutomoc/Adir/libA.cpp
new file mode 100644
index 0000000..3968c44
--- /dev/null
+++ b/Tests/QtAutomoc/Adir/libA.cpp
@@ -0,0 +1,13 @@
+
+#include "libA.h"
+
+LibA::LibA(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+int LibA::foo()
+{
+ return 0;
+}
diff --git a/Tests/QtAutomoc/Adir/libA.h b/Tests/QtAutomoc/Adir/libA.h
new file mode 100644
index 0000000..03ad1e0
--- /dev/null
+++ b/Tests/QtAutomoc/Adir/libA.h
@@ -0,0 +1,18 @@
+
+#ifndef LIBA_H
+#define LIBA_H
+
+#include "liba_export.h"
+
+#include <QObject>
+
+class LIBA_EXPORT LibA : public QObject
+{
+ Q_OBJECT
+public:
+ explicit LibA(QObject *parent = 0);
+
+ int foo();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/Bdir/CMakeLists.txt b/Tests/QtAutomoc/Bdir/CMakeLists.txt
new file mode 100644
index 0000000..5497105
--- /dev/null
+++ b/Tests/QtAutomoc/Bdir/CMakeLists.txt
@@ -0,0 +1,10 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_BUILD_INTERFACE_INCLUDES ON)
+
+add_library(libB SHARED libB.cpp)
+generate_export_header(libB)
+
+# set_property(TARGET libB APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
+target_link_libraries(libB LINK_PUBLIC libA)
diff --git a/Tests/QtAutomoc/Bdir/libB.cpp b/Tests/QtAutomoc/Bdir/libB.cpp
new file mode 100644
index 0000000..72f2cfa
--- /dev/null
+++ b/Tests/QtAutomoc/Bdir/libB.cpp
@@ -0,0 +1,13 @@
+
+#include "libB.h"
+
+LibB::LibB(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+int LibB::foo()
+{
+ return a.foo();
+}
diff --git a/Tests/QtAutomoc/Bdir/libB.h b/Tests/QtAutomoc/Bdir/libB.h
new file mode 100644
index 0000000..510c17f
--- /dev/null
+++ b/Tests/QtAutomoc/Bdir/libB.h
@@ -0,0 +1,21 @@
+
+#ifndef LIBB_H
+#define LIBB_H
+
+#include "libb_export.h"
+
+#include <QObject>
+#include "libA.h"
+
+class LIBB_EXPORT LibB : public QObject
+{
+ Q_OBJECT
+public:
+ explicit LibB(QObject *parent = 0);
+
+ int foo();
+private:
+ LibA a;
+};
+
+#endif
diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt
index 855fcf0..530818e 100644
--- a/Tests/QtAutomoc/CMakeLists.txt
+++ b/Tests/QtAutomoc/CMakeLists.txt
@@ -23,4 +23,18 @@ add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
set_target_properties(foo codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE)
-target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} )
+include(GenerateExportHeader)
+# The order is relevant here. B depends on A, and B headers depend on A
+# headers both subdirectories use CMAKE_BUILD_INTERFACE_INCLUDES and we
+# test that CMAKE_AUTOMOC successfully reads the include directories
+# for the build interface from those targets. There has previously been
+# a bug where caching of the include directories happened before
+# extracting the includes to pass to moc.
+add_subdirectory(Bdir)
+add_subdirectory(Adir)
+add_library(libC SHARED libC.cpp)
+set_target_properties(libC PROPERTIES AUTOMOC TRUE)
+generate_export_header(libC)
+target_link_libraries(libC LINK_PUBLIC libB)
+
+target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} libC)
diff --git a/Tests/QtAutomoc/libC.cpp b/Tests/QtAutomoc/libC.cpp
new file mode 100644
index 0000000..8d61cb1
--- /dev/null
+++ b/Tests/QtAutomoc/libC.cpp
@@ -0,0 +1,13 @@
+
+#include "libC.h"
+
+LibC::LibC(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+int LibC::foo()
+{
+ return b.foo();
+}
diff --git a/Tests/QtAutomoc/libC.h b/Tests/QtAutomoc/libC.h
new file mode 100644
index 0000000..4fb4a2c
--- /dev/null
+++ b/Tests/QtAutomoc/libC.h
@@ -0,0 +1,22 @@
+
+#ifndef LIBC_H
+#define LIBC_H
+
+#include "libc_export.h"
+
+#include <QObject>
+#include "libB.h"
+
+class LIBC_EXPORT LibC : public QObject
+{
+ Q_OBJECT
+public:
+ explicit LibC(QObject *parent = 0);
+
+
+ int foo();
+private:
+ LibB b;
+};
+
+#endif
diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutomoc/main.cpp
index 738f677..d952171 100644
--- a/Tests/QtAutomoc/main.cpp
+++ b/Tests/QtAutomoc/main.cpp
@@ -48,6 +48,7 @@
#include "abc.h"
#include "xyz.h"
#include "yaf.h"
+#include "libC.h"
int main(int argv, char **args)
{
@@ -78,5 +79,8 @@ int main(int argv, char **args)
Yaf yaf;
yaf.doYaf();
+ LibC lc;
+ lc.foo();
+
return app.exec();
}
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 0000000..d00491f
--- /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 0000000..5a8f99d
--- /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 0000000..711368a
--- /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 922ad7f..9768151 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)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-stderr.txt
new file mode 100644
index 0000000..fb06554
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at BadLinked-UtilityTarget.cmake:7 \(set_property\):
+ Error evaluating generator expression:
+
+ \$<LINKED:check>
+
+ Target "check" is not an executable or library.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:8 \(include\)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget.cmake
new file mode 100644
index 0000000..d114c8f
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget.cmake
@@ -0,0 +1,7 @@
+
+add_custom_target(check ALL
+ COMMAND ${CMAKE_COMMAND} -E echo check
+)
+
+add_library(foo STATIC empty.cpp)
+set_property(TARGET foo PROPERTY INCLUDE_DIRECTORIES $<LINKED:check>)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
index ea48f61..84039c4 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
@@ -16,3 +16,4 @@ run_cmake(BadInvalidName6)
run_cmake(BadInvalidName7)
run_cmake(BadInvalidName8)
run_cmake(BadLinked)
+run_cmake(BadLinked-UtilityTarget)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp b/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp
new file mode 100644
index 0000000..8b1a393
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp
@@ -0,0 +1 @@
+// empty
diff --git a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
index 736fe69..c17e0ae 100644
--- a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
+++ b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
@@ -23,13 +23,21 @@ CMake Debug Log at DebugIncludes.cmake:18 \(include_directories\):
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
-CMake Debug Log at DebugIncludes.cmake:25 \(set_property\):
+CMake Debug Log at DebugIncludes.cmake:26 \(target_link_libraries\):
Used includes for target lll:
\* .*/Tests/RunCMake/include_directories/five
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at DebugIncludes.cmake:29 \(set_property\):
+ Used includes for target lll:
+
\* .*/Tests/RunCMake/include_directories/six
+ \* .*/Tests/RunCMake/include_directories/seven
Call Stack \(most recent call first\):
- DebugIncludes.cmake:35 \(some_macro\)
- DebugIncludes.cmake:38 \(some_function\)
+ DebugIncludes.cmake:40 \(some_macro\)
+ DebugIncludes.cmake:43 \(some_function\)
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include_directories/DebugIncludes.cmake b/Tests/RunCMake/include_directories/DebugIncludes.cmake
index 51daf74..794a852 100644
--- a/Tests/RunCMake/include_directories/DebugIncludes.cmake
+++ b/Tests/RunCMake/include_directories/DebugIncludes.cmake
@@ -21,6 +21,10 @@ include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/four"
)
+add_library(foo "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp")
+target_include_directories(foo INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/five")
+target_link_libraries(lll foo)
+
macro(some_macro)
set_property(TARGET lll APPEND PROPERTY
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/one"
@@ -28,6 +32,7 @@ macro(some_macro)
"${CMAKE_CURRENT_SOURCE_DIR}/four"
"${CMAKE_CURRENT_SOURCE_DIR}/five"
"${CMAKE_CURRENT_SOURCE_DIR}/six"
+ "${CMAKE_CURRENT_SOURCE_DIR}/seven"
)
endmacro()
diff --git a/Tests/RunCMake/include_directories/RunCMakeTest.cmake b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
index de37252..ddf268c 100644
--- a/Tests/RunCMake/include_directories/RunCMakeTest.cmake
+++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
@@ -2,3 +2,4 @@ include(RunCMake)
run_cmake(NotFoundContent)
run_cmake(DebugIncludes)
+run_cmake(TID-bad-target)
diff --git a/Tests/RunCMake/include_directories/TID-bad-target-result.txt b/Tests/RunCMake/include_directories/TID-bad-target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/include_directories/TID-bad-target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt b/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt
new file mode 100644
index 0000000..481e358
--- /dev/null
+++ b/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at TID-bad-target.cmake:6 \(target_include_directories\):
+ target_include_directories called with non-compilable target type
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include_directories/TID-bad-target.cmake b/Tests/RunCMake/include_directories/TID-bad-target.cmake
new file mode 100644
index 0000000..32201c1
--- /dev/null
+++ b/Tests/RunCMake/include_directories/TID-bad-target.cmake
@@ -0,0 +1,6 @@
+
+add_custom_target(check ALL
+ COMMAND ${CMAKE_COMMAND} -E echo check
+)
+
+target_include_directories(check PRIVATE somedir)