Commit 13c2c406 authored by Daniel Teske's avatar Daniel Teske

Cmake: Read the build.ninja file only once

The first getCmakeCXXFlags that reads the build.ninja file
stores the contents in the inout parameter cachedBuildNinja.
Further calls to getCMakeCXXFlags just use this cached value.

This prevents excessive locking of this file while constructing
the code model information.

Change-Id: I81e1431194bed6913c69abb2d954068c999a5c1b
Task-number: QTCREATORBUG-14639
Reviewed-by: Tom Tanner
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent 42d86726
......@@ -177,7 +177,7 @@ void CMakeProject::changeBuildDirectory(CMakeBuildConfiguration *bc, const QStri
parseCMakeLists();
}
QStringList CMakeProject::getCXXFlagsFor(const CMakeBuildTarget &buildTarget)
QStringList CMakeProject::getCXXFlagsFor(const CMakeBuildTarget &buildTarget, QByteArray *cachedBuildNinja)
{
QString makeCommand = QDir::fromNativeSeparators(buildTarget.makeCommand);
int startIndex = makeCommand.indexOf(QLatin1Char('\"'));
......@@ -206,32 +206,43 @@ QStringList CMakeProject::getCXXFlagsFor(const CMakeBuildTarget &buildTarget)
// found
// Get "all" target's working directory
if (!buildTargets().empty()) {
QString buildNinjaFile = QDir::fromNativeSeparators(buildTargets().at(0).workingDirectory);
buildNinjaFile += QLatin1String("/build.ninja");
QFile buildNinja(buildNinjaFile);
if (buildNinja.exists()) {
buildNinja.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream stream(&buildNinja);
bool targetFound = false;
bool cxxFound = false;
QString targetSearchPattern = QString::fromLatin1("target %1").arg(buildTarget.title);
if (cachedBuildNinja->isNull()) {
QString buildNinjaFile = QDir::fromNativeSeparators(buildTargets().at(0).workingDirectory);
buildNinjaFile += QLatin1String("/build.ninja");
QFile buildNinja(buildNinjaFile);
if (buildNinja.exists()) {
buildNinja.open(QIODevice::ReadOnly | QIODevice::Text);
*cachedBuildNinja = buildNinja.readAll();
buildNinja.close();
} else {
*cachedBuildNinja = QByteArray();
}
}
while (!stream.atEnd()) {
// 1. Look for a block that refers to the current target
// 2. Look for a build rule which invokes CXX_COMPILER
// 3. Return the FLAGS definition
QString line = stream.readLine().trimmed();
if (line.startsWith(QLatin1String("#"))) {
if (!line.startsWith(QLatin1String("# Object build statements for"))) continue;
targetFound = line.endsWith(targetSearchPattern);
} else if (targetFound && line.startsWith(QLatin1String("build"))) {
cxxFound = line.indexOf(QLatin1String("CXX_COMPILER")) != -1;
} else if (cxxFound && line.startsWith(QLatin1String("FLAGS ="))) {
// Skip past =
return line.mid(7).trimmed().split(QLatin1Char(' '), QString::SkipEmptyParts);
}
if (cachedBuildNinja->isEmpty())
return QStringList();
QTextStream stream(cachedBuildNinja);
bool targetFound = false;
bool cxxFound = false;
QString targetSearchPattern = QString::fromLatin1("target %1").arg(buildTarget.title);
while (!stream.atEnd()) {
// 1. Look for a block that refers to the current target
// 2. Look for a build rule which invokes CXX_COMPILER
// 3. Return the FLAGS definition
QString line = stream.readLine().trimmed();
if (line.startsWith(QLatin1String("#"))) {
if (!line.startsWith(QLatin1String("# Object build statements for"))) continue;
targetFound = line.endsWith(targetSearchPattern);
} else if (targetFound && line.startsWith(QLatin1String("build"))) {
cxxFound = line.indexOf(QLatin1String("CXX_COMPILER")) != -1;
} else if (cxxFound && line.startsWith(QLatin1String("FLAGS ="))) {
// Skip past =
return line.mid(7).trimmed().split(QLatin1Char(' '), QString::SkipEmptyParts);
}
}
}
return QStringList();
}
......@@ -338,13 +349,15 @@ bool CMakeProject::parseCMakeLists()
ppBuilder.setQtVersion(activeQtVersion);
QByteArray cachedBuildNinja;
foreach (const CMakeBuildTarget &cbt, m_buildTargets) {
// This explicitly adds -I. to the include paths
QStringList includePaths = cbt.includeFiles;
includePaths += projectDirectory().toString();
ppBuilder.setIncludePaths(includePaths);
ppBuilder.setCFlags(getCXXFlagsFor(cbt));
ppBuilder.setCxxFlags(getCXXFlagsFor(cbt));
QStringList cxxflags = getCXXFlagsFor(cbt, &cachedBuildNinja);
ppBuilder.setCFlags(cxxflags);
ppBuilder.setCxxFlags(cxxflags);
ppBuilder.setDefines(cbt.defines);
ppBuilder.setDisplayName(cbt.title);
......
......@@ -139,7 +139,7 @@ private:
QString uiHeaderFile(const QString &uiFile);
void updateRunConfigurations(ProjectExplorer::Target *t);
void updateApplicationAndDeploymentTargets();
QStringList getCXXFlagsFor(const CMakeBuildTarget &buildTarget);
QStringList getCXXFlagsFor(const CMakeBuildTarget &buildTarget, QByteArray *cachedBuildNinja);
Internal::CMakeManager *m_manager;
ProjectExplorer::Target *m_activeTarget;
......
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