mirror of
https://github.com/reactos/CMake.git
synced 2024-11-24 12:09:48 +00:00
98093c45db
Transitively consume the property from linked dependents. Implement configuration-specific support by following the pattern set out for compile definitions and includes in cmQtAutoGenerators. Implement support for origin-tracking with CMAKE_DEBUG_TARGET_PROPERTIES. This is motivated by the needs of KDE, which provides a separate translation system based on gettext instead of the Qt linguist translation system. The Qt uic tool provides command line options for configuring the method used to translate text, and to add an include directive to the generated file to provide the method. http://thread.gmane.org/gmane.comp.kde.devel.frameworks/7930/focus=7992 Implement the interface to provide the uic options as a usage-requirement on the KI18n target, as designed for KDE.
221 lines
7.0 KiB
C++
221 lines
7.0 KiB
C++
/*============================================================================
|
|
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), TransitivePropertiesOnly(false)
|
|
{
|
|
const cmGeneratorExpressionDAGChecker *top = this;
|
|
const cmGeneratorExpressionDAGChecker *p = this->Parent;
|
|
while (p)
|
|
{
|
|
top = p;
|
|
p = p->Parent;
|
|
}
|
|
this->CheckResult = this->checkGraph();
|
|
|
|
#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) \
|
|
top->METHOD () ||
|
|
|
|
if (CheckResult == DAG && (
|
|
CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(TEST_TRANSITIVE_PROPERTY_METHOD)
|
|
false)
|
|
)
|
|
{
|
|
std::map<cmStdString, std::set<cmStdString> >::const_iterator it
|
|
= top->Seen.find(target);
|
|
if (it != top->Seen.end())
|
|
{
|
|
const std::set<cmStdString> &propSet = it->second;
|
|
const std::set<cmStdString>::const_iterator i = propSet.find(property);
|
|
if (i != propSet.end())
|
|
{
|
|
this->CheckResult = ALREADY_SEEN;
|
|
return;
|
|
}
|
|
}
|
|
const_cast<cmGeneratorExpressionDAGChecker *>(top)
|
|
->Seen[target].insert(property);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmGeneratorExpressionDAGChecker::Result
|
|
cmGeneratorExpressionDAGChecker::check() const
|
|
{
|
|
return this->CheckResult;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmGeneratorExpressionDAGChecker::reportError(
|
|
cmGeneratorExpressionContext *context,
|
|
const std::string &expr)
|
|
{
|
|
if (this->CheckResult == DAG)
|
|
{
|
|
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->HeadTarget->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;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmGeneratorExpressionDAGChecker::Result
|
|
cmGeneratorExpressionDAGChecker::checkGraph() const
|
|
{
|
|
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
|
while (parent)
|
|
{
|
|
if (this->Target == parent->Target && this->Property == parent->Property)
|
|
{
|
|
return (parent == this->Parent) ? SELF_REFERENCE : CYCLIC_REFERENCE;
|
|
}
|
|
parent = parent->Parent;
|
|
}
|
|
return DAG;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly()
|
|
{
|
|
const cmGeneratorExpressionDAGChecker *top = this;
|
|
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
|
while (parent)
|
|
{
|
|
top = parent;
|
|
parent = parent->Parent;
|
|
}
|
|
|
|
return top->TransitivePropertiesOnly;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt)
|
|
{
|
|
const cmGeneratorExpressionDAGChecker *top = this;
|
|
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
|
while (parent)
|
|
{
|
|
top = parent;
|
|
parent = parent->Parent;
|
|
}
|
|
|
|
const char *prop = top->Property.c_str();
|
|
|
|
if (tgt)
|
|
{
|
|
return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0;
|
|
}
|
|
|
|
return (strcmp(prop, "LINK_LIBRARIES") == 0
|
|
|| strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
|
|
|| strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
|
|
|| cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_")
|
|
|| cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_"))
|
|
|| strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() const
|
|
{
|
|
const char *prop = this->Property.c_str();
|
|
return (strcmp(prop, "INCLUDE_DIRECTORIES") == 0
|
|
|| strcmp(prop, "INTERFACE_INCLUDE_DIRECTORIES") == 0 );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
cmGeneratorExpressionDAGChecker::EvaluatingSystemIncludeDirectories() const
|
|
{
|
|
const char *prop = this->Property.c_str();
|
|
return strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const
|
|
{
|
|
const char *prop = this->Property.c_str();
|
|
return (strcmp(prop, "COMPILE_DEFINITIONS") == 0
|
|
|| strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0
|
|
|| cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_"));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmGeneratorExpressionDAGChecker::EvaluatingCompileOptions() const
|
|
{
|
|
const char *prop = this->Property.c_str();
|
|
return (strcmp(prop, "COMPILE_OPTIONS") == 0
|
|
|| strcmp(prop, "INTERFACE_COMPILE_OPTIONS") == 0 );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmGeneratorExpressionDAGChecker::EvaluatingAutoUicOptions() const
|
|
{
|
|
const char *prop = this->Property.c_str();
|
|
return (strcmp(prop, "AUTOUIC_OPTIONS") == 0
|
|
|| strcmp(prop, "INTERFACE_AUTOUIC_OPTIONS") == 0 );
|
|
}
|