Merge topic 'linked-usage-cleanup'

fde949d Don't add target-specific interface includes and defines to Qt 4 targets.
79ae968 Revert "Add a way to exclude INTERFACE properties from exported targets."
71bf96e Revert "find_package: Reword <package>_NO_INTERFACES documentation"
3df36b5 Revert "Add the $<LINKED:...> generator expression."
e1f9080 Don't populate INTERFACE includes and defines properties in tll.
567c8d1 Revert "Don't allow utility or global targets in the LINKED expression."
a1c4905 Use the link information as a source of compile definitions and includes.
5c9f5e3 Don't use LINKED where not needed.
5b88504 Rename the IncludeDirectoriesEntry to be more generic.
b030323 Fix determination of when we're evaluating compile definitions.
This commit is contained in:
Brad King 2013-02-15 13:11:04 -05:00 committed by CMake Topic Stage
commit 0e2ed9b097
35 changed files with 284 additions and 513 deletions

View File

@ -972,14 +972,6 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
${_PROPERTY}
"Qt4::Qt${_DEPEND}"
)
set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES
"$<TARGET_PROPERTY:Qt4::Qt${_DEPEND},INTERFACE_INCLUDE_DIRECTORIES>"
)
set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS
"$<TARGET_PROPERTY:Qt4::Qt${_DEPEND},INTERFACE_COMPILE_DEFINITIONS>"
)
endforeach()
endif()
endmacro()

View File

@ -51,14 +51,6 @@
"on the target tgt.\n" \
"Note that tgt is not added as a dependency of the target this " \
"expression is evaluated on.\n" \
" $<LINKED:item> = An empty string if item is not a " \
"target. If item is a target then the " \
"INTERFACE_INCLUDE_DIRECTORIES or INTERFACE_COMPILE_DEFINITIONS " \
"content is read from the target. " \
"This generator expression can only be used in evaluation of the " \
"INCLUDE_DIRECTORIES or COMPILE_DEFINITIONS property. Note that " \
"this expression is for internal use and may be changed or removed " \
"in the future.\n" \
" $<TARGET_POLICY:pol> = '1' if the policy was NEW when " \
"the 'head' target was created, else '0'. If the policy was not " \
"set, the warning message for the policy will be emitted. This " \

View File

@ -25,8 +25,6 @@
#include <cmsys/auto_ptr.hxx>
#include "assert.h"
//----------------------------------------------------------------------------
cmExportFileGenerator::cmExportFileGenerator()
{
@ -162,7 +160,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
preprocessRule);
if (!prepro.empty())
{
this->ResolveTargetsInGeneratorExpressions(prepro, target, propName,
this->ResolveTargetsInGeneratorExpressions(prepro, target,
missingTargets);
properties[outputName] = prepro;
}
@ -266,16 +264,15 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
{
if (!properties.empty())
{
os << "if(NOT ${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES)\n";
std::string targetName = this->Namespace;
targetName += target->GetName();
os << " set_target_properties(" << targetName << " PROPERTIES\n";
os << "set_target_properties(" << targetName << " PROPERTIES\n";
for(ImportPropertyMap::const_iterator pi = properties.begin();
pi != properties.end(); ++pi)
{
os << " " << pi->first << " \"" << pi->second << "\"\n";
os << " " << pi->first << " \"" << pi->second << "\"\n";
}
os << " )\nendif()\n\n";
os << ")\n\n";
}
}
@ -318,14 +315,13 @@ cmExportFileGenerator::AddTargetNamespace(std::string &input,
void
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string &input,
cmTarget* target, const char *propName,
cmTarget* target,
std::vector<std::string> &missingTargets,
FreeTargetsReplace replace)
{
if (replace == NoReplaceFreeTargets)
{
this->ResolveTargetsInGeneratorExpression(input, target, propName,
missingTargets);
this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
return;
}
std::vector<std::string> parts;
@ -344,7 +340,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
{
this->ResolveTargetsInGeneratorExpression(
*li,
target, propName,
target,
missingTargets);
}
input += sep + *li;
@ -356,7 +352,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
void
cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
std::string &input,
cmTarget* target, const char *propName,
cmTarget* target,
std::vector<std::string> &missingTargets)
{
std::string::size_type pos = 0;
@ -391,57 +387,6 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
}
std::string errorString;
pos = 0;
lastPos = pos;
while((pos = input.find("$<LINKED:", lastPos)) != input.npos)
{
std::string::size_type nameStartPos = pos + sizeof("$<LINKED:") - 1;
std::string::size_type endPos = input.find(">", nameStartPos);
if (endPos == input.npos)
{
errorString = "$<LINKED:...> expression incomplete";
break;
}
std::string targetName = input.substr(nameStartPos,
endPos - nameStartPos);
if(targetName.find("$<") != input.npos)
{
errorString = "$<LINKED:...> requires its parameter to be a "
"literal.";
break;
}
if (this->AddTargetNamespace(targetName, target, missingTargets))
{
assert(propName); // The link libraries strings will
// never contain $<LINKED>
std::string replacement = "$<TARGET_PROPERTY:"
+ targetName + "," + propName;
input.replace(pos, endPos - pos, replacement);
lastPos = pos + replacement.size() + 1;
}
else
{
if (pos != 0)
{
if (input[pos - 1] == ';')
{
--pos;
}
}
else if (input[endPos + 1] == ';')
{
++endPos;
}
input.replace(pos, endPos - pos + 1, "");
lastPos = pos;
}
}
if (!errorString.empty())
{
mf->IssueMessage(cmake::FATAL_ERROR, errorString);
return;
}
pos = 0;
lastPos = pos;
while((pos = input.find("$<TARGET_NAME:", lastPos)) != input.npos)
@ -537,7 +482,7 @@ cmExportFileGenerator
preprocessRule);
if (!prepro.empty())
{
this->ResolveTargetsInGeneratorExpressions(prepro, target, 0,
this->ResolveTargetsInGeneratorExpressions(prepro, target,
missingTargets,
ReplaceFreeTargets);
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;

View File

@ -119,7 +119,7 @@ protected:
};
void ResolveTargetsInGeneratorExpressions(std::string &input,
cmTarget* target, const char *propName,
cmTarget* target,
std::vector<std::string> &missingTargets,
FreeTargetsReplace replace = NoReplaceFreeTargets);
@ -150,7 +150,7 @@ private:
std::vector<std::string> &missingTargets);
void ResolveTargetsInGeneratorExpression(std::string &input,
cmTarget* target, const char *propName,
cmTarget* target,
std::vector<std::string> &missingTargets);
virtual void ReplaceInstallPrefix(std::string &input);

View File

@ -376,26 +376,6 @@ void cmFindPackageCommand::GenerateDocumentation()
"The package configuration file may set <package>_FOUND to false "
"to tell find_package that component requirements are not satisfied."
"\n"
"A package configuration file may include() a <package>Targets.cmake "
"file, created by install(EXPORT) in the upstream source, to import "
"targets into the downstream consumer. "
"When a new version of the upstream adds INTERFACE properties not "
"present in a previous version it can change behavior for existing "
"downstreams. "
"In order to remain source compatible the upstream package configuration "
"file may set <package>_NO_INTERFACES to disable INTERFACE properties. "
"For example, code of the form:\n"
" if(<package>_FIND_VERSION VERSION_LESS <new-version>\n"
" AND NOT <package>_INTERFACES)\n"
" set(<package>_NO_INTERFACES 1)\n"
" endif()\n"
" include(\"${CMAKE_CURRENT_LIST_DIR}/<package>Targets.cmake\")\n"
"tells <package>Targets.cmake not to provide the INTERFACE properties "
"unless the downstream requests at least <new-version> or sets "
"<package>_INTERFACES to explicitly request them. "
"This allows consumers to decide when to enable the new interfaces when "
"upgrading."
"\n"
"See the cmake_policy() command documentation for discussion of the "
"NO_POLICY_SCOPE option."
;

View File

@ -165,5 +165,6 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions()
{
const char *prop = this->Property.c_str();
return (strcmp(prop, "COMPILE_DEFINITIONS") == 0
|| strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 );
|| strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0
|| strncmp(prop, "COMPILE_DEFINITIONS_", 20) == 0);
}

View File

@ -451,15 +451,68 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
const char *prop = target->GetProperty(propertyName.c_str());
std::string linkedTargetsContent;
if (dagCheckerParent)
{
if (dagCheckerParent->EvaluatingLinkLibraries())
{
if(!prop)
{
return std::string();
}
}
else
{
assert(dagCheckerParent->EvaluatingIncludeDirectories()
|| dagCheckerParent->EvaluatingCompileDefinitions());
if (propertyName == "INTERFACE_INCLUDE_DIRECTORIES"
|| propertyName == "INTERFACE_COMPILE_DEFINITIONS")
{
const cmTarget::LinkInterface *iface = target->GetLinkInterface(
context->Config,
context->HeadTarget);
if(iface)
{
cmGeneratorExpression ge(context->Backtrace);
std::string sep;
std::string depString;
for (std::vector<std::string>::const_iterator
it = iface->Libraries.begin();
it != iface->Libraries.end(); ++it)
{
if (context->Makefile->FindTargetToUse(it->c_str()))
{
depString +=
sep + "$<TARGET_PROPERTY:" + *it + "," + propertyName + ">";
sep = ";";
}
}
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(depString);
linkedTargetsContent = cge->Evaluate(context->Makefile,
context->Config,
context->Quiet,
context->HeadTarget,
target,
&dagChecker);
if (cge->GetHadContextSensitiveCondition())
{
context->HadContextSensitiveCondition = true;
}
}
}
}
}
if (!prop)
{
if (target->IsImported())
{
return std::string();
}
if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
{
return std::string();
return linkedTargetsContent;
}
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
context->Config))
@ -480,7 +533,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return propContent ? propContent : "";
}
return std::string();
return linkedTargetsContent;
}
for (size_t i = 0;
@ -503,6 +556,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
context->HadContextSensitiveCondition = true;
}
if (!linkedTargetsContent.empty())
{
result += (result.empty() ? "" : ";") + linkedTargetsContent;
}
return result;
}
}
@ -655,106 +712,6 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
} installPrefixNode;
//----------------------------------------------------------------------------
static const struct LinkedNode : public cmGeneratorExpressionNode
{
LinkedNode() {}
virtual bool GeneratesContent() const { return true; }
virtual int NumExpectedParameters() const { return 1; }
virtual bool RequiresLiteralInput() const { return true; }
std::string Evaluate(const std::vector<std::string> &parameters,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content,
cmGeneratorExpressionDAGChecker *dagChecker) const
{
if (dagChecker->EvaluatingIncludeDirectories())
{
return this->GetInterfaceProperty(parameters.front(),
"INCLUDE_DIRECTORIES",
context, content, dagChecker);
}
if (dagChecker->EvaluatingCompileDefinitions())
{
return this->GetInterfaceProperty(parameters.front(),
"COMPILE_DEFINITIONS",
context, content, dagChecker);
}
reportError(context, content->GetOriginalExpression(),
"$<LINKED:...> may only be used in INCLUDE_DIRECTORIES and "
"COMPILE_DEFINITIONS properties.");
return std::string();
}
private:
std::string GetInterfaceProperty(const std::string &item,
const std::string &prop,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content,
cmGeneratorExpressionDAGChecker *dagCheckerParent) const
{
cmTarget *target = context->CurrentTarget
->GetMakefile()->FindTargetToUse(item.c_str());
if (!target)
{
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)
{
return std::string();
}
cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
target->GetName(),
propertyName,
content,
dagCheckerParent);
switch (dagChecker.check())
{
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.reportError(context, content->GetOriginalExpression());
return std::string();
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// 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();
case cmGeneratorExpressionDAGChecker::DAG:
break;
}
cmGeneratorExpression ge(context->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propContent);
std::string result = cge->Evaluate(context->Makefile,
context->Config,
context->Quiet,
context->HeadTarget,
target,
&dagChecker);
if (cge->GetHadContextSensitiveCondition())
{
context->HadContextSensitiveCondition = true;
}
return result;
}
} linkedNode;
//----------------------------------------------------------------------------
template<bool linker, bool soname>
struct TargetFilesystemArtifactResultCreator
@ -989,8 +946,6 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
return &targetDefinedNode;
else if (identifier == "INSTALL_PREFIX")
return &installPrefixNode;
else if (identifier == "LINKED")
return &linkedNode;
return 0;
}

View File

@ -76,4 +76,13 @@ struct cmListFile
std::vector<cmListFileFunction> Functions;
};
struct cmValueWithOrigin {
cmValueWithOrigin(const std::string &value,
const cmListFileBacktrace &bt)
: Value(value), Backtrace(bt)
{}
std::string Value;
cmListFileBacktrace Backtrace;
};
#endif

View File

@ -1487,7 +1487,7 @@ void cmMakefile::InitializeFromParent()
// Initialize definitions with the closure of the parent scope.
this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure();
const std::vector<IncludeDirectoriesEntry> parentIncludes =
const std::vector<cmValueWithOrigin> parentIncludes =
parent->GetIncludeDirectoriesEntries();
this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(),
parentIncludes.begin(),
@ -1636,13 +1636,13 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
sep = ";";
}
std::vector<IncludeDirectoriesEntry>::iterator position =
std::vector<cmValueWithOrigin>::iterator position =
before ? this->IncludeDirectoriesEntries.begin()
: this->IncludeDirectoriesEntries.end();
cmListFileBacktrace lfbt;
this->GetBacktrace(lfbt);
IncludeDirectoriesEntry entry(incString, lfbt);
cmValueWithOrigin entry(incString, lfbt);
this->IncludeDirectoriesEntries.insert(position, entry);
// Property on each target:
@ -3461,7 +3461,7 @@ void cmMakefile::SetProperty(const char* prop, const char* value)
cmListFileBacktrace lfbt;
this->GetBacktrace(lfbt);
this->IncludeDirectoriesEntries.push_back(
IncludeDirectoriesEntry(value, lfbt));
cmValueWithOrigin(value, lfbt));
return;
}
@ -3500,7 +3500,7 @@ void cmMakefile::AppendProperty(const char* prop, const char* value,
cmListFileBacktrace lfbt;
this->GetBacktrace(lfbt);
this->IncludeDirectoriesEntries.push_back(
IncludeDirectoriesEntry(value, lfbt));
cmValueWithOrigin(value, lfbt));
return;
}
if ( propname == "LINK_DIRECTORIES" )
@ -3617,7 +3617,7 @@ const char *cmMakefile::GetProperty(const char* prop,
else if (!strcmp("INCLUDE_DIRECTORIES",prop))
{
std::string sep;
for (std::vector<IncludeDirectoriesEntry>::const_iterator
for (std::vector<cmValueWithOrigin>::const_iterator
it = this->IncludeDirectoriesEntries.begin(),
end = this->IncludeDirectoriesEntries.end();
it != end; ++it)

View File

@ -22,7 +22,6 @@
#include "cmNewLineStyle.h"
#include "cmGeneratorTarget.h"
#include "cmake.h"
#include "cmMakefileIncludeDirectoriesEntry.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmSourceGroup.h"
@ -863,9 +862,7 @@ public:
/** Set whether or not to report a CMP0000 violation. */
void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
typedef cmMakefileIncludeDirectoriesEntry IncludeDirectoriesEntry;
std::vector<IncludeDirectoriesEntry> GetIncludeDirectoriesEntries() const
std::vector<cmValueWithOrigin> GetIncludeDirectoriesEntries() const
{
return this->IncludeDirectoriesEntries;
}
@ -921,7 +918,7 @@ protected:
std::vector<std::string> HeaderFileExtensions;
std::string DefineFlags;
std::vector<IncludeDirectoriesEntry> IncludeDirectoriesEntries;
std::vector<cmValueWithOrigin> IncludeDirectoriesEntries;
// Track the value of the computed DEFINITIONS property.
void AddDefineFlag(const char*, std::string&);

View File

@ -1,28 +0,0 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2012 Stephen Kelly <steveire@gmail.com>
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmMakefileIncludeDirectoriesEntry_h
#define cmMakefileIncludeDirectoriesEntry_h
#include <string>
#include "cmListFileCache.h"
struct cmMakefileIncludeDirectoriesEntry {
cmMakefileIncludeDirectoriesEntry(const std::string &value,
const cmListFileBacktrace &bt)
: Value(value), Backtrace(bt)
{}
std::string Value;
cmListFileBacktrace Backtrace;
};
#endif

View File

@ -137,6 +137,7 @@ public:
std::vector<std::string> CachedIncludes;
};
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries;
};
//----------------------------------------------------------------------------
@ -1496,10 +1497,10 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property:
const std::vector<cmMakefileIncludeDirectoriesEntry> parentIncludes =
const std::vector<cmValueWithOrigin> parentIncludes =
this->Makefile->GetIncludeDirectoriesEntries();
for (std::vector<cmMakefileIncludeDirectoriesEntry>::const_iterator it
for (std::vector<cmValueWithOrigin>::const_iterator it
= parentIncludes.begin(); it != parentIncludes.end(); ++it)
{
this->InsertInclude(*it);
@ -2743,7 +2744,13 @@ void cmTarget::AppendBuildInterfaceIncludes()
}
//----------------------------------------------------------------------------
void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
void cmTarget::AppendTllInclude(const cmValueWithOrigin &entry)
{
this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry);
}
//----------------------------------------------------------------------------
void cmTarget::InsertInclude(const cmValueWithOrigin &entry,
bool before)
{
cmGeneratorExpression ge(entry.Backtrace);
@ -2756,6 +2763,73 @@ void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(entry.Value)));
}
//----------------------------------------------------------------------------
static void processIncludeDirectories(cmTarget *tgt,
const std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries,
std::vector<std::string> &includes,
std::set<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker,
const char *config, bool debugIncludes)
{
cmMakefile *mf = tgt->GetMakefile();
for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
bool testIsOff = true;
bool cacheIncludes = false;
std::vector<std::string> entryIncludes = (*it)->CachedIncludes;
if(!entryIncludes.empty())
{
testIsOff = false;
}
else
{
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
config,
false,
tgt,
dagChecker),
entryIncludes);
if (mf->IsGeneratingBuildSystem()
&& !(*it)->ge->GetHadContextSensitiveCondition())
{
cacheIncludes = true;
}
}
std::string usedIncludes;
for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
{
cmSystemTools::ConvertToUnixSlashes(*li);
}
std::string inc = *li;
if(uniqueIncludes.insert(inc).second)
{
includes.push_back(inc);
if (debugIncludes)
{
usedIncludes += " * " + inc + "\n";
}
}
}
if (cacheIncludes)
{
(*it)->CachedIncludes = entryIncludes;
}
if (!usedIncludes.empty())
{
mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
std::string("Used includes for target ")
+ tgt->GetName() + ":\n"
+ usedIncludes, (*it)->ge->GetBacktrace());
}
}
}
//----------------------------------------------------------------------------
std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
{
@ -2788,63 +2862,50 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
this->DebugIncludesDone = true;
}
for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
it = this->Internal->IncludeDirectoriesEntries.begin(),
end = this->Internal->IncludeDirectoriesEntries.end();
processIncludeDirectories(this,
this->Internal->IncludeDirectoriesEntries,
includes,
uniqueIncludes,
&dagChecker,
config,
debugIncludes);
std::vector<cmTargetInternals::IncludeDirectoriesEntry*>
linkInterfaceIncludeDirectoriesEntries;
for (std::vector<cmValueWithOrigin>::const_iterator
it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(),
end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end();
it != end; ++it)
{
bool testIsOff = true;
bool cacheIncludes = false;
std::vector<std::string> entryIncludes = (*it)->CachedIncludes;
if(!entryIncludes.empty())
{
cmGeneratorExpression ge(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(it->Value);
std::string result = cge->Evaluate(this->Makefile, config,
false, this, 0, 0);
if (!this->Makefile->FindTargetToUse(result.c_str()))
{
testIsOff = false;
}
else
{
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
config,
false,
this,
&dagChecker),
entryIncludes);
if (this->Makefile->IsGeneratingBuildSystem()
&& !(*it)->ge->GetHadContextSensitiveCondition())
{
cacheIncludes = true;
}
}
std::string usedIncludes;
for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
{
cmSystemTools::ConvertToUnixSlashes(*li);
}
std::string inc = *li;
if(uniqueIncludes.insert(inc).second)
{
includes.push_back(inc);
if (debugIncludes)
{
usedIncludes += " * " + inc + "\n";
}
}
}
if (cacheIncludes)
{
(*it)->CachedIncludes = entryIncludes;
}
if (!usedIncludes.empty())
{
this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,
"Used includes for target " + this->Name + ":\n"
+ usedIncludes, (*it)->ge->GetBacktrace());
continue;
}
}
cmGeneratorExpression ge(it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
"$<TARGET_PROPERTY:" + it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>");
linkInterfaceIncludeDirectoriesEntries.push_back(
new cmTargetInternals::IncludeDirectoriesEntry(cge));
}
processIncludeDirectories(this,
linkInterfaceIncludeDirectoriesEntries,
includes,
uniqueIncludes,
&dagChecker,
config,
debugIncludes);
deleteAndClear(linkInterfaceIncludeDirectoriesEntries);
return includes;
}
@ -2858,23 +2919,57 @@ std::string cmTarget::GetCompileDefinitions(const char *config)
}
const char *prop = this->GetProperty(defPropName.c_str());
cmListFileBacktrace lfbt;
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(),
defPropName, 0, 0);
if (!prop)
std::string result;
if (prop)
{
return "";
cmGeneratorExpression ge(lfbt);
result = ge.Parse(prop)->Evaluate(this->Makefile,
config,
false,
this,
&dagChecker);
}
cmListFileBacktrace lfbt;
cmGeneratorExpression ge(lfbt);
std::vector<std::string> libs;
this->GetDirectLinkLibraries(config, libs, this);
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(),
defPropName, 0, 0);
return ge.Parse(prop)->Evaluate(this->Makefile,
config,
false,
this,
&dagChecker);
if (libs.empty())
{
return result;
}
std::string sep;
std::string depString;
for (std::vector<std::string>::const_iterator it = libs.begin();
it != libs.end(); ++it)
{
if (this->Makefile->FindTargetToUse(it->c_str()))
{
depString += sep + "$<TARGET_PROPERTY:"
+ *it + ",INTERFACE_COMPILE_DEFINITIONS>";
sep = ";";
}
}
cmGeneratorExpression ge2(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge2 = ge2.Parse(depString);
std::string depResult = cge2->Evaluate(this->Makefile,
config,
false,
this,
&dagChecker);
if (!depResult.empty())
{
result += (result.empty() ? "" : ";") + depResult;
}
return result;
}
//----------------------------------------------------------------------------

View File

@ -15,7 +15,7 @@
#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
#include "cmPolicies.h"
#include "cmMakefileIncludeDirectoriesEntry.h"
#include "cmListFileCache.h"
#include <cmsys/auto_ptr.hxx>
@ -493,8 +493,9 @@ public:
std::string GetFrameworkDirectory(const char* config = 0);
std::vector<std::string> GetIncludeDirectories(const char *config);
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
void InsertInclude(const cmValueWithOrigin &entry,
bool before = false);
void AppendTllInclude(const cmValueWithOrigin &entry);
void AppendBuildInterfaceIncludes();

View File

@ -11,8 +11,6 @@
============================================================================*/
#include "cmTargetCompileDefinitionsCommand.h"
#include "cmMakefileIncludeDirectoriesEntry.h"
bool cmTargetCompileDefinitionsCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{

View File

@ -11,8 +11,6 @@
============================================================================*/
#include "cmTargetIncludeDirectoriesCommand.h"
#include "cmMakefileIncludeDirectoriesEntry.h"
//----------------------------------------------------------------------------
bool cmTargetIncludeDirectoriesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@ -71,6 +69,6 @@ void cmTargetIncludeDirectoriesCommand
{
cmListFileBacktrace lfbt;
this->Makefile->GetBacktrace(lfbt);
cmMakefileIncludeDirectoriesEntry entry(this->Join(content), lfbt);
cmValueWithOrigin entry(this->Join(content), lfbt);
tgt->InsertInclude(entry, prepend);
}

View File

@ -251,46 +251,22 @@ cmTargetLinkLibrariesCommand
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
//----------------------------------------------------------------------------
static std::string compileProperty(cmTarget *tgt, const std::string &lib,
bool isGenex,
const std::string &property,
cmTarget::LinkLibraryType llt)
{
std::string value = !isGenex ? "$<LINKED:" + lib + ">"
: "$<$<TARGET_DEFINED:" + lib + ">:" +
"$<TARGET_PROPERTY:" + lib +
",INTERFACE_" + property + ">"
">";
return tgt->GetDebugGeneratorExpressions(value, llt);
}
//----------------------------------------------------------------------------
void
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
cmTarget::LinkLibraryType llt)
{
const bool isGenex = cmGeneratorExpression::Find(lib) != std::string::npos;
const bool potentialTargetName
= cmGeneratorExpression::IsValidTargetName(lib);
if (potentialTargetName || isGenex)
{
this->Target->AppendProperty("INCLUDE_DIRECTORIES",
compileProperty(this->Target, lib,
isGenex,
"INCLUDE_DIRECTORIES", llt).c_str());
this->Target->AppendProperty("COMPILE_DEFINITIONS",
compileProperty(this->Target, lib,
isGenex,
"COMPILE_DEFINITIONS", llt).c_str());
}
// Handle normal case first.
if(this->CurrentProcessingState != ProcessingLinkInterface)
{
{
cmListFileBacktrace lfbt;
this->Makefile->GetBacktrace(lfbt);
cmValueWithOrigin entry(this->Target->GetDebugGeneratorExpressions(lib,
llt),
lfbt);
this->Target->AppendTllInclude(entry);
}
this->Makefile
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
if (this->CurrentProcessingState != ProcessingPublicInterface)
@ -300,18 +276,6 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
}
}
if (potentialTargetName || isGenex)
{
this->Target->AppendProperty("INTERFACE_COMPILE_DEFINITIONS",
compileProperty(this->Target, lib,
isGenex,
"COMPILE_DEFINITIONS", llt).c_str());
this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
compileProperty(this->Target, lib,
isGenex,
"INCLUDE_DIRECTORIES", llt).c_str());
}
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> const& debugConfigs =
this->Makefile->GetCMakeInstance()->GetDebugConfigs();

View File

@ -16,15 +16,9 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
add_library(linked UNKNOWN IMPORTED)
set_property(TARGET linked PROPERTY
INTERFACE_COMPILE_DEFINITIONS "MY_LINKED_DEFINE")
target_compile_definitions(consumer
PRIVATE $<TARGET_PROPERTY:target_compile_definitions,INTERFACE_COMPILE_DEFINITIONS>
$<$<TARGET_DEFINED:notdefined>:SHOULD_NOT_BE_DEFINED>
$<$<TARGET_DEFINED:target_compile_definitions>:SHOULD_BE_DEFINED>
$<LINKED:linked>
-DDASH_D_DEFINE
)

View File

@ -23,8 +23,4 @@
#error Expected DASH_D_DEFINE
#endif
#ifndef MY_LINKED_DEFINE
#error Expected MY_LINKED_DEFINE
#endif
int main() { return 0; }

View File

@ -17,9 +17,6 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/poison/common.h" "#error Should not be i
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/cure")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cure/common.h" "#define CURE_DEFINE\n")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/linkedinclude")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/linkedinclude/linkedinclude.h" "#define LINKEDINCLUDE_DEFINE\n")
add_executable(target_include_directories
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
)
@ -45,13 +42,8 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
add_library(linked UNKNOWN IMPORTED)
set_property(TARGET linked PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/linkedinclude")
target_include_directories(consumer
PRIVATE
$<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES>
$<LINKED:linked>
relative_dir
)

View File

@ -3,7 +3,6 @@
#include "publicinclude.h"
#include "interfaceinclude.h"
#include "relative_dir.h"
#include "linkedinclude.h"
#ifdef PRIVATEINCLUDE_DEFINE
#error Unexpected PRIVATEINCLUDE_DEFINE
@ -25,8 +24,4 @@
#error Expected RELATIVE_DIR_DEFINE
#endif
#ifndef LINKEDINCLUDE_DEFINE
#error Expected LINKEDINCLUDE_DEFINE
#endif
int main() { return 0; }

View File

@ -17,8 +17,3 @@ add_executable(imp_testTransExe1 imp_testTransExe1.c)
target_link_libraries(imp_testTransExe1 imp_lib1)
add_executable(imp_testTransExe1b imp_testTransExe1.c)
target_link_libraries(imp_testTransExe1b imp_lib1b)
# Test package INTERFACE controls
add_subdirectory(package_old_old)
add_subdirectory(package_new_old)
add_subdirectory(package_new_new)

View File

@ -1,23 +0,0 @@
cmake_minimum_required(VERSION 2.8)
find_package(testLibRequired 2.5 REQUIRED)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
"
#include \"testSharedLibRequired.h\"
int main(int argc, char **argv)
{
TestSharedLibRequired req;
return req.foo();
}
"
)
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
if (NOT prop)
message(SEND_ERROR "Interface of Req::testSharedLibRequired should not be empty")
endif()
add_executable(new_new_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
target_link_libraries(new_new_test Req::testSharedLibRequired)

View File

@ -1,24 +0,0 @@
cmake_minimum_required(VERSION 2.8)
find_package(testLibRequired 2.5 REQUIRED)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
"
#include \"testSharedLibRequired.h\"
int main(int argc, char **argv)
{
TestSharedLibRequired req;
return req.foo();
}
"
)
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
if ("${prop}" STREQUAL "")
message(SEND_ERROR "Interface of Req::testSharedLibRequired should not be empty")
endif()
add_executable(new_old_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
target_link_libraries(new_old_test Req::testSharedLibRequired)
include_directories(${testLibRequired_INCLUDE_DIRS})

View File

@ -1,24 +0,0 @@
cmake_minimum_required(VERSION 2.8)
find_package(testLibRequired 2.1 REQUIRED)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
"
#include \"testSharedLibRequired.h\"
int main(int argc, char **argv)
{
TestSharedLibRequired req;
return req.foo();
}
"
)
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
if (prop)
message(SEND_ERROR "Interface of Req::testSharedLibRequired should be empty, but is ${prop}")
endif()
add_executable(old_old_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
target_link_libraries(old_old_test Req::testSharedLibRequired)
include_directories(${testLibRequired_INCLUDE_DIRS})

View File

@ -121,5 +121,5 @@ target_link_libraries(lib5 libbad libgood)
# get the libgood includes in before the libbad includes.
# We do that with this command:
target_include_directories(lib5
BEFORE PRIVATE $<LINKED:libgood>
BEFORE PRIVATE $<TARGET_PROPERTY:libgood,INTERFACE_INCLUDE_DIRECTORIES>
)

View File

@ -1,8 +0,0 @@
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\)

View File

@ -1,7 +0,0 @@
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>)

View File

@ -1,7 +0,0 @@
CMake Error:
Error evaluating generator expression:
\$<LINKED:something>
\$<LINKED:...> may only be used in INCLUDE_DIRECTORIES and
COMPILE_DEFINITIONS properties.$

View File

@ -1,7 +0,0 @@
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
"int main(int, char **) { return 0; }\n")
add_executable(TargetPropertyGeneratorExpressions
"${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
target_link_libraries(TargetPropertyGeneratorExpressions "$<LINKED:something>")

View File

@ -15,5 +15,3 @@ run_cmake(BadInvalidName5)
run_cmake(BadInvalidName6)
run_cmake(BadInvalidName7)
run_cmake(BadInvalidName8)
run_cmake(BadLinked)
run_cmake(BadLinked-UtilityTarget)

View File

@ -23,21 +23,22 @@ 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:26 \(target_link_libraries\):
CMake Debug Log at DebugIncludes.cmake:33 \(set_property\):
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:40 \(some_macro\)
DebugIncludes.cmake:43 \(some_function\)
DebugIncludes.cmake:44 \(some_macro\)
DebugIncludes.cmake:47 \(some_function\)
CMakeLists.txt:3 \(include\)
+
CMake Debug Log at DebugIncludes.cmake:30 \(target_link_libraries\):
Used includes for target lll:
\* .*/Tests/RunCMake/include_directories/eight
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -22,7 +22,11 @@ include_directories(
)
add_library(foo "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp")
target_include_directories(foo INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/five")
target_include_directories(foo
INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/seven"
"${CMAKE_CURRENT_SOURCE_DIR}/eight"
)
target_link_libraries(lll foo)
macro(some_macro)