diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 35420b48b..5baee01cb 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 $>) set(_isNotExcluded $>>) set(_isPolicyNEW $) - set_property(TARGET Qt4::QtCore APPEND PROPERTY - IMPORTED_LINK_INTERFACE_LIBRARIES - $<$: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} + $<$:Qt4::qtmain> + ) + endforeach() + unset(_configs) unset(_isExe) unset(_isWin32) unset(_isNotExcluded) diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 9f7c0c197..1826f4229 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 7e4c3dfe5..fbed95a8b 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -314,14 +314,6 @@ cmExportFileGenerator::AddTargetNamespace(std::string &input, return true; } -//---------------------------------------------------------------------------- -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( @@ -344,7 +336,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( for(std::vector::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 7a704311e..20dd57ad1 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 7add1bf39..5d162fe03 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::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 700fe033b..489b052e9 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -62,6 +62,10 @@ public: static void Split(const std::string &input, std::vector &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 const& GetTargets() const { return this->Targets; } - std::map const& GetSeenTargetProperties() const + std::set const& GetSeenTargetProperties() const { return this->SeenTargetProperties; } ~cmCompiledGeneratorExpression(); @@ -120,7 +124,7 @@ private: bool NeedsParsing; mutable std::set Targets; - mutable std::map SeenTargetProperties; + mutable std::set SeenTargetProperties; mutable std::string Output; mutable bool HadContextSensitiveCondition; }; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index b9069ef60..0ac1a483d 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 5d9471883..98e0ada67 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -333,10 +333,6 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode "$ 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 ecf6b413a..dc39fdc8d 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 &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 b2ff0c48f..84cf6caee 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 &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 d629e7135..f6ab0d051 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 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 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::const_iterator di = defines.begin(); + for(std::set::const_iterator di = defines.begin(); di != defines.end(); ++di) { cmakefileStream diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index dbd0c36ec..299e5646f 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 &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::const_iterator + it = this->SystemIncludeDirectories.begin(); + it != this->SystemIncludeDirectories.end(); ++it) + { + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + + std::vector 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 a2783f296..c0020bf6b 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 &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 ca0e24b53..bf918d52e 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 seenProps = cge->GetSeenTargetProperties(); + for (std::set::const_iterator it = seenProps.begin(); + it != seenProps.end(); ++it) + { + if (!this->GetProperty(it->c_str())) + { + this->LinkImplicitNullProperties.insert(*it); + } + } } } @@ -2269,14 +2283,6 @@ static std::string targetNameGenex(const char *lib) return std::string("$"; } -//---------------------------------------------------------------------------- -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, @@ -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 cmTarget::GetIncludeDirectories(const char *config) this->GetName(), "INCLUDE_DIRECTORIES", 0, 0); + this->AppendBuildInterfaceIncludes(); std::vector debugProperties; const char *debugProp = @@ -2795,7 +2809,8 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) this, &dagChecker), entryIncludes); - if (!(*it)->ge->GetHadContextSensitiveCondition()) + if (this->Makefile->IsGeneratingBuildSystem() + && !(*it)->ge->GetHadContextSensitiveCondition()) { cacheIncludes = true; } @@ -4521,18 +4536,6 @@ const char* cmTarget::GetExportMacro() } } -//---------------------------------------------------------------------------- -void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p, - std::set &targets) -{ - const std::map >::const_iterator findIt - = this->LinkDependentProperties.find(p); - if (findIt != this->LinkDependentProperties.end()) - { - targets = findIt->second; - } -} - //---------------------------------------------------------------------------- bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) { @@ -4540,24 +4543,6 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) != this->LinkImplicitNullProperties.end(); } -//---------------------------------------------------------------------------- -void cmTarget::AddLinkDependentTargetsForProperties( - const std::map &map) -{ - for (std::map::const_iterator it = map.begin(); - it != map.end(); ++it) - { - std::vector 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 PropertyType getTypedProperty(cmTarget *tgt, const char *prop, @@ -4613,9 +4598,6 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, const bool explicitlySet = tgt->GetProperties() .find(p.c_str()) != tgt->GetProperties().end(); - std::set 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 emitted; + std::set emittedBools; + std::set emittedStrings; for(cmComputeLinkInformation::ItemVector::const_iterator li = deps.begin(); @@ -5637,19 +5629,36 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, checkPropertyConsistency(this, li->Target, "COMPATIBLE_INTERFACE_BOOL", - emitted, config, 0); + emittedBools, config, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } checkPropertyConsistency(this, li->Target, "COMPATIBLE_INTERFACE_STRING", - emitted, config, 0); + emittedStrings, config, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } } + + for(std::set::const_iterator li = emittedBools.begin(); + li != emittedBools.end(); ++li) + { + const std::set::const_iterator si = emittedStrings.find(*li); + if (si != emittedStrings.end()) + { + cmOStringStream e; + e << "Property \"" << *li << "\" appears in both the " + "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING " + "property in the dependencies of target \"" << this->GetName() << + "\". This is not allowed. A property may only require compatibility " + "in a boolean interpretation or a string interpretation, but not both."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + break; + } + } } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 7577a5941..fb1496fa2 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -498,17 +498,12 @@ public: void AppendBuildInterfaceIncludes(); - void GetLinkDependentTargetsForProperty(const std::string &p, - std::set &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 &map); - bool GetLinkInterfaceDependentBoolProperty(const std::string &p, const char *config); @@ -627,8 +622,6 @@ private: bool IsApple; bool IsImportedTarget; bool DebugIncludesDone; - mutable std::map > - LinkDependentProperties; mutable std::set LinkImplicitNullProperties; bool BuildInterfaceIncludesAppended; diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index eaacfa9e7..808806a3a 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -40,14 +40,6 @@ void cmTargetIncludeDirectoriesCommand this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } -//---------------------------------------------------------------------------- -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 &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 cb913f57a..9dd0e5be2 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", @@ -264,24 +266,15 @@ static std::string compileProperty(cmTarget *tgt, const std::string &lib, return tgt->GetDebugGeneratorExpressions(value, llt); } -//---------------------------------------------------------------------------- -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 18a1d2a9f..771097ca2 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 cd0fe1129..19ee59f41 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 +# $<$,EXECUTABLE>:depG>>:\ +# $,EXECUTABLE>:depG>,INTERFACE_INCLUDE_DIRECTORIES>> +target_link_libraries(targetC $<$,EXECUTABLE>:depG>) diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt index 329510b05..cd0a37d20 100644 --- a/Tests/CompatibleInterface/CMakeLists.txt +++ b/Tests/CompatibleInterface/CMakeLists.txt @@ -67,3 +67,18 @@ target_compile_definitions(CompatibleInterface PRIVATE $<$>: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 36c86e7e9..55778eabf 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 32d8cebf6..a567f960b 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_compile_definitions(Bexport PRIVATE $) diff --git a/Tests/ObjectLibrary/B/b.h b/Tests/ObjectLibrary/B/b.h index 11b22f427..3489c7105 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 87234159f..13a07b44a 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_include_directories(ABstatic PUBLIC $) +target_compile_definitions(ABstatic PUBLIC $) + 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_compile_definitions(ABshared PUBLIC $) + 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_compile_definitions(ABmain PUBLIC $) add_executable(UseABinternal ${dummy} $ $ $ ) diff --git a/Tests/ObjectLibrary/mainAB.c b/Tests/ObjectLibrary/mainAB.c index 556898b83..38db20520 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 000000000..abd328e76 --- /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 000000000..3968c4415 --- /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 000000000..03ad1e006 --- /dev/null +++ b/Tests/QtAutomoc/Adir/libA.h @@ -0,0 +1,18 @@ + +#ifndef LIBA_H +#define LIBA_H + +#include "liba_export.h" + +#include + +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 000000000..549710571 --- /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 000000000..72f2cfae9 --- /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 000000000..510c17f8f --- /dev/null +++ b/Tests/QtAutomoc/Bdir/libB.h @@ -0,0 +1,21 @@ + +#ifndef LIBB_H +#define LIBB_H + +#include "libb_export.h" + +#include +#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 855fcf0f5..530818e9c 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 000000000..8d61cb1bf --- /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 000000000..4fb4a2cf4 --- /dev/null +++ b/Tests/QtAutomoc/libC.h @@ -0,0 +1,22 @@ + +#ifndef LIBC_H +#define LIBC_H + +#include "libc_export.h" + +#include +#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 738f67720..d952171b5 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 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt new file mode 100644 index 000000000..5a8f99df2 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt @@ -0,0 +1,5 @@ +CMake Error in CMakeLists.txt: + Property "SOMETHING" appears in both the COMPATIBLE_INTERFACE_BOOL and the + COMPATIBLE_INTERFACE_STRING property in the dependencies of target "user". + This is not allowed. A property may only require compatibility in a + boolean interpretation or a string interpretation, but not both. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake new file mode 100644 index 000000000..711368a80 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake @@ -0,0 +1,9 @@ + +add_library(foo UNKNOWN IMPORTED) +add_library(bar UNKNOWN IMPORTED) + +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMETHING) +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMETHING) + +add_executable(user main.cpp) +target_link_libraries(user foo bar) diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake index 922ad7fc7..976815111 100644 --- a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake @@ -8,3 +8,4 @@ run_cmake(InterfaceString-mismatch-depends) run_cmake(InterfaceString-mismatch-depend-self) run_cmake(InterfaceString-mismatched-use) run_cmake(InterfaceString-builtin-prop) +run_cmake(InterfaceString-Bool-Conflict) diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadLinked-UtilityTarget-result.txt new file mode 100644 index 000000000..d00491fd7 --- /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 000000000..fb065540b --- /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: + + \$ + + 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 000000000..d114c8fc6 --- /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 $) diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake index ea48f61a8..84039c437 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 000000000..8b1a39374 --- /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 736fe6967..c17e0ae02 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 - \* .*/Tests/RunCMake/include_directories/six Call Stack \(most recent call first\): - DebugIncludes.cmake:35 \(some_macro\) - DebugIncludes.cmake:38 \(some_function\) + 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: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 51daf7480..794a85253 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 de3725226..ddf268c1e 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 000000000..d00491fd7 --- /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 000000000..481e358b2 --- /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 000000000..32201c1fb --- /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)