cmGeneratorTarget: Move include directory processing from cmTarget.

This commit is contained in:
Stephen Kelly 2015-08-04 23:14:53 +02:00
parent 8bfb0c53da
commit e6ccbf6f30
5 changed files with 292 additions and 231 deletions

View File

@ -34,6 +34,18 @@
#define UNORDERED_SET std::set
#endif
class cmGeneratorTarget::TargetPropertyEntry {
static cmLinkImplItem NoLinkImplItem;
public:
TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
cmLinkImplItem const& item = NoLinkImplItem)
: ge(cge), LinkImplItem(item)
{}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
cmLinkImplItem const& LinkImplItem;
};
cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
//----------------------------------------------------------------------------
void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
cmGeneratorTarget const* target, cmake *cm)
@ -227,19 +239,43 @@ struct TagVisitor
}
};
void CreatePropertyGeneratorExpressions(
cmStringRange const& entries,
cmBacktraceRange const& backtraces,
std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
bool evaluateForBuildsystem = false)
{
std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
for (std::vector<std::string>::const_iterator it = entries.begin();
it != entries.end(); ++it, ++btIt)
{
cmGeneratorExpression ge(*btIt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it);
cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
items.push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
}
}
//----------------------------------------------------------------------------
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
: Target(t),
SourceFileFlagsConstructed(false),
PolicyWarnedCMP0022(false)
PolicyWarnedCMP0022(false),
DebugIncludesDone(false)
{
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = lg;
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
CreatePropertyGeneratorExpressions(
t->GetIncludeDirectoriesEntries(),
t->GetIncludeDirectoriesBacktraces(),
this->IncludeDirectoriesEntries);
}
cmGeneratorTarget::~cmGeneratorTarget()
{
cmDeleteAll(this->IncludeDirectoriesEntries);
cmDeleteAll(this->LinkInformation);
this->LinkInformation.clear();
}
@ -1964,13 +2000,248 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
}
return "";
}
//----------------------------------------------------------------------------
static void processIncludeDirectories(cmGeneratorTarget const* tgt,
const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
std::vector<std::string> &includes,
UNORDERED_SET<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugIncludes,
const std::string& language)
{
cmMakefile *mf = tgt->Target->GetMakefile();
for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
cmLinkImplItem const& item = (*it)->LinkImplItem;
std::string const& targetName = item;
bool const fromImported = item.Target && item.Target->IsImported();
bool const checkCMP0027 = item.FromGenex;
std::vector<std::string> entryIncludes;
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
config,
false,
tgt->Target,
dagChecker, language),
entryIncludes);
std::string usedIncludes;
for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
if (fromImported
&& !cmSystemTools::FileExists(li->c_str()))
{
std::ostringstream e;
cmake::MessageType messageType = cmake::FATAL_ERROR;
if (checkCMP0027)
{
switch(tgt->Target->GetPolicyStatusCMP0027())
{
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
case cmPolicies::OLD:
messageType = cmake::AUTHOR_WARNING;
break;
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
break;
}
}
e << "Imported target \"" << targetName << "\" includes "
"non-existent path\n \"" << *li << "\"\nin its "
"INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
"* The path was deleted, renamed, or moved to another "
"location.\n"
"* An install or uninstall procedure did not complete "
"successfully.\n"
"* The installation package was faulty and references files it "
"does not provide.\n";
tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
return;
}
if (!cmSystemTools::FileIsFullPath(li->c_str()))
{
std::ostringstream e;
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
if (!targetName.empty())
{
e << "Target \"" << targetName << "\" contains relative "
"path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
" \"" << *li << "\"";
}
else
{
switch(tgt->Target->GetPolicyStatusCMP0021())
{
case cmPolicies::WARN:
{
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
messageType = cmake::AUTHOR_WARNING;
}
break;
case cmPolicies::OLD:
noMessage = true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
}
e << "Found relative path while evaluating include directories of "
"\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n";
}
if (!noMessage)
{
tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
if (messageType == cmake::FATAL_ERROR)
{
return;
}
}
}
if (!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 (!usedIncludes.empty())
{
mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
std::string("Used includes for target ")
+ tgt->GetName() + ":\n"
+ usedIncludes, (*it)->ge->GetBacktrace());
}
}
}
//----------------------------------------------------------------------------
static void AddInterfaceEntries(
cmGeneratorTarget const* thisTarget, std::string const& config,
std::string const& prop,
std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
{
if(cmLinkImplementationLibraries const* impl =
thisTarget->Target->GetLinkImplementationLibraries(config))
{
for (std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin(), end = impl->Libraries.end();
it != end; ++it)
{
if(it->Target)
{
std::string genex =
"$<TARGET_PROPERTY:" + *it + "," + prop + ">";
cmGeneratorExpression ge(it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
cge->SetEvaluateForBuildsystem(true);
entries.push_back(
new cmGeneratorTarget::TargetPropertyEntry(cge, *it));
}
}
}
}
//----------------------------------------------------------------------------
std::vector<std::string>
cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
const std::string& lang) const
{
return this->Target->GetIncludeDirectories(config, lang);
std::vector<std::string> includes;
UNORDERED_SET<std::string> uniqueIncludes;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"INCLUDE_DIRECTORIES", 0, 0);
std::vector<std::string> debugProperties;
const char *debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp)
{
cmSystemTools::ExpandListArgument(debugProp, debugProperties);
}
bool debugIncludes = !this->DebugIncludesDone
&& std::find(debugProperties.begin(),
debugProperties.end(),
"INCLUDE_DIRECTORIES")
!= debugProperties.end();
if (this->Makefile->IsConfigured())
{
this->DebugIncludesDone = true;
}
processIncludeDirectories(this,
this->IncludeDirectoriesEntries,
includes,
uniqueIncludes,
&dagChecker,
config,
debugIncludes,
lang);
std::vector<cmGeneratorTarget::TargetPropertyEntry*>
linkInterfaceIncludeDirectoriesEntries;
AddInterfaceEntries(
this, config, "INTERFACE_INCLUDE_DIRECTORIES",
linkInterfaceIncludeDirectoriesEntries);
if(this->Makefile->IsOn("APPLE"))
{
cmLinkImplementationLibraries const* impl =
this->Target->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it)
{
std::string libDir = cmSystemTools::CollapseFullPath(*it);
static cmsys::RegularExpression
frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
if(!frameworkCheck.find(libDir))
{
continue;
}
libDir = frameworkCheck.match(1);
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(libDir.c_str());
linkInterfaceIncludeDirectoriesEntries
.push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
}
}
processIncludeDirectories(this,
linkInterfaceIncludeDirectoriesEntries,
includes,
uniqueIncludes,
&dagChecker,
config,
debugIncludes,
lang);
cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
return includes;
}
//----------------------------------------------------------------------------

View File

@ -332,6 +332,8 @@ public:
const std::string &report,
const std::string &compatibilityType) const;
class TargetPropertyEntry;
private:
friend class cmTargetTraceDependencies;
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@ -404,6 +406,8 @@ private:
GetImportLinkInterface(const std::string& config, cmTarget const* head,
bool usage_requirements_only) const;
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
void ExpandLinkItems(std::string const& prop, std::string const& value,
std::string const& config, cmTarget const* headTarget,
bool usage_requirements_only,
@ -416,6 +420,7 @@ private:
typedef std::map<OutputNameKey, std::string> OutputNameMapType;
mutable OutputNameMapType OutputNameMap;
mutable bool PolicyWarnedCMP0022;
mutable bool DebugIncludesDone;
public:
std::vector<cmTarget const*> const&

View File

@ -343,7 +343,7 @@ void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config,
const std::string &language)
{
std::vector<std::string> includes =
this->Target->GetIncludeDirectories(config, language);
this->GeneratorTarget->GetIncludeDirectories(config, language);
for (std::vector<std::string>::const_iterator includes_i = includes.begin();
includes_i != includes.end(); ++includes_i)
{

View File

@ -139,7 +139,6 @@ public:
};
std::vector<std::string> IncludeDirectoriesEntries;
std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
std::vector<TargetPropertyEntry*> IncludeDirectoriesItems;
std::vector<std::string> CompileOptionsEntries;
std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
std::vector<TargetPropertyEntry*> CompileOptionsItems;
@ -177,7 +176,6 @@ cmTarget::cmTarget()
this->IsApple = false;
this->IsImportedTarget = false;
this->BuildInterfaceIncludesAppended = false;
this->DebugIncludesDone = false;
this->DebugCompileOptionsDone = false;
this->DebugCompileFeaturesDone = false;
this->DebugCompileDefinitionsDone = false;
@ -425,11 +423,6 @@ void CreatePropertyGeneratorExpressions(
void cmTarget::Compute()
{
CreatePropertyGeneratorExpressions(
this->Internal->IncludeDirectoriesEntries,
this->Internal->IncludeDirectoriesBacktraces,
this->Internal->IncludeDirectoriesItems);
CreatePropertyGeneratorExpressions(
this->Internal->CompileOptionsEntries,
this->Internal->CompileOptionsBacktraces,
@ -1319,6 +1312,16 @@ cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs)
this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
}
cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
{
return cmMakeRange(this->Internal->IncludeDirectoriesEntries);
}
cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
{
return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
//----------------------------------------------------------------------------
void
@ -1915,222 +1918,6 @@ void cmTarget::InsertCompileDefinition(std::string const& entry,
this->Internal->CompileDefinitionsBacktraces.push_back(bt);
}
//----------------------------------------------------------------------------
static void processIncludeDirectories(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &includes,
UNORDERED_SET<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugIncludes,
const std::string& language)
{
cmMakefile *mf = tgt->GetMakefile();
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
cmLinkImplItem const& item = (*it)->LinkImplItem;
std::string const& targetName = item;
bool const fromImported = item.Target && item.Target->IsImported();
bool const checkCMP0027 = item.FromGenex;
std::vector<std::string> entryIncludes;
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
config,
false,
tgt,
dagChecker, language),
entryIncludes);
std::string usedIncludes;
for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
if (fromImported
&& !cmSystemTools::FileExists(li->c_str()))
{
std::ostringstream e;
cmake::MessageType messageType = cmake::FATAL_ERROR;
if (checkCMP0027)
{
switch(tgt->GetPolicyStatusCMP0027())
{
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
case cmPolicies::OLD:
messageType = cmake::AUTHOR_WARNING;
break;
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
break;
}
}
e << "Imported target \"" << targetName << "\" includes "
"non-existent path\n \"" << *li << "\"\nin its "
"INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
"* The path was deleted, renamed, or moved to another "
"location.\n"
"* An install or uninstall procedure did not complete "
"successfully.\n"
"* The installation package was faulty and references files it "
"does not provide.\n";
tgt->GetMakefile()->IssueMessage(messageType, e.str());
return;
}
if (!cmSystemTools::FileIsFullPath(li->c_str()))
{
std::ostringstream e;
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
if (!targetName.empty())
{
e << "Target \"" << targetName << "\" contains relative "
"path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
" \"" << *li << "\"";
}
else
{
switch(tgt->GetPolicyStatusCMP0021())
{
case cmPolicies::WARN:
{
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
messageType = cmake::AUTHOR_WARNING;
}
break;
case cmPolicies::OLD:
noMessage = true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
}
e << "Found relative path while evaluating include directories of "
"\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n";
}
if (!noMessage)
{
tgt->GetMakefile()->IssueMessage(messageType, e.str());
if (messageType == cmake::FATAL_ERROR)
{
return;
}
}
}
if (!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 (!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 std::string& config,
const std::string& language) const
{
std::vector<std::string> includes;
UNORDERED_SET<std::string> uniqueIncludes;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"INCLUDE_DIRECTORIES", 0, 0);
std::vector<std::string> debugProperties;
const char *debugProp =
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
if (debugProp)
{
cmSystemTools::ExpandListArgument(debugProp, debugProperties);
}
bool debugIncludes = !this->DebugIncludesDone
&& std::find(debugProperties.begin(),
debugProperties.end(),
"INCLUDE_DIRECTORIES")
!= debugProperties.end();
if (this->Makefile->IsConfigured())
{
this->DebugIncludesDone = true;
}
processIncludeDirectories(this,
this->Internal->IncludeDirectoriesItems,
includes,
uniqueIncludes,
&dagChecker,
config,
debugIncludes,
language);
std::vector<cmTargetInternals::TargetPropertyEntry*>
linkInterfaceIncludeDirectoriesEntries;
this->Internal->AddInterfaceEntries(
this, config, "INTERFACE_INCLUDE_DIRECTORIES",
linkInterfaceIncludeDirectoriesEntries);
if(this->Makefile->IsOn("APPLE"))
{
cmLinkImplementationLibraries const* impl =
this->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it)
{
std::string libDir = cmSystemTools::CollapseFullPath(*it);
static cmsys::RegularExpression
frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
if(!frameworkCheck.find(libDir))
{
continue;
}
libDir = frameworkCheck.match(1);
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(libDir.c_str());
linkInterfaceIncludeDirectoriesEntries
.push_back(new cmTargetInternals::TargetPropertyEntry(cge));
}
}
processIncludeDirectories(this,
linkInterfaceIncludeDirectoriesEntries,
includes,
uniqueIncludes,
&dagChecker,
config,
debugIncludes,
language);
cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
return includes;
}
//----------------------------------------------------------------------------
static void processCompileOptionsInternal(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
@ -4379,7 +4166,6 @@ cmTargetInternalPointer
//----------------------------------------------------------------------------
cmTargetInternalPointer::~cmTargetInternalPointer()
{
cmDeleteAll(this->Pointer->IncludeDirectoriesItems);
cmDeleteAll(this->Pointer->CompileOptionsItems);
cmDeleteAll(this->Pointer->CompileFeaturesItems);
cmDeleteAll(this->Pointer->CompileDefinitionsItems);

View File

@ -364,9 +364,6 @@ public:
/** @return whether this target have a well defined output file name. */
bool HaveWellDefinedOutputFiles() const;
std::vector<std::string> GetIncludeDirectories(
const std::string& config,
const std::string& language) const;
void InsertInclude(std::string const& entry,
cmListFileBacktrace const& bt,
bool before = false);
@ -402,6 +399,9 @@ public:
return this->MaxLanguageStandards;
}
cmStringRange GetIncludeDirectoriesEntries() const;
cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
#if defined(_WIN32) && !defined(__CYGWIN__)
const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
return this->LinkLibrariesForVS6;}
@ -516,7 +516,6 @@ private:
bool IsApple;
bool IsImportedTarget;
bool BuildInterfaceIncludesAppended;
mutable bool DebugIncludesDone;
mutable bool DebugCompileOptionsDone;
mutable bool DebugCompileDefinitionsDone;
mutable bool DebugSourcesDone;