Merge topic 'include-dirs-debugging'

0941d62 Add a way to print the origins of used include directories.
18a3195 Keep track of INCLUDE_DIRECTORIES as a vector of structs.
76ea420 Use cmsys::auto_ptr to manage cmCompiledGeneratorExpressions
This commit is contained in:
Brad King 2013-01-03 13:53:21 -05:00 committed by CMake Topic Stage
commit 9f8975a1a9
24 changed files with 409 additions and 142 deletions

View File

@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{ {
return target->GetLocation(this->Config); return target->GetLocation(this->Config);
} }
return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config); return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -58,7 +58,7 @@ cmCustomCommandGenerator
cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c]; cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
for(unsigned int j=1;j < commandLine.size(); ++j) for(unsigned int j=1;j < commandLine.size(); ++j)
{ {
std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile, std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile,
this->Config); this->Config);
cmd += " "; cmd += " ";
if(this->OldStyle) if(this->OldStyle)

View File

@ -896,6 +896,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
" script, it may get fatal error messages from the script.",false, " script, it may get fatal error messages from the script.",false,
"Variables That Change Behavior"); "Variables That Change Behavior");
cm->DefineProperty
("CMAKE_DEBUG_TARGET_PROPERTIES", cmProperty::VARIABLE,
"Enables tracing output for target properties.",
"This variable can be populated with a list of properties to generate "
"debug output for when evaluating target properties. Currently it can "
"only be used when evaluating the INCLUDE_DIRECTORIES target property. "
"In that case, it outputs a backtrace for each include directory in "
"the build. Default is unset.",false,"Variables That Change Behavior");
// Variables defined by CMake that describe the system // Variables defined by CMake that describe the system
cm->DefineProperty cm->DefineProperty

View File

@ -25,44 +25,29 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmGeneratorExpression::cmGeneratorExpression( cmGeneratorExpression::cmGeneratorExpression(
cmListFileBacktrace const& backtrace): cmListFileBacktrace const& backtrace):
Backtrace(backtrace), CompiledExpression(0) Backtrace(backtrace)
{ {
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const cmCompiledGeneratorExpression & cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(std::string const& input) cmGeneratorExpression::Parse(std::string const& input)
{ {
return this->Parse(input.c_str()); return this->Parse(input.c_str());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const cmCompiledGeneratorExpression & cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(const char* input) cmGeneratorExpression::Parse(const char* input)
{ {
cmGeneratorExpressionLexer l; return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(input); new cmCompiledGeneratorExpression(
bool needsParsing = l.GetSawGeneratorExpression(); this->Backtrace,
std::vector<cmGeneratorExpressionEvaluator*> evaluators; input));
if (needsParsing)
{
cmGeneratorExpressionParser p(tokens);
p.Parse(evaluators);
}
delete this->CompiledExpression;
this->CompiledExpression = new cmCompiledGeneratorExpression(
this->Backtrace,
evaluators,
input,
needsParsing);
return *this->CompiledExpression;
} }
cmGeneratorExpression::~cmGeneratorExpression() cmGeneratorExpression::~cmGeneratorExpression()
{ {
delete this->CompiledExpression;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -73,7 +58,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
{ {
if (!this->NeedsParsing) if (!this->NeedsParsing)
{ {
return this->Input; return this->Input.c_str();
} }
this->Output = ""; this->Output = "";
@ -108,12 +93,19 @@ const char *cmCompiledGeneratorExpression::Evaluate(
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace const& backtrace, cmListFileBacktrace const& backtrace,
const std::vector<cmGeneratorExpressionEvaluator*> &evaluators, const char *input)
const char *input, bool needsParsing) : Backtrace(backtrace), Input(input ? input : "")
: Backtrace(backtrace), Evaluators(evaluators), Input(input),
NeedsParsing(needsParsing)
{ {
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens =
l.Tokenize(this->Input.c_str());
this->NeedsParsing = l.GetSawGeneratorExpression();
if (this->NeedsParsing)
{
cmGeneratorExpressionParser p(tokens);
p.Parse(this->Evaluators);
}
} }

View File

@ -14,10 +14,12 @@
#define cmGeneratorExpression_h #define cmGeneratorExpression_h
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
#include "cmListFileCache.h"
#include <stack> #include <stack>
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
#include <cmsys/auto_ptr.hxx>
class cmTarget; class cmTarget;
class cmMakefile; class cmMakefile;
@ -44,8 +46,9 @@ public:
cmGeneratorExpression(cmListFileBacktrace const& backtrace); cmGeneratorExpression(cmListFileBacktrace const& backtrace);
~cmGeneratorExpression(); ~cmGeneratorExpression();
const cmCompiledGeneratorExpression& Parse(std::string const& input); cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
const cmCompiledGeneratorExpression& Parse(const char* input); std::string const& input);
cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(const char* input);
enum PreprocessContext { enum PreprocessContext {
StripAllGeneratorExpressions StripAllGeneratorExpressions
@ -59,7 +62,6 @@ private:
void operator=(const cmGeneratorExpression &); void operator=(const cmGeneratorExpression &);
cmListFileBacktrace const& Backtrace; cmListFileBacktrace const& Backtrace;
cmCompiledGeneratorExpression *CompiledExpression;
}; };
class cmCompiledGeneratorExpression class cmCompiledGeneratorExpression
@ -76,20 +78,29 @@ public:
~cmCompiledGeneratorExpression(); ~cmCompiledGeneratorExpression();
std::string GetInput() const
{
return this->Input;
}
cmListFileBacktrace GetBacktrace() const
{
return this->Backtrace;
}
private: private:
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
const std::vector<cmGeneratorExpressionEvaluator*> &evaluators, const char *input);
const char *input, bool needsParsing);
friend class cmGeneratorExpression; friend class cmGeneratorExpression;
cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &); cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &);
void operator=(const cmCompiledGeneratorExpression &); void operator=(const cmCompiledGeneratorExpression &);
cmListFileBacktrace const& Backtrace; cmListFileBacktrace Backtrace;
const std::vector<cmGeneratorExpressionEvaluator*> Evaluators; std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
const char* const Input; const std::string Input;
const bool NeedsParsing; bool NeedsParsing;
mutable std::set<cmTarget*> Targets; mutable std::set<cmTarget*> Targets;
mutable std::string Output; mutable std::string Output;

View File

@ -252,45 +252,7 @@ const char* cmGeneratorTarget::GetCreateRuleVariable()
std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories( std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
const char *config) const char *config)
{ {
std::vector<std::string> includes; return this->Target->GetIncludeDirectories(config);
const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES");
if(!prop)
{
return includes;
}
cmListFileBacktrace lfbt;
cmGeneratorExpression ge(lfbt);
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(),
"INCLUDE_DIRECTORIES", 0, 0);
cmSystemTools::ExpandListArgument(ge.Parse(prop)
.Evaluate(this->Makefile,
config,
false,
this->Target,
&dagChecker),
includes);
std::set<std::string> uniqueIncludes;
std::vector<std::string> orderedAndUniqueIncludes;
for(std::vector<std::string>::const_iterator
li = includes.begin(); li != includes.end(); ++li)
{
std::string inc = *li;
if (!cmSystemTools::IsOff(inc.c_str()))
{
cmSystemTools::ConvertToUnixSlashes(inc);
}
if(uniqueIncludes.insert(inc).second)
{
orderedAndUniqueIncludes.push_back(inc);
}
}
return orderedAndUniqueIncludes;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -315,7 +277,7 @@ std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
cmGeneratorExpressionDAGChecker dagChecker(lfbt, cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(), this->GetName(),
defPropName, 0, 0); defPropName, 0, 0);
return ge.Parse(prop).Evaluate(this->Makefile, return ge.Parse(prop)->Evaluate(this->Makefile,
config, config,
false, false,
this->Target, this->Target,

View File

@ -1485,9 +1485,12 @@ void cmMakefile::InitializeFromParent()
// Initialize definitions with the closure of the parent scope. // Initialize definitions with the closure of the parent scope.
this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure(); this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure();
// copy include paths const std::vector<IncludeDirectoriesEntry> parentIncludes =
this->SetProperty("INCLUDE_DIRECTORIES", parent->GetIncludeDirectoriesEntries();
parent->GetProperty("INCLUDE_DIRECTORIES")); this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(),
parentIncludes.begin(),
parentIncludes.end());
this->SystemIncludeDirectories = parent->SystemIncludeDirectories; this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
// define flags // define flags
@ -1612,41 +1615,6 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
} }
} }
//----------------------------------------------------------------------------
void AddStringToProperty(cmProperty *prop, const char* name, const char* s,
bool before)
{
if (!prop)
{
return;
}
// Don't worry about duplicates at this point. We eliminate them when
// we convert the property to a vector in GetIncludeDirectories.
if (before)
{
const char *val = prop->GetValue();
cmOStringStream oss;
if(val && *val)
{
oss << s << ";" << val;
}
else
{
oss << s;
}
std::string newVal = oss.str();
prop->Set(name, newVal.c_str());
}
else
{
prop->Append(name, s);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmMakefile::AddIncludeDirectory(const char* inc, bool before) void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
{ {
@ -1655,18 +1623,21 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
return; return;
} }
// Directory property: std::vector<IncludeDirectoriesEntry>::iterator position =
cmProperty *prop = before ? this->IncludeDirectoriesEntries.begin()
this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES"); : this->IncludeDirectoriesEntries.end();
AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
cmListFileBacktrace lfbt;
this->GetBacktrace(lfbt);
IncludeDirectoriesEntry entry(inc, lfbt);
this->IncludeDirectoriesEntries.insert(position, entry);
// Property on each target: // Property on each target:
for (cmTargets::iterator l = this->Targets.begin(); for (cmTargets::iterator l = this->Targets.begin();
l != this->Targets.end(); ++l) l != this->Targets.end(); ++l)
{ {
cmTarget &t = l->second; cmTarget &t = l->second;
prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES"); t.InsertInclude(entry, before);
AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
} }
} }
@ -3451,6 +3422,15 @@ void cmMakefile::SetProperty(const char* prop, const char* value)
this->SetLinkDirectories(varArgsExpanded); this->SetLinkDirectories(varArgsExpanded);
return; return;
} }
if (propname == "INCLUDE_DIRECTORIES")
{
this->IncludeDirectoriesEntries.clear();
cmListFileBacktrace lfbt;
this->GetBacktrace(lfbt);
this->IncludeDirectoriesEntries.push_back(
IncludeDirectoriesEntry(value, lfbt));
return;
}
if ( propname == "INCLUDE_REGULAR_EXPRESSION" ) if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
{ {
@ -3482,6 +3462,14 @@ void cmMakefile::AppendProperty(const char* prop, const char* value,
// handle special props // handle special props
std::string propname = prop; std::string propname = prop;
if (propname == "INCLUDE_DIRECTORIES")
{
cmListFileBacktrace lfbt;
this->GetBacktrace(lfbt);
this->IncludeDirectoriesEntries.push_back(
IncludeDirectoriesEntry(value, lfbt));
return;
}
if ( propname == "LINK_DIRECTORIES" ) if ( propname == "LINK_DIRECTORIES" )
{ {
std::vector<std::string> varArgsExpanded; std::vector<std::string> varArgsExpanded;
@ -3593,6 +3581,20 @@ const char *cmMakefile::GetProperty(const char* prop,
output = str.str(); output = str.str();
return output.c_str(); return output.c_str();
} }
else if (!strcmp("INCLUDE_DIRECTORIES",prop))
{
std::string sep;
for (std::vector<IncludeDirectoriesEntry>::const_iterator
it = this->IncludeDirectoriesEntries.begin(),
end = this->IncludeDirectoriesEntries.end();
it != end; ++it)
{
output += sep;
output += it->Value;
sep = ";";
}
return output.c_str();
}
bool chain = false; bool chain = false;
const char *retVal = const char *retVal =

View File

@ -22,6 +22,7 @@
#include "cmNewLineStyle.h" #include "cmNewLineStyle.h"
#include "cmGeneratorTarget.h" #include "cmGeneratorTarget.h"
#include "cmake.h" #include "cmake.h"
#include "cmMakefileIncludeDirectoriesEntry.h"
#if defined(CMAKE_BUILD_WITH_CMAKE) #if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmSourceGroup.h" #include "cmSourceGroup.h"
@ -861,6 +862,13 @@ public:
/** Set whether or not to report a CMP0000 violation. */ /** Set whether or not to report a CMP0000 violation. */
void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; } void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
typedef cmMakefileIncludeDirectoriesEntry IncludeDirectoriesEntry;
std::vector<IncludeDirectoriesEntry> GetIncludeDirectoriesEntries() const
{
return this->IncludeDirectoriesEntries;
}
protected: protected:
// add link libraries and directories to the target // add link libraries and directories to the target
void AddGlobalLinkInformation(const char* name, cmTarget& target); void AddGlobalLinkInformation(const char* name, cmTarget& target);
@ -909,6 +917,8 @@ protected:
std::vector<std::string> HeaderFileExtensions; std::vector<std::string> HeaderFileExtensions;
std::string DefineFlags; std::string DefineFlags;
std::vector<IncludeDirectoriesEntry> IncludeDirectoriesEntries;
// Track the value of the computed DEFINITIONS property. // Track the value of the computed DEFINITIONS property.
void AddDefineFlag(const char*, std::string&); void AddDefineFlag(const char*, std::string&);
void RemoveDefineFlag(const char*, std::string::size_type, std::string&); void RemoveDefineFlag(const char*, std::string::size_type, std::string&);

View File

@ -0,0 +1,28 @@
/*============================================================================
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

@ -21,6 +21,7 @@
#include "cmDocumentLocationUndefined.h" #include "cmDocumentLocationUndefined.h"
#include "cmListFileCache.h" #include "cmListFileCache.h"
#include "cmGeneratorExpression.h" #include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
#include <map> #include <map>
#include <set> #include <set>
@ -118,6 +119,14 @@ public:
struct SourceEntry { std::vector<cmSourceFile*> Depends; }; struct SourceEntry { std::vector<cmSourceFile*> Depends; };
typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType; typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
SourceEntriesType SourceEntries; SourceEntriesType SourceEntries;
struct IncludeDirectoriesEntry {
IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge)
: ge(cge)
{}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
};
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
}; };
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1392,8 +1401,14 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// Initialize the INCLUDE_DIRECTORIES property based on the current value // Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property: // of the same directory property:
this->SetProperty("INCLUDE_DIRECTORIES", const std::vector<cmMakefileIncludeDirectoriesEntry> parentIncludes =
this->Makefile->GetProperty("INCLUDE_DIRECTORIES")); this->Makefile->GetIncludeDirectoriesEntries();
for (std::vector<cmMakefileIncludeDirectoriesEntry>::const_iterator it
= parentIncludes.begin(); it != parentIncludes.end(); ++it)
{
this->InsertInclude(*it);
}
if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
|| this->TargetTypeValue == cmTarget::MODULE_LIBRARY) || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
@ -1728,9 +1743,10 @@ cmTargetTraceDependencies
for(cmCustomCommandLine::const_iterator cli = cit->begin(); for(cmCustomCommandLine::const_iterator cli = cit->begin();
cli != cit->end(); ++cli) cli != cit->end(); ++cli)
{ {
const cmCompiledGeneratorExpression &cge = ge.Parse(*cli); const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
cge.Evaluate(this->Makefile, 0, true); = ge.Parse(*cli);
std::set<cmTarget*> geTargets = cge.GetTargets(); cge->Evaluate(this->Makefile, 0, true);
std::set<cmTarget*> geTargets = cge->GetTargets();
for(std::set<cmTarget*>::const_iterator it = geTargets.begin(); for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
it != geTargets.end(); ++it) it != geTargets.end(); ++it)
{ {
@ -2444,6 +2460,20 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
} }
} }
//----------------------------------------------------------------------------
void deleteAndClear(
std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries)
{
for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
it = entries.begin(),
end = entries.end();
it != end; ++it)
{
delete *it;
}
entries.clear();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::SetProperty(const char* prop, const char* value) void cmTarget::SetProperty(const char* prop, const char* value)
{ {
@ -2452,6 +2482,17 @@ void cmTarget::SetProperty(const char* prop, const char* value)
return; return;
} }
if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
{
cmListFileBacktrace lfbt;
this->Makefile->GetBacktrace(lfbt);
cmGeneratorExpression ge(lfbt);
deleteAndClear(this->Internal->IncludeDirectoriesEntries);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->IncludeDirectoriesEntries.push_back(
new cmTargetInternals::IncludeDirectoriesEntry(cge));
return;
}
this->Properties.SetProperty(prop, value, cmProperty::TARGET); this->Properties.SetProperty(prop, value, cmProperty::TARGET);
this->MaybeInvalidatePropertyCache(prop); this->MaybeInvalidatePropertyCache(prop);
} }
@ -2464,10 +2505,99 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
{ {
return; return;
} }
if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
{
cmListFileBacktrace lfbt;
this->Makefile->GetBacktrace(lfbt);
cmGeneratorExpression ge(lfbt);
this->Internal->IncludeDirectoriesEntries.push_back(
new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value)));
return;
}
this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
this->MaybeInvalidatePropertyCache(prop); this->MaybeInvalidatePropertyCache(prop);
} }
//----------------------------------------------------------------------------
void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
bool before)
{
cmGeneratorExpression ge(entry.Backtrace);
std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::iterator position
= before ? this->Internal->IncludeDirectoriesEntries.begin()
: this->Internal->IncludeDirectoriesEntries.end();
this->Internal->IncludeDirectoriesEntries.insert(position,
new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(entry.Value)));
}
//----------------------------------------------------------------------------
std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
{
std::vector<std::string> includes;
std::set<std::string> uniqueIncludes;
cmListFileBacktrace lfbt;
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
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 = std::find(debugProperties.begin(),
debugProperties.end(),
"INCLUDE_DIRECTORIES")
!= debugProperties.end();
for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
it = this->Internal->IncludeDirectoriesEntries.begin(),
end = this->Internal->IncludeDirectoriesEntries.end();
it != end; ++it)
{
std::vector<std::string> entryIncludes;
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
config,
false,
this,
&dagChecker),
entryIncludes);
std::string usedIncludes;
for(std::vector<std::string>::const_iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
std::string inc = *li;
if (!cmSystemTools::IsOff(inc.c_str()))
{
cmSystemTools::ConvertToUnixSlashes(inc);
}
if(uniqueIncludes.insert(inc).second)
{
includes.push_back(*li);
if (debugIncludes)
{
usedIncludes += " * " + *li + "\n";
}
}
}
if (!usedIncludes.empty())
{
this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,
"Used includes:\n" + usedIncludes,
(*it)->ge->GetBacktrace());
}
}
return includes;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::MaybeInvalidatePropertyCache(const char* prop) void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
{ {
@ -2795,6 +2925,24 @@ const char *cmTarget::GetProperty(const char* prop,
} }
} }
} }
if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
{
static std::string output;
output = "";
std::string sep;
typedef cmTargetInternals::IncludeDirectoriesEntry
IncludeDirectoriesEntry;
for (std::vector<IncludeDirectoriesEntry*>::const_iterator
it = this->Internal->IncludeDirectoriesEntries.begin(),
end = this->Internal->IncludeDirectoriesEntries.end();
it != end; ++it)
{
output += sep;
output += (*it)->ge->GetInput();
sep = ";";
}
return output.c_str();
}
if (strcmp(prop,"IMPORTED") == 0) if (strcmp(prop,"IMPORTED") == 0)
{ {
@ -4918,6 +5066,7 @@ cmTargetInternalPointer
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTargetInternalPointer::~cmTargetInternalPointer() cmTargetInternalPointer::~cmTargetInternalPointer()
{ {
deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
delete this->Pointer; delete this->Pointer;
} }

View File

@ -15,6 +15,7 @@
#include "cmCustomCommand.h" #include "cmCustomCommand.h"
#include "cmPropertyMap.h" #include "cmPropertyMap.h"
#include "cmPolicies.h" #include "cmPolicies.h"
#include "cmMakefileIncludeDirectoriesEntry.h"
#include <cmsys/auto_ptr.hxx> #include <cmsys/auto_ptr.hxx>
@ -470,6 +471,9 @@ public:
/** @return the Mac framework directory without the base. */ /** @return the Mac framework directory without the base. */
std::string GetFrameworkDirectory(const char* config = 0); std::string GetFrameworkDirectory(const char* config = 0);
std::vector<std::string> GetIncludeDirectories(const char *config);
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
bool before = false);
private: private:
/** /**
* A list of direct dependencies. Use in conjunction with DependencyMap. * A list of direct dependencies. Use in conjunction with DependencyMap.

View File

@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
else else
{ {
// Use the command name given. // Use the command name given.
exe = ge.Parse(exe.c_str()).Evaluate(mf, config); exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
cmSystemTools::ConvertToUnixSlashes(exe); cmSystemTools::ConvertToUnixSlashes(exe);
} }
@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
for(std::vector<std::string>::const_iterator ci = command.begin()+1; for(std::vector<std::string>::const_iterator ci = command.begin()+1;
ci != command.end(); ++ci) ci != command.end(); ++ci)
{ {
os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config)); os << " " << lg->EscapeForCMake(ge.Parse(*ci)->Evaluate(mf, config));
} }
// Finish the test command. // Finish the test command.

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadInvalidName1.cmake:7 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:Invali/dTarget,INCLUDE_DIRECTORIES> \$<TARGET_PROPERTY:Invali/dTarget,INCLUDE_DIRECTORIES>
Target name not supported. Target name not supported.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadInvalidName2.cmake:7 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:Invali/dTarget,Invali/dProperty> \$<TARGET_PROPERTY:Invali/dTarget,Invali/dProperty>
Target name and property name not supported.$ Target name and property name not supported.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadInvalidName3.cmake:7 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:Invali/dProperty> \$<TARGET_PROPERTY:Invali/dProperty>
Property name not supported.$ Property name not supported.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadInvalidName4.cmake:9 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:foo,Invali/dProperty> \$<TARGET_PROPERTY:foo,Invali/dProperty>
Property name not supported.$ Property name not supported.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -1,7 +1,9 @@
CMake Error: CMake Error at BadInvalidName5.cmake:7 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:,> \$<TARGET_PROPERTY:,>
\$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty target name and \$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty target name and
property name. property name.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadInvalidName6.cmake:7 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:,ValidProperty> \$<TARGET_PROPERTY:,ValidProperty>
\$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty target name. \$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty target name.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadInvalidName7.cmake:9 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:foo,> \$<TARGET_PROPERTY:foo,>
\$<TARGET_PROPERTY:...> expression requires a non-empty property name. \$<TARGET_PROPERTY:...> expression requires a non-empty property name.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadInvalidName8.cmake:7 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:> \$<TARGET_PROPERTY:>
\$<TARGET_PROPERTY:...> expression requires a non-empty property name. \$<TARGET_PROPERTY:...> expression requires a non-empty property name.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -1,6 +1,8 @@
CMake Error: CMake Error at BadNonTarget.cmake:7 \(include_directories\):
Error evaluating generator expression: Error evaluating generator expression:
\$<TARGET_PROPERTY:NonExistant,INCLUDE_DIRECTORIES> \$<TARGET_PROPERTY:NonExistant,INCLUDE_DIRECTORIES>
Target "NonExistant" not found.$ Target "NonExistant" not found.
Call Stack \(most recent call first\):
CMakeLists.txt:8 \(include\)$

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,42 @@
CMake Warning at DebugIncludes.cmake:8 \(include_directories\):
Used includes:
\* .*/Tests/RunCMake/include_directories/one
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Warning at DebugIncludes.cmake:8 \(include_directories\):
Used includes:
\* .*/Tests/RunCMake/include_directories/two
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Warning at DebugIncludes.cmake:13 \(set_property\):
Used includes:
\* .*/Tests/RunCMake/include_directories/three
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Warning at DebugIncludes.cmake:18 \(include_directories\):
Used includes:
\* .*/Tests/RunCMake/include_directories/four
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Warning at DebugIncludes.cmake:25 \(set_property\):
Used includes:
\* .*/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\)

View File

@ -0,0 +1,38 @@
project(DebugIncludes)
set(CMAKE_DEBUG_TARGET_PROPERTIES INCLUDE_DIRECTORIES)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp" "enum { dummy };\n")
include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/one"
"${CMAKE_CURRENT_SOURCE_DIR}/two"
)
set_property(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
"${CMAKE_CURRENT_SOURCE_DIR}/three")
add_library(lll "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp")
include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/two"
"${CMAKE_CURRENT_SOURCE_DIR}/three"
"${CMAKE_CURRENT_SOURCE_DIR}/four"
)
macro(some_macro)
set_property(TARGET lll APPEND PROPERTY
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/one"
"${CMAKE_CURRENT_SOURCE_DIR}/three"
"${CMAKE_CURRENT_SOURCE_DIR}/four"
"${CMAKE_CURRENT_SOURCE_DIR}/five"
"${CMAKE_CURRENT_SOURCE_DIR}/six"
)
endmacro()
function(some_function)
some_macro()
endfunction()
some_function()

View File

@ -1,3 +1,4 @@
include(RunCMake) include(RunCMake)
run_cmake(NotFoundContent) run_cmake(NotFoundContent)
run_cmake(DebugIncludes)