Commit 7688754b authored by Sergey Shambir's avatar Sergey Shambir Committed by hjk

Autotools: added parsing defines and C/C++ flags from Makefile

Change-Id: I7443ba3ada97e4abac5560bb5399ec96e065acee
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent d07d6836
......@@ -411,7 +411,10 @@ void AutotoolsProject::updateCppCodeModel()
if (!modelManager)
return;
const QStringList cxxflags; // FIXME: Autotools should be able to do better than this!
const QStringList cflags = m_makefileParserThread->cflags();
QStringList cxxflags = m_makefileParserThread->cxxflags();
if (cxxflags.isEmpty())
cxxflags = cflags;
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this);
pinfo.clearProjectParts();
......@@ -420,7 +423,7 @@ void AutotoolsProject::updateCppCodeModel()
if (activeTarget()) {
ProjectExplorer::Kit *k = activeTarget()->kit();
ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k);
part->evaluateToolchain(tc, cxxflags, cxxflags,
part->evaluateToolchain(tc, cxxflags, cflags,
SysRootKitInformation::sysRoot(k));
}
......@@ -428,6 +431,7 @@ void AutotoolsProject::updateCppCodeModel()
part->files << CppTools::ProjectFile(file, CppTools::ProjectFile::CXXSource);
part->includePaths += m_makefileParserThread->includePaths();
part->defines += m_makefileParserThread->defines();
pinfo.appendProjectPart(part);
modelManager->updateProjectInfo(pinfo);
......
......@@ -123,6 +123,21 @@ QStringList MakefileParser::includePaths() const
return m_includePaths;
}
QByteArray MakefileParser::defines() const
{
return m_defines;
}
QStringList MakefileParser::cflags() const
{
return m_cflags;
}
QStringList MakefileParser::cxxflags() const
{
return m_cxxflags;
}
void MakefileParser::cancel()
{
QMutexLocker locker(&m_mutex);
......@@ -424,6 +439,59 @@ QString MakefileParser::parseIdentifierBeforeAssign(const QString &line)
return (end < line.size() && line[end] == QLatin1Char('=')) ? ret : QString();
}
QStringList MakefileParser::parseTermsAfterAssign(const QString &line)
{
int assignPos = line.indexOf(QLatin1Char('=')) + 1;
if (assignPos >= line.size())
return QStringList();
return line.mid(assignPos).split(QLatin1Char(' '), QString::SkipEmptyParts);
}
bool MakefileParser::maybeParseDefine(const QString &term)
{
if (term.startsWith(QLatin1String("-D"))) {
QString def = term.mid(2); // remove the "-D"
QByteArray data = def.toUtf8();
int pos = data.indexOf('=');
if (pos >= 0)
data[pos] = ' ';
m_defines += (QByteArray("#define ") + data + '\n');
return true;
}
return false;
}
bool MakefileParser::maybeParseInclude(const QString &term, const QString &dirName)
{
if (term.startsWith(QLatin1String("-I"))) {
QString includePath = term.mid(2); // remove the "-I"
if (includePath == QLatin1String("."))
includePath = dirName;
if (!includePath.isEmpty())
m_includePaths += includePath;
return true;
}
return false;
}
bool MakefileParser::maybeParseCFlag(const QString &term)
{
if (term.startsWith(QLatin1Char('-'))) {
m_cflags += term;
return true;
}
return false;
}
bool MakefileParser::maybeParseCXXFlag(const QString &term)
{
if (term.startsWith(QLatin1Char('-'))) {
m_cxxflags += term;
return true;
}
return false;
}
void MakefileParser::addAllSources()
{
QStringList extensions;
......@@ -446,25 +514,37 @@ void MakefileParser::parseIncludePaths()
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
// TODO: The parsing is done very poor. Comments are ignored and targets
// are ignored too. Whether it is worth to improve this, depends on whether
// TODO: Targets are ignored at this moment.
// Whether it is worth to improve this, depends on whether
// we want to parse the generated Makefile at all or whether we want to
// improve the Makefile.am parsing to be aware of variables.
QTextStream textStream(&file);
QString line;
do {
line = textStream.readLine();
QStringList terms = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
foreach (const QString &term, terms) {
if (term.startsWith(QLatin1String("-I"))) {
QString includePath = term.right(term.length() - 2); // remove the "-I"
if (includePath == QLatin1String("."))
includePath = dirName;
if (!includePath.isEmpty())
m_includePaths += includePath;
}
const QString varName = parseIdentifierBeforeAssign(line);
if (varName.isEmpty())
continue;
if (varName == QLatin1String("DEFS")) {
foreach (const QString &term, parseTermsAfterAssign(line))
maybeParseDefine(term);
} else if (varName.endsWith(QLatin1String("INCLUDES"))) {
foreach (const QString &term, parseTermsAfterAssign(line))
maybeParseInclude(term, dirName);
} else if (varName.endsWith(QLatin1String("CFLAGS"))) {
foreach (const QString &term, parseTermsAfterAssign(line))
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|| maybeParseCFlag(term);
} else if (varName.endsWith(QLatin1String("CPPFLAGS"))
|| varName.endsWith(QLatin1String("CXXFLAGS"))) {
foreach (const QString &term, parseTermsAfterAssign(line))
maybeParseDefine(term) || maybeParseInclude(term, dirName)
|| maybeParseCXXFlag(term);
}
} while (!line.isNull());
m_includePaths.removeDuplicates();
m_cflags.removeDuplicates();
m_cxxflags.removeDuplicates();
}
......@@ -96,6 +96,25 @@ public:
*/
QStringList includePaths() const;
/**
* @return Concatenated normalized defines, just like in code:
* @code
* #define X12_DEPRECATED __attribute__((deprecated))
* #define X12_HAS_DEPRECATED
* @endcode
*/
QByteArray defines() const;
/**
* @return List of compiler flags for C.
*/
QStringList cflags() const;
/**
* @return List of compiler flags for C++.
*/
QStringList cxxflags() const;
/**
* Cancels the parsing. Calling this method only makes sense, if the
* parser runs in a different thread than the caller of this method.
......@@ -211,6 +230,33 @@ private:
*/
static QString parseIdentifierBeforeAssign(const QString &line);
/**
* Parses list of space-separated terms after "="
*/
static QStringList parseTermsAfterAssign(const QString &line);
/**
* If term is compiler flag -D<macro>, adds macro to defines and returns true.
*/
bool maybeParseDefine(const QString &term);
/**
* If term is compiler flag -I<path>, adds path to includes and returns true.
* @param term Term itself
* @param dirName Directory where Makefile placed
*/
bool maybeParseInclude(const QString &term, const QString &dirName);
/**
* If term is compiler flag -<flag>, adds it to cflags and returns true.
*/
bool maybeParseCFlag(const QString &term);
/**
* If term is compiler flag -<flag>, adds it to cxxflags and returns true.
*/
bool maybeParseCXXFlag(const QString &term);
private:
bool m_success; ///< Return value for MakefileParser::parse().
......@@ -222,6 +268,9 @@ private:
QStringList m_sources; ///< Return value for MakefileParser::sources()
QStringList m_makefiles; ///< Return value for MakefileParser::makefiles()
QStringList m_includePaths; ///< Return value for MakefileParser::includePaths()
QByteArray m_defines; ///< Return value for MakefileParser::defines()
QStringList m_cflags; ///< Return value for MakefileParser::cflags()
QStringList m_cxxflags; ///< Return value for MakefileParser::cxxflags()
QString m_line; ///< Current line of the makefile
QTextStream m_textStream; ///< Textstream that represents the makefile
......
......@@ -72,6 +72,24 @@ QStringList MakefileParserThread::includePaths() const
return m_includePaths;
}
QByteArray MakefileParserThread::defines() const
{
QMutexLocker locker(&m_mutex);
return m_defines;
}
QStringList MakefileParserThread::cflags() const
{
QMutexLocker locker(&m_mutex);
return m_cflags;
}
QStringList MakefileParserThread::cxxflags() const
{
QMutexLocker locker(&m_mutex);
return m_cxxflags;
}
bool MakefileParserThread::hasError() const
{
QMutexLocker locker(&m_mutex);
......@@ -102,4 +120,7 @@ void MakefileParserThread::run()
m_sources = m_parser.sources();
m_makefiles = m_parser.makefiles();
m_includePaths = m_parser.includePaths();
m_defines = m_parser.defines();
m_cflags = m_parser.cflags();
m_cxxflags = m_parser.cxxflags();
}
......@@ -86,6 +86,24 @@ public:
*/
QStringList includePaths() const;
/**
* @return Concatenated defines. Should be invoked, after the signal
* finished() has been emitted.
*/
QByteArray defines() const;
/**
* @return List of compiler flags for C. Should be invoked, after the signal
* finished() has been emitted.
*/
QStringList cflags() const;
/**
* @return List of compiler flags for C++. Should be invoked, after the
* signal finished() has been emitted.
*/
QStringList cxxflags() const;
/**
* @return True, if an error occurred during the parsing. Should be invoked,
* after the signal finished() has been emitted.
......@@ -122,6 +140,9 @@ private:
QStringList m_sources; ///< Return value for MakefileParserThread::sources()
QStringList m_makefiles; ///< Return value for MakefileParserThread::makefiles()
QStringList m_includePaths; ///< Return value for MakefileParserThread::includePaths()
QByteArray m_defines; ///< Return value for MakefileParserThread::defines()
QStringList m_cflags; ///< Return value for MakefileParserThread::cflags()
QStringList m_cxxflags; ///< Return value for MakefileParserThread::cxxflags()
};
} // namespace Internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment