Merge topic 'generator-expression-target-properties'
083de7e
Process generator expressions in the COMPILE_DEFINITIONS target property.08cb4fa
Process generator expressions in the INCLUDE_DIRECTORIES property.0ef091d
Early return if there is no target.eb250cd
Add a self-reference check for target properties.7e80747
Add API to check that dependent target properties form a DAG.239ac84
Add a generator expression for target properties.e028381
Extend the generator expression language with more logic.b8e61d6
Refactor GetCompileDefinitions a bit.2c2b25b
Return a std::string from GetCompileDefinitions.b7e48e0
Add an AppendDefines std::string overload.9a16087
Convert paths in INCLUDE_DIRECTORIES property to Unix slashes.4557c8d
Don't prepend a path before generator expressions in include_directories.c6abc41
Add include guard for cmGeneratorExpression.0ff4e3f
Port remaining code to GetCompileDefinitions().f178d53
Fix indentation in the code blocks generator.
This commit is contained in:
commit
103d99338a
|
@ -183,6 +183,8 @@ set(SRCS
|
|||
cmFileTimeComparison.cxx
|
||||
cmFileTimeComparison.h
|
||||
cmGeneratedFileStream.cxx
|
||||
cmGeneratorExpressionDAGChecker.cxx
|
||||
cmGeneratorExpressionDAGChecker.h
|
||||
cmGeneratorExpressionEvaluator.cxx
|
||||
cmGeneratorExpressionEvaluator.h
|
||||
cmGeneratorExpressionLexer.cxx
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
"\n"
|
||||
"Arguments after COMMAND may use \"generator expressions\" with the "
|
||||
"syntax \"$<...>\". "
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS
|
||||
"Example usage:\n"
|
||||
" add_test(NAME mytest\n"
|
||||
" COMMAND testDriver --config $<CONFIGURATION>\n"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#ifndef cmDocumentGeneratorExpressions_h
|
||||
#define cmDocumentGeneratorExpressions_h
|
||||
|
||||
#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \
|
||||
#define CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
|
||||
"Generator expressions are evaluted during build system generation " \
|
||||
"to produce information specific to each build configuration. " \
|
||||
"Valid expressions are:\n" \
|
||||
|
@ -20,6 +20,12 @@
|
|||
" $<1:...> = content of \"...\"\n" \
|
||||
" $<CONFIG:cfg> = '1' if config is \"cfg\", else '0'\n" \
|
||||
" $<CONFIGURATION> = configuration name\n" \
|
||||
" $<BOOL:...> = '1' if the '...' is true, else '0'\n" \
|
||||
" $<STREQUAL:a,b> = '1' if a is STREQUAL b, else '0'\n" \
|
||||
" $<ANGLE-R> = A literal '>'. Used to compare " \
|
||||
"strings which contain a '>' for example.\n" \
|
||||
" $<COMMA> = A literal ','. Used to compare " \
|
||||
"strings which contain a ',' for example.\n" \
|
||||
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
|
||||
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
|
||||
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
|
||||
|
@ -29,11 +35,20 @@
|
|||
" $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n" \
|
||||
" $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \
|
||||
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" \
|
||||
" $<TARGET_PROPERTY:tgt,prop> = The value of the property prop\n" \
|
||||
"the target tgt. Note that tgt is not added as a dependency of the " \
|
||||
"target this expression is evaluated on.\n" \
|
||||
"Boolean expressions:\n" \
|
||||
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
|
||||
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
|
||||
" $<NOT:?> = '0' if '?' is '1', else '1'\n" \
|
||||
"where '?' is always either '0' or '1'.\n" \
|
||||
|
||||
#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \
|
||||
CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
|
||||
"Expressions with an implicit 'this' target:" \
|
||||
" $<TARGET_PROPERTY:prop> = The value of the property prop on\n" \
|
||||
"the target on which the generator expression is evaluated.\n" \
|
||||
""
|
||||
|
||||
#endif
|
||||
|
|
|
@ -617,14 +617,17 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
|
|||
" <Option compiler=\"" << compiler << "\" />\n"
|
||||
" <Compiler>\n";
|
||||
|
||||
cmGeneratorTarget *gtgt = this->GlobalGenerator
|
||||
->GetGeneratorTarget(target);
|
||||
|
||||
// the compilerdefines for this target
|
||||
const char* cdefs = target->GetMakefile()->GetProperty(
|
||||
"COMPILE_DEFINITIONS");
|
||||
if(cdefs)
|
||||
std::string cdefs = gtgt->GetCompileDefinitions();
|
||||
|
||||
if(cdefs.empty())
|
||||
{
|
||||
// Expand the list.
|
||||
std::vector<std::string> defs;
|
||||
cmSystemTools::ExpandListArgument(cdefs, defs);
|
||||
cmSystemTools::ExpandListArgument(cdefs.c_str(), defs);
|
||||
for(std::vector<std::string>::const_iterator di = defs.begin();
|
||||
di != defs.end(); ++di)
|
||||
{
|
||||
|
@ -633,59 +636,57 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
|
|||
}
|
||||
}
|
||||
|
||||
// the include directories for this target
|
||||
std::set<std::string> uniqIncludeDirs;
|
||||
// the include directories for this target
|
||||
std::set<std::string> uniqIncludeDirs;
|
||||
|
||||
cmGeneratorTarget *gtgt = this->GlobalGenerator
|
||||
->GetGeneratorTarget(target);
|
||||
std::vector<std::string> includes;
|
||||
target->GetMakefile()->GetLocalGenerator()->
|
||||
GetIncludeDirectories(includes, gtgt);
|
||||
for(std::vector<std::string>::const_iterator dirIt=includes.begin();
|
||||
dirIt != includes.end();
|
||||
std::vector<std::string> includes;
|
||||
target->GetMakefile()->GetLocalGenerator()->
|
||||
GetIncludeDirectories(includes, gtgt);
|
||||
for(std::vector<std::string>::const_iterator dirIt=includes.begin();
|
||||
dirIt != includes.end();
|
||||
++dirIt)
|
||||
{
|
||||
uniqIncludeDirs.insert(*dirIt);
|
||||
}
|
||||
|
||||
std::string systemIncludeDirs = makefile->GetSafeDefinition(
|
||||
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
|
||||
if (!systemIncludeDirs.empty())
|
||||
{
|
||||
std::vector<std::string> dirs;
|
||||
cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
|
||||
for(std::vector<std::string>::const_iterator dirIt=dirs.begin();
|
||||
dirIt != dirs.end();
|
||||
++dirIt)
|
||||
{
|
||||
uniqIncludeDirs.insert(*dirIt);
|
||||
}
|
||||
}
|
||||
|
||||
std::string systemIncludeDirs = makefile->GetSafeDefinition(
|
||||
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
|
||||
if (!systemIncludeDirs.empty())
|
||||
{
|
||||
std::vector<std::string> dirs;
|
||||
cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
|
||||
for(std::vector<std::string>::const_iterator dirIt=dirs.begin();
|
||||
dirIt != dirs.end();
|
||||
++dirIt)
|
||||
{
|
||||
uniqIncludeDirs.insert(*dirIt);
|
||||
}
|
||||
}
|
||||
|
||||
systemIncludeDirs = makefile->GetSafeDefinition(
|
||||
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
|
||||
if (!systemIncludeDirs.empty())
|
||||
{
|
||||
std::vector<std::string> dirs;
|
||||
cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
|
||||
for(std::vector<std::string>::const_iterator dirIt=dirs.begin();
|
||||
dirIt != dirs.end();
|
||||
++dirIt)
|
||||
{
|
||||
uniqIncludeDirs.insert(*dirIt);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::set<std::string>::const_iterator dirIt=uniqIncludeDirs.begin();
|
||||
dirIt != uniqIncludeDirs.end();
|
||||
systemIncludeDirs = makefile->GetSafeDefinition(
|
||||
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
|
||||
if (!systemIncludeDirs.empty())
|
||||
{
|
||||
std::vector<std::string> dirs;
|
||||
cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
|
||||
for(std::vector<std::string>::const_iterator dirIt=dirs.begin();
|
||||
dirIt != dirs.end();
|
||||
++dirIt)
|
||||
{
|
||||
fout <<" <Add directory=\"" << dirIt->c_str() << "\" />\n";
|
||||
uniqIncludeDirs.insert(*dirIt);
|
||||
}
|
||||
|
||||
fout<<" </Compiler>\n";
|
||||
}
|
||||
else // e.g. all and the GLOBAL and UTILITY targets
|
||||
|
||||
for(std::set<std::string>::const_iterator dirIt=uniqIncludeDirs.begin();
|
||||
dirIt != uniqIncludeDirs.end();
|
||||
++dirIt)
|
||||
{
|
||||
fout <<" <Add directory=\"" << dirIt->c_str() << "\" />\n";
|
||||
}
|
||||
|
||||
fout<<" </Compiler>\n";
|
||||
}
|
||||
else // e.g. all and the GLOBAL and UTILITY targets
|
||||
{
|
||||
fout<<" <Option working_dir=\""
|
||||
<< makefile->GetStartOutputDirectory() << "\" />\n"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "cmGeneratorExpressionEvaluator.h"
|
||||
#include "cmGeneratorExpressionLexer.h"
|
||||
#include "cmGeneratorExpressionParser.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmGeneratorExpression::cmGeneratorExpression(
|
||||
|
@ -65,7 +66,9 @@ cmGeneratorExpression::~cmGeneratorExpression()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
const char *cmCompiledGeneratorExpression::Evaluate(
|
||||
cmMakefile* mf, const char* config, bool quiet) const
|
||||
cmMakefile* mf, const char* config, bool quiet,
|
||||
cmGeneratorTarget *target,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const
|
||||
{
|
||||
if (!this->NeedsParsing)
|
||||
{
|
||||
|
@ -84,11 +87,12 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
|||
context.Config = config;
|
||||
context.Quiet = quiet;
|
||||
context.HadError = false;
|
||||
context.Target = target;
|
||||
context.Backtrace = this->Backtrace;
|
||||
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
this->Output += (*it)->Evaluate(&context);
|
||||
this->Output += (*it)->Evaluate(&context, dagChecker);
|
||||
if (context.HadError)
|
||||
{
|
||||
this->Output = "";
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
|
||||
#ifndef cmGeneratorExpression_h
|
||||
#define cmGeneratorExpression_h
|
||||
|
||||
#include "cmStandardIncludes.h"
|
||||
|
||||
#include <stack>
|
||||
|
@ -16,10 +20,12 @@
|
|||
#include <cmsys/RegularExpression.hxx>
|
||||
|
||||
class cmTarget;
|
||||
class cmGeneratorTarget;
|
||||
class cmMakefile;
|
||||
class cmListFileBacktrace;
|
||||
|
||||
struct cmGeneratorExpressionEvaluator;
|
||||
struct cmGeneratorExpressionDAGChecker;
|
||||
|
||||
class cmCompiledGeneratorExpression;
|
||||
|
||||
|
@ -54,7 +60,9 @@ class cmCompiledGeneratorExpression
|
|||
{
|
||||
public:
|
||||
const char* Evaluate(cmMakefile* mf, const char* config,
|
||||
bool quiet = false) const;
|
||||
bool quiet = false,
|
||||
cmGeneratorTarget *target = 0,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker = 0) const;
|
||||
|
||||
/** Get set of targets found during evaluations. */
|
||||
std::set<cmTarget*> const& GetTargets() const
|
||||
|
@ -80,3 +88,5 @@ private:
|
|||
mutable std::set<cmTarget*> Targets;
|
||||
mutable std::string Output;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*============================================================================
|
||||
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.
|
||||
============================================================================*/
|
||||
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
|
||||
#include "cmMakefile.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
|
||||
const cmListFileBacktrace &backtrace,
|
||||
const std::string &target,
|
||||
const std::string &property,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *parent)
|
||||
: Parent(parent), Target(target), Property(property),
|
||||
Content(content), Backtrace(backtrace)
|
||||
{
|
||||
this->IsDAG = this->isDAG();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::check() const
|
||||
{
|
||||
return this->IsDAG;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorExpressionDAGChecker::reportError(
|
||||
cmGeneratorExpressionContext *context,
|
||||
const std::string &expr)
|
||||
{
|
||||
if (this->IsDAG)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context->HadError = true;
|
||||
if (context->Quiet)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
||||
|
||||
if (parent && !parent->Parent)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Error evaluating generator expression:\n"
|
||||
<< " " << expr << "\n"
|
||||
<< "Self reference on target \""
|
||||
<< context->Target->GetName() << "\".\n";
|
||||
context->Makefile->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
|
||||
parent->Backtrace);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Error evaluating generator expression:\n"
|
||||
<< " " << expr << "\n"
|
||||
<< "Dependency loop found.";
|
||||
context->Makefile->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
|
||||
context->Backtrace);
|
||||
}
|
||||
|
||||
int loopStep = 1;
|
||||
while (parent)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Loop step " << loopStep << "\n"
|
||||
<< " "
|
||||
<< (parent->Content ? parent->Content->GetOriginalExpression() : expr)
|
||||
<< "\n";
|
||||
context->Makefile->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
|
||||
parent->Backtrace);
|
||||
parent = parent->Parent;
|
||||
++loopStep;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::isDAG() const
|
||||
{
|
||||
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
||||
while (parent)
|
||||
{
|
||||
if (this->Target == parent->Target && this->Property == parent->Property)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
parent = parent->Parent;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*============================================================================
|
||||
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 cmGeneratorExpressionDAGChecker_h
|
||||
#define cmGeneratorExpressionDAGChecker_h
|
||||
|
||||
#include "cmStandardIncludes.h"
|
||||
|
||||
#include "cmGeneratorExpressionEvaluator.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct cmGeneratorExpressionDAGChecker
|
||||
{
|
||||
cmGeneratorExpressionDAGChecker(const cmListFileBacktrace &backtrace,
|
||||
const std::string &target,
|
||||
const std::string &property,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *parent);
|
||||
|
||||
bool check() const;
|
||||
|
||||
void reportError(cmGeneratorExpressionContext *context,
|
||||
const std::string &expr);
|
||||
private:
|
||||
bool isDAG() const;
|
||||
|
||||
private:
|
||||
const cmGeneratorExpressionDAGChecker * const Parent;
|
||||
const std::string Target;
|
||||
const std::string Property;
|
||||
const GeneratorExpressionContent * const Content;
|
||||
const cmListFileBacktrace Backtrace;
|
||||
bool IsDAG;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include "cmGeneratorExpressionEvaluator.h"
|
||||
#include "cmGeneratorExpressionParser.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static void reportError(cmGeneratorExpressionContext *context,
|
||||
|
@ -47,7 +49,8 @@ struct cmGeneratorExpressionNode
|
|||
|
||||
virtual std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker
|
||||
) const = 0;
|
||||
};
|
||||
|
||||
|
@ -60,7 +63,8 @@ static const struct ZeroNode : public cmGeneratorExpressionNode
|
|||
|
||||
std::string Evaluate(const std::vector<std::string> &,
|
||||
cmGeneratorExpressionContext *,
|
||||
const GeneratorExpressionContent *) const
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
// Unreachable
|
||||
return std::string();
|
||||
|
@ -76,7 +80,8 @@ static const struct OneNode : public cmGeneratorExpressionNode
|
|||
|
||||
std::string Evaluate(const std::vector<std::string> &,
|
||||
cmGeneratorExpressionContext *,
|
||||
const GeneratorExpressionContent *) const
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
// Unreachable
|
||||
return std::string();
|
||||
|
@ -93,7 +98,8 @@ static const struct OP ## Node : public cmGeneratorExpressionNode \
|
|||
\
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters, \
|
||||
cmGeneratorExpressionContext *context, \
|
||||
const GeneratorExpressionContent *content) const \
|
||||
const GeneratorExpressionContent *content, \
|
||||
cmGeneratorExpressionDAGChecker *) const \
|
||||
{ \
|
||||
std::vector<std::string>::const_iterator it = parameters.begin(); \
|
||||
const std::vector<std::string>::const_iterator end = parameters.end(); \
|
||||
|
@ -123,9 +129,11 @@ BOOLEAN_OP_NODE(orNode, OR, 0, 1)
|
|||
static const struct NotNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
NotNode() {}
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content) const
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
if (*parameters.begin() != "0" && *parameters.begin() != "1")
|
||||
{
|
||||
|
@ -137,15 +145,81 @@ static const struct NotNode : public cmGeneratorExpressionNode
|
|||
}
|
||||
} notNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct BoolNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
BoolNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 1; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *,
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0";
|
||||
}
|
||||
} boolNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct StrEqualNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
StrEqualNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 2; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *,
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return *parameters.begin() == parameters.at(1) ? "1" : "0";
|
||||
}
|
||||
} strEqualNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct Angle_RNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
Angle_RNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 0; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> &,
|
||||
cmGeneratorExpressionContext *,
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return ">";
|
||||
}
|
||||
} angle_rNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct CommaNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
CommaNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 0; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> &,
|
||||
cmGeneratorExpressionContext *,
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return ",";
|
||||
}
|
||||
} commaNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct ConfigurationNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
ConfigurationNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 0; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> &,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *) const
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return context->Config ? context->Config : "";
|
||||
}
|
||||
|
@ -160,7 +234,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
|
|||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content) const
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
if (!context->Config)
|
||||
{
|
||||
|
@ -179,6 +254,61 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
|
|||
}
|
||||
} configurationTestNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetPropertyNode() {}
|
||||
|
||||
// This node handles errors on parameter count itself.
|
||||
virtual int NumExpectedParameters() const { return -1; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *dagCheckerParent
|
||||
) const
|
||||
{
|
||||
if (parameters.size() != 1 && parameters.size() != 2)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<TARGET_PROPERTY:...> expression requires one or two parameters");
|
||||
return std::string();
|
||||
}
|
||||
cmGeneratorTarget* target = context->Target;
|
||||
std::string propertyName = *parameters.begin();
|
||||
if (parameters.size() == 2)
|
||||
{
|
||||
target = context->Makefile->FindGeneratorTargetToUse(
|
||||
parameters.begin()->c_str());
|
||||
|
||||
if (!target)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \""
|
||||
<< target
|
||||
<< "\" not found.";
|
||||
reportError(context, content->GetOriginalExpression(), e.str());
|
||||
}
|
||||
propertyName = parameters.at(1);
|
||||
}
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
|
||||
target->GetName(),
|
||||
propertyName,
|
||||
content,
|
||||
dagCheckerParent);
|
||||
|
||||
if (!dagChecker.check())
|
||||
{
|
||||
dagChecker.reportError(context, content->GetOriginalExpression());
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const char *prop = target->GetProperty(propertyName.c_str());
|
||||
return prop ? prop : "";
|
||||
}
|
||||
} targetPropertyNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<bool linker, bool soname>
|
||||
struct TargetFilesystemArtifactResultCreator
|
||||
|
@ -293,7 +423,8 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
|
|||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content) const
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
// Lookup the referenced target.
|
||||
std::string name = *parameters.begin();
|
||||
|
@ -392,7 +523,18 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|||
return &targetLinkerFileDirNode;
|
||||
else if (identifier == "TARGET_SONAME_FILE_DIR")
|
||||
return &targetSoNameFileDirNode;
|
||||
else if (identifier == "STREQUAL")
|
||||
return &strEqualNode;
|
||||
else if (identifier == "BOOL")
|
||||
return &boolNode;
|
||||
else if (identifier == "ANGLE-R")
|
||||
return &angle_rNode;
|
||||
else if (identifier == "COMMA")
|
||||
return &commaNode;
|
||||
else if (identifier == "TARGET_PROPERTY")
|
||||
return &targetPropertyNode;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -412,7 +554,8 @@ std::string GeneratorExpressionContent::GetOriginalExpression() const
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string GeneratorExpressionContent::Evaluate(
|
||||
cmGeneratorExpressionContext *context) const
|
||||
cmGeneratorExpressionContext *context,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const
|
||||
{
|
||||
std::string identifier;
|
||||
{
|
||||
|
@ -422,7 +565,7 @@ std::string GeneratorExpressionContent::Evaluate(
|
|||
= this->IdentifierChildren.end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
identifier += (*it)->Evaluate(context);
|
||||
identifier += (*it)->Evaluate(context, dagChecker);
|
||||
if (context->HadError)
|
||||
{
|
||||
return std::string();
|
||||
|
@ -465,7 +608,7 @@ std::string GeneratorExpressionContent::Evaluate(
|
|||
= pit->end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
result += (*it)->Evaluate(context);
|
||||
result += (*it)->Evaluate(context, dagChecker);
|
||||
if (context->HadError)
|
||||
{
|
||||
return std::string();
|
||||
|
@ -491,7 +634,7 @@ std::string GeneratorExpressionContent::Evaluate(
|
|||
pit->end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
parameter += (*it)->Evaluate(context);
|
||||
parameter += (*it)->Evaluate(context, dagChecker);
|
||||
if (context->HadError)
|
||||
{
|
||||
return std::string();
|
||||
|
@ -534,7 +677,7 @@ std::string GeneratorExpressionContent::Evaluate(
|
|||
return std::string();
|
||||
}
|
||||
|
||||
return node->Evaluate(parameters, context, this);
|
||||
return node->Evaluate(parameters, context, this, dagChecker);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "cmListFileCache.h"
|
||||
|
||||
class cmTarget;
|
||||
class cmGeneratorTarget;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct cmGeneratorExpressionContext
|
||||
{
|
||||
|
@ -22,11 +27,13 @@ struct cmGeneratorExpressionContext
|
|||
std::set<cmTarget*> Targets;
|
||||
cmMakefile *Makefile;
|
||||
const char *Config;
|
||||
cmTarget *Target;
|
||||
cmGeneratorTarget *Target;
|
||||
bool Quiet;
|
||||
bool HadError;
|
||||
};
|
||||
|
||||
struct cmGeneratorExpressionDAGChecker;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct cmGeneratorExpressionEvaluator
|
||||
{
|
||||
|
@ -41,8 +48,8 @@ struct cmGeneratorExpressionEvaluator
|
|||
|
||||
virtual Type GetType() const = 0;
|
||||
|
||||
virtual std::string Evaluate(cmGeneratorExpressionContext *context
|
||||
) const = 0;
|
||||
virtual std::string Evaluate(cmGeneratorExpressionContext *context,
|
||||
cmGeneratorExpressionDAGChecker *) const = 0;
|
||||
|
||||
private:
|
||||
cmGeneratorExpressionEvaluator(const cmGeneratorExpressionEvaluator &);
|
||||
|
@ -57,7 +64,8 @@ struct TextContent : public cmGeneratorExpressionEvaluator
|
|||
|
||||
}
|
||||
|
||||
std::string Evaluate(cmGeneratorExpressionContext *) const
|
||||
std::string Evaluate(cmGeneratorExpressionContext *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return std::string(this->Content, this->Length);
|
||||
}
|
||||
|
@ -102,7 +110,8 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
|
|||
return cmGeneratorExpressionEvaluator::Generator;
|
||||
}
|
||||
|
||||
std::string Evaluate(cmGeneratorExpressionContext *context) const;
|
||||
std::string Evaluate(cmGeneratorExpressionContext *context,
|
||||
cmGeneratorExpressionDAGChecker *) const;
|
||||
|
||||
std::string GetOriginalExpression() const;
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -289,19 +291,40 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories()
|
|||
{
|
||||
std::vector<std::string> includes;
|
||||
const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES");
|
||||
if(prop)
|
||||
if(!prop)
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(prop, includes);
|
||||
return includes;
|
||||
}
|
||||
|
||||
const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
|
||||
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,
|
||||
&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)
|
||||
{
|
||||
if(uniqueIncludes.insert(*li).second)
|
||||
std::string inc = *li;
|
||||
if (!cmSystemTools::IsOff(inc.c_str()))
|
||||
{
|
||||
orderedAndUniqueIncludes.push_back(*li);
|
||||
cmSystemTools::ConvertToUnixSlashes(inc);
|
||||
}
|
||||
if(uniqueIncludes.insert(inc).second)
|
||||
{
|
||||
orderedAndUniqueIncludes.push_back(inc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,15 +332,30 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char *cmGeneratorTarget::GetCompileDefinitions(const char *config)
|
||||
std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
|
||||
{
|
||||
if (!config)
|
||||
std::string defPropName = "COMPILE_DEFINITIONS";
|
||||
if (config)
|
||||
{
|
||||
return this->Target->GetProperty("COMPILE_DEFINITIONS");
|
||||
defPropName += "_" + cmSystemTools::UpperCase(config);
|
||||
}
|
||||
std::string defPropName = "COMPILE_DEFINITIONS_";
|
||||
defPropName +=
|
||||
cmSystemTools::UpperCase(config);
|
||||
|
||||
return this->Target->GetProperty(defPropName.c_str());
|
||||
const char *prop = this->Target->GetProperty(defPropName.c_str());
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
defPropName, 0, 0);
|
||||
return ge.Parse(prop).Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this,
|
||||
&dagChecker);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
/** Get the include directories for this target. */
|
||||
std::vector<std::string> GetIncludeDirectories();
|
||||
|
||||
const char *GetCompileDefinitions(const char *config = 0);
|
||||
std::string GetCompileDefinitions(const char *config = 0);
|
||||
|
||||
private:
|
||||
void ClassifySources();
|
||||
|
|
|
@ -1647,16 +1647,12 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
// Add the export symbol definition for shared library objects.
|
||||
this->AppendDefines(ppDefs, exportMacro);
|
||||
}
|
||||
this->AppendDefines
|
||||
(ppDefs, this->CurrentMakefile->GetProperty("COMPILE_DEFINITIONS"));
|
||||
this->AppendDefines(ppDefs, target.GetProperty("COMPILE_DEFINITIONS"));
|
||||
cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
|
||||
this->AppendDefines(ppDefs, gtgt->GetCompileDefinitions().c_str());
|
||||
if(configName)
|
||||
{
|
||||
std::string defVarName = "COMPILE_DEFINITIONS_";
|
||||
defVarName += cmSystemTools::UpperCase(configName);
|
||||
this->AppendDefines
|
||||
(ppDefs, this->CurrentMakefile->GetProperty(defVarName.c_str()));
|
||||
this->AppendDefines(ppDefs, target.GetProperty(defVarName.c_str()));
|
||||
this->AppendDefines(ppDefs,
|
||||
gtgt->GetCompileDefinitions(configName).c_str());
|
||||
}
|
||||
buildSettings->AddAttribute
|
||||
("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
|
||||
|
@ -1713,10 +1709,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
|
||||
// Set target-specific architectures.
|
||||
std::vector<std::string> archs;
|
||||
{
|
||||
cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
|
||||
gtgt->GetAppleArchs(configName, archs);
|
||||
}
|
||||
|
||||
if(!archs.empty())
|
||||
{
|
||||
// Enable ARCHS attribute.
|
||||
|
@ -1953,7 +1947,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
BuildObjectListOrString dirs(this, this->XcodeVersion >= 30);
|
||||
BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30);
|
||||
std::vector<std::string> includes;
|
||||
cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
|
||||
this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt);
|
||||
std::set<cmStdString> emitted;
|
||||
emitted.insert("/System/Library/Frameworks");
|
||||
|
|
|
@ -55,6 +55,11 @@ bool cmIncludeDirectoryCommand
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool StartsWithGeneratorExpression(const std::string &input)
|
||||
{
|
||||
return input[0] == '$' && input[1] == '<';
|
||||
}
|
||||
|
||||
// do a lot of cleanup on the arguments because this is one place where folks
|
||||
// sometimes take the output of a program and pass it directly into this
|
||||
// command not thinking that a single argument could be filled with spaces
|
||||
|
@ -105,10 +110,13 @@ void cmIncludeDirectoryCommand::AddDirectory(const char *i,
|
|||
cmSystemTools::ConvertToUnixSlashes(ret);
|
||||
if(!cmSystemTools::FileIsFullPath(ret.c_str()))
|
||||
{
|
||||
std::string tmp = this->Makefile->GetStartDirectory();
|
||||
tmp += "/";
|
||||
tmp += ret;
|
||||
ret = tmp;
|
||||
if(!StartsWithGeneratorExpression(ret))
|
||||
{
|
||||
std::string tmp = this->Makefile->GetStartDirectory();
|
||||
tmp += "/";
|
||||
tmp += ret;
|
||||
ret = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->Makefile->AddIncludeDirectory(ret.c_str(), before);
|
||||
|
|
|
@ -1390,6 +1390,11 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
|
|||
}
|
||||
}
|
||||
|
||||
if(!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Load implicit include directories for this language.
|
||||
std::string impDirVar = "CMAKE_";
|
||||
impDirVar += lang;
|
||||
|
@ -1407,10 +1412,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
|
|||
|
||||
// Get the target-specific include directories.
|
||||
std::vector<std::string> includes;
|
||||
if(target)
|
||||
{
|
||||
includes = target->GetIncludeDirectories();
|
||||
}
|
||||
|
||||
includes = target->GetIncludeDirectories();
|
||||
|
||||
// Support putting all the in-project include directories first if
|
||||
// it is requested by the project.
|
||||
|
|
|
@ -157,6 +157,11 @@ public:
|
|||
*/
|
||||
void AppendDefines(std::set<std::string>& defines,
|
||||
const char* defines_list);
|
||||
void AppendDefines(std::set<std::string>& defines,
|
||||
std::string defines_list)
|
||||
{
|
||||
this->AppendDefines(defines, defines_list.c_str());
|
||||
}
|
||||
/**
|
||||
* Join a set of defines into a definesString with a space separator.
|
||||
*/
|
||||
|
|
|
@ -724,10 +724,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
|||
flags += targetFlags;
|
||||
}
|
||||
|
||||
std::string configUpper = cmSystemTools::UpperCase(configName);
|
||||
std::string defPropName = "COMPILE_DEFINITIONS_";
|
||||
defPropName += configUpper;
|
||||
|
||||
// Get preprocessor definitions for this directory.
|
||||
std::string defineFlags = this->Makefile->GetDefineFlags();
|
||||
Options::Tool t = Options::Compiler;
|
||||
|
@ -744,11 +740,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
|||
targetOptions.Parse(flags.c_str());
|
||||
targetOptions.Parse(defineFlags.c_str());
|
||||
targetOptions.ParseFinish();
|
||||
targetOptions.AddDefines
|
||||
(this->Makefile->GetProperty("COMPILE_DEFINITIONS"));
|
||||
targetOptions.AddDefines(target.GetProperty("COMPILE_DEFINITIONS"));
|
||||
targetOptions.AddDefines(this->Makefile->GetProperty(defPropName.c_str()));
|
||||
targetOptions.AddDefines(target.GetProperty(defPropName.c_str()));
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
targetOptions.AddDefines(gt->GetCompileDefinitions().c_str());
|
||||
targetOptions.AddDefines(gt->GetCompileDefinitions(configName).c_str());
|
||||
targetOptions.SetVerboseMakefile(
|
||||
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
|
||||
|
||||
|
@ -819,8 +814,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
|||
targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
|
||||
fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
|
||||
std::vector<std::string> includes;
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
this->GetIncludeDirectories(includes, gt);
|
||||
std::vector<std::string>::iterator i = includes.begin();
|
||||
for(;i != includes.end(); ++i)
|
||||
|
|
|
@ -1225,21 +1225,16 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
|
|||
flags += " ";
|
||||
flags += targetFlags;
|
||||
}
|
||||
std::string configUpper = cmSystemTools::UpperCase(configName);
|
||||
std::string defPropName = "COMPILE_DEFINITIONS_";
|
||||
defPropName += configUpper;
|
||||
|
||||
// Get preprocessor definitions for this directory.
|
||||
std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags();
|
||||
clOptions.FixExceptionHandlingDefault();
|
||||
clOptions.AddFlag("PrecompiledHeader", "NotUsing");
|
||||
clOptions.Parse(flags.c_str());
|
||||
clOptions.Parse(defineFlags.c_str());
|
||||
clOptions.AddDefines
|
||||
(this->Makefile->GetProperty("COMPILE_DEFINITIONS"));
|
||||
clOptions.AddDefines(this->Target->GetProperty("COMPILE_DEFINITIONS"));
|
||||
clOptions.AddDefines(this->Makefile->GetProperty(defPropName.c_str()));
|
||||
clOptions.AddDefines(this->Target->GetProperty(defPropName.c_str()));
|
||||
clOptions.AddDefines(
|
||||
this->GeneratorTarget->GetCompileDefinitions().c_str());
|
||||
clOptions.AddDefines(this->GeneratorTarget->GetCompileDefinitions(
|
||||
configName.c_str()).c_str());
|
||||
clOptions.SetVerboseMakefile(
|
||||
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
|
||||
|
||||
|
|
|
@ -27,6 +27,15 @@ enum {
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef TEST_GENERATOR_EXPRESSIONS
|
||||
#ifndef CMAKE_IS_DECLARATIVE
|
||||
#error Expect declarative definition
|
||||
#endif
|
||||
#ifdef GE_NOT_DEFINED
|
||||
#error Expect not defined generator expression
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -7,3 +7,9 @@ set_target_properties(target_prop_executable PROPERTIES COMPILE_DEFINITIONS CMAK
|
|||
|
||||
set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_REALLY="Very Fun" CMAKE_IS=Fun)
|
||||
set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_FUN CMAKE_IS_="Fun")
|
||||
|
||||
set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
|
||||
TEST_GENERATOR_EXPRESSIONS
|
||||
"$<1:CMAKE_IS_DECLARATIVE>"
|
||||
"$<0:GE_NOT_DEFINED>"
|
||||
)
|
||||
|
|
|
@ -22,6 +22,23 @@ add_custom_target(check ALL
|
|||
-Dtest_or_1=$<OR:1>
|
||||
-Dtest_or_1_0=$<OR:1,0>
|
||||
-Dtest_or_1_1=$<OR:1,1>
|
||||
-Dtest_bool_notfound=$<BOOL:NOTFOUND>
|
||||
-Dtest_bool_foo_notfound=$<BOOL:Foo-NOTFOUND>
|
||||
-Dtest_bool_true=$<BOOL:True>
|
||||
-Dtest_bool_false=$<BOOL:False>
|
||||
-Dtest_bool_on=$<BOOL:On>
|
||||
-Dtest_bool_off=$<BOOL:Off>
|
||||
-Dtest_bool_no=$<BOOL:No>
|
||||
-Dtest_bool_n=$<BOOL:N>
|
||||
-Dtest_strequal_yes_yes=$<STREQUAL:Yes,Yes>
|
||||
-Dtest_strequal_yes_yes_cs=$<STREQUAL:Yes,yes>
|
||||
-Dtest_strequal_yes_no=$<STREQUAL:Yes,No>
|
||||
-Dtest_strequal_no_yes=$<STREQUAL:No,Yes>
|
||||
-Dtest_strequal_angle_r=$<STREQUAL:$<ANGLE-R>,$<ANGLE-R>>
|
||||
-Dtest_strequal_comma=$<STREQUAL:$<COMMA>,$<COMMA>>
|
||||
-Dtest_strequal_angle_r_comma=$<STREQUAL:$<ANGLE-R>,$<COMMA>>
|
||||
-Dtest_angle_r=$<ANGLE-R>
|
||||
-Dtest_comma=$<COMMA>
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "check done"
|
||||
VERBATIM
|
||||
|
|
|
@ -23,3 +23,20 @@ check(test_or_0_1 "1")
|
|||
check(test_or_1 "1")
|
||||
check(test_or_1_0 "1")
|
||||
check(test_or_1_1 "1")
|
||||
check(test_bool_notfound "0")
|
||||
check(test_bool_foo_notfound "0")
|
||||
check(test_bool_true "1")
|
||||
check(test_bool_false "0")
|
||||
check(test_bool_on "1")
|
||||
check(test_bool_off "0")
|
||||
check(test_bool_no "0")
|
||||
check(test_bool_n "0")
|
||||
check(test_strequal_yes_yes "1")
|
||||
check(test_strequal_yes_yes_cs "0")
|
||||
check(test_strequal_yes_no "0")
|
||||
check(test_strequal_no_yes "0")
|
||||
check(test_strequal_angle_r "1")
|
||||
check(test_strequal_comma "1")
|
||||
check(test_strequal_angle_r_comma "0")
|
||||
check(test_angle_r ">")
|
||||
check(test_comma ",")
|
||||
|
|
|
@ -12,13 +12,21 @@ create_header(bar)
|
|||
create_header(bat)
|
||||
create_header(foo)
|
||||
create_header(baz)
|
||||
create_header(bang)
|
||||
create_header(bing)
|
||||
create_header(bung)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/bar")
|
||||
include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/bang>")
|
||||
|
||||
add_executable(TargetIncludeDirectories main.cpp)
|
||||
set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bat")
|
||||
set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foo")
|
||||
set_property(TARGET TargetIncludeDirectories APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES "$<1:${CMAKE_CURRENT_BINARY_DIR}/bing>")
|
||||
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/baz")
|
||||
include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/bung>")
|
||||
include_directories("sing$<1:/ting>")
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#include "bat.h"
|
||||
#include "foo.h"
|
||||
#include "baz.h"
|
||||
#include "bang.h"
|
||||
#include "bing.h"
|
||||
#include "bung.h"
|
||||
#include "ting.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
//ting.h
|
|
@ -46,6 +46,7 @@ macro(add_RunCMake_test test)
|
|||
endmacro()
|
||||
|
||||
add_RunCMake_test(GeneratorExpression)
|
||||
add_RunCMake_test(TargetPropertyGeneratorExpressions)
|
||||
add_RunCMake_test(Languages)
|
||||
add_RunCMake_test(ObjectLibrary)
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>
|
||||
|
||||
Self reference on target "TargetPropertyGeneratorExpressions".$
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"int main(int, char **) { return 0; }\n")
|
||||
|
||||
add_executable(TargetPropertyGeneratorExpressions
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
include_directories("$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>
|
||||
|
||||
Self reference on target "TargetPropertyGeneratorExpressions".$
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"int main(int, char **) { return 0; }\n")
|
||||
|
||||
add_executable(TargetPropertyGeneratorExpressions
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
set_property(TARGET TargetPropertyGeneratorExpressions PROPERTY
|
||||
INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>"
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,INCLUDE_DIRECTORIES>
|
||||
|
||||
Self reference on target "TargetPropertyGeneratorExpressions".$
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"int main(int, char **) { return 0; }\n")
|
||||
|
||||
add_executable(TargetPropertyGeneratorExpressions
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
include_directories(
|
||||
"$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,INCLUDE_DIRECTORIES>")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,INCLUDE_DIRECTORIES>
|
||||
|
||||
Self reference on target "TargetPropertyGeneratorExpressions".$
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"int main(int, char **) { return 0; }\n")
|
||||
|
||||
add_executable(TargetPropertyGeneratorExpressions
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
set_property(TARGET TargetPropertyGeneratorExpressions PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
"$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,INCLUDE_DIRECTORIES>"
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_PROPERTY:COMPILE_DEFINITIONS>
|
||||
|
||||
Self reference on target "TargetPropertyGeneratorExpressions".$
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"int main(int, char **) { return 0; }\n")
|
||||
|
||||
add_executable(TargetPropertyGeneratorExpressions
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
set_property(TARGET TargetPropertyGeneratorExpressions
|
||||
PROPERTY
|
||||
COMPILE_DEFINITIONS "$<TARGET_PROPERTY:COMPILE_DEFINITIONS>"
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,COMPILE_DEFINITIONS>
|
||||
|
||||
Self reference on target "TargetPropertyGeneratorExpressions".$
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"int main(int, char **) { return 0; }\n")
|
||||
|
||||
add_executable(TargetPropertyGeneratorExpressions
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
set_property(TARGET TargetPropertyGeneratorExpressions PROPERTY
|
||||
COMPILE_DEFINITIONS
|
||||
"$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,COMPILE_DEFINITIONS>"
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(${RunCMake_TEST} CXX)
|
||||
|
||||
# MSVC creates extra targets which pollute the stderr unless we set this.
|
||||
set(CMAKE_SUPPRESS_REGENERATION TRUE)
|
||||
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,8 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(BadSelfReference1)
|
||||
run_cmake(BadSelfReference2)
|
||||
run_cmake(BadSelfReference3)
|
||||
run_cmake(BadSelfReference4)
|
||||
run_cmake(BadSelfReference5)
|
||||
run_cmake(BadSelfReference6)
|
Loading…
Reference in New Issue