QmakePM: Improve performance of import

Shuffle order of parse and add short cuts in case we can
stop parsing early.

Change-Id: If03a5cbc0e51dc77f4b03b1cf1d07243f5b2a70b
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Christian Stenger
2023-09-27 16:20:18 +02:00
parent 5a2df08ae0
commit cf6b6b5a8a
3 changed files with 25 additions and 10 deletions

View File

@@ -25,7 +25,13 @@ static QString findQMakeLine(const FilePath &makefile, const QString &key)
{ {
QFile fi(makefile.toString()); QFile fi(makefile.toString());
if (fi.exists() && fi.open(QFile::ReadOnly)) { if (fi.exists() && fi.open(QFile::ReadOnly)) {
static const QString cmakeLine("# CMAKE generated file: DO NOT EDIT!");
QTextStream ts(&fi); QTextStream ts(&fi);
if (!ts.atEnd()) {
if (ts.readLine() == cmakeLine)
return {};
ts.seek(0);
}
while (!ts.atEnd()) { while (!ts.atEnd()) {
const QString line = ts.readLine(); const QString line = ts.readLine();
if (line.startsWith(key)) if (line.startsWith(key))
@@ -48,7 +54,7 @@ void MakeFileParse::parseArgs(const QString &args, const QString &project,
QList<QMakeAssignment> *assignments, QList<QMakeAssignment> *assignments,
QList<QMakeAssignment> *afterAssignments) QList<QMakeAssignment> *afterAssignments)
{ {
const QRegularExpression regExp(QLatin1String("^([^\\s\\+-]*)\\s*(\\+=|=|-=|~=)(.*)$")); static const QRegularExpression regExp(QLatin1String("^([^\\s\\+-]*)\\s*(\\+=|=|-=|~=)(.*)$"));
bool after = false; bool after = false;
bool ignoreNext = false; bool ignoreNext = false;
m_unparsedArguments = args; m_unparsedArguments = args;
@@ -207,7 +213,7 @@ static FilePath findQMakeBinaryFromMakefile(const FilePath &makefile)
QFile fi(makefile.toString()); QFile fi(makefile.toString());
if (fi.exists() && fi.open(QFile::ReadOnly)) { if (fi.exists() && fi.open(QFile::ReadOnly)) {
QTextStream ts(&fi); QTextStream ts(&fi);
const QRegularExpression r1(QLatin1String("^QMAKE\\s*=(.*)$")); static const QRegularExpression r1(QLatin1String("^QMAKE\\s*=(.*)$"));
while (!ts.atEnd()) { while (!ts.atEnd()) {
QString line = ts.readLine(); QString line = ts.readLine();
const QRegularExpressionMatch match = r1.match(line); const QRegularExpressionMatch match = r1.match(line);
@@ -228,7 +234,9 @@ static FilePath findQMakeBinaryFromMakefile(const FilePath &makefile)
return {}; return {};
} }
MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode) : m_mode(mode) MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode,
std::optional<FilePath> projectPath)
: m_mode(mode)
{ {
qCDebug(logging()) << "Parsing makefile" << makefile; qCDebug(logging()) << "Parsing makefile" << makefile;
if (!makefile.exists()) { if (!makefile.exists()) {
@@ -237,10 +245,6 @@ MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode) : m_mode(mode)
return; return;
} }
// Qt Version!
m_qmakePath = findQMakeBinaryFromMakefile(makefile);
qCDebug(logging()) << " qmake:" << m_qmakePath;
QString project = findQMakeLine(makefile, QLatin1String("# Project:")).trimmed(); QString project = findQMakeLine(makefile, QLatin1String("# Project:")).trimmed();
if (project.isEmpty()) { if (project.isEmpty()) {
m_state = CouldNotParse; m_state = CouldNotParse;
@@ -254,6 +258,14 @@ MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode) : m_mode(mode)
// Src Pro file // Src Pro file
m_srcProFile = makefile.parentDir().resolvePath(project); m_srcProFile = makefile.parentDir().resolvePath(project);
qCDebug(logging()) << " source .pro file:" << m_srcProFile; qCDebug(logging()) << " source .pro file:" << m_srcProFile;
if (projectPath && m_srcProFile != *projectPath) { // shortcut when importing
m_state = Okay;
return;
}
// Qt Version!
m_qmakePath = findQMakeBinaryFromMakefile(makefile);
qCDebug(logging()) << " qmake:" << m_qmakePath;
QString command = findQMakeLine(makefile, QLatin1String("# Command:")).trimmed(); QString command = findQMakeLine(makefile, QLatin1String("# Command:")).trimmed();
if (command.isEmpty()) { if (command.isEmpty()) {

View File

@@ -7,6 +7,8 @@
#include <qtsupport/baseqtversion.h> #include <qtsupport/baseqtversion.h>
#include <utils/filepath.h> #include <utils/filepath.h>
#include <optional>
namespace QmakeProjectManager { namespace QmakeProjectManager {
namespace Internal { namespace Internal {
@@ -21,7 +23,8 @@ class MakeFileParse
{ {
public: public:
enum class Mode { FilterKnownConfigValues, DoNotFilterKnownConfigValues }; enum class Mode { FilterKnownConfigValues, DoNotFilterKnownConfigValues };
MakeFileParse(const Utils::FilePath &makefile, Mode mode); MakeFileParse(const Utils::FilePath &makefile, Mode mode,
std::optional<Utils::FilePath> projectFile = std::nullopt);
enum MakefileState { MakefileMissing, CouldNotParse, Okay }; enum MakefileState { MakefileMissing, CouldNotParse, Okay };

View File

@@ -97,7 +97,7 @@ QList<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath,
qCDebug(logs) << " Parsing makefile" << file; qCDebug(logs) << " Parsing makefile" << file;
// find interesting makefiles // find interesting makefiles
const FilePath makefile = importPath / file; const FilePath makefile = importPath / file;
MakeFileParse parse(makefile, MakeFileParse::Mode::FilterKnownConfigValues); MakeFileParse parse(makefile, MakeFileParse::Mode::FilterKnownConfigValues, projectFilePath());
if (parse.makeFileState() != MakeFileParse::Okay) { if (parse.makeFileState() != MakeFileParse::Okay) {
qCDebug(logs) << " Parsing the makefile failed" << makefile; qCDebug(logs) << " Parsing the makefile failed" << makefile;
continue; continue;
@@ -108,7 +108,7 @@ QList<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath,
} }
data->canonicalQmakeBinary = parse.qmakePath().canonicalPath(); data->canonicalQmakeBinary = parse.qmakePath().canonicalPath();
if (data->canonicalQmakeBinary.isEmpty()) { if (!data->canonicalQmakeBinary.exists()) {
qCDebug(logs) << " " << parse.qmakePath() << "doesn't exist anymore"; qCDebug(logs) << " " << parse.qmakePath() << "doesn't exist anymore";
continue; continue;
} }