aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2016-10-25 21:25:25 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2016-11-01 17:37:17 +0000
commit5f17c280ec2f077670b82cfd9d255449ceedee7e (patch)
treecf1e993681284c6c690d6a3b73b9ff5cf1de37e0
parent4a59a7d714bdfdf54e279d6dc8de11383fff7ccd (diff)
de-duplicate INSTALLS resolution
don't resolve the source files once for deployment and once for the project tree. Change-Id: Ifddf8fc7883bf025d3640de0d6676b5930991088 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.cpp78
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.h16
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp6
-rw-r--r--src/shared/proparser/profileevaluator.cpp35
-rw-r--r--src/shared/proparser/profileevaluator.h4
5 files changed, 70 insertions, 69 deletions
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
index 9f20ebeead4..e802968c9ab 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -660,24 +660,22 @@ void QmakePriFileNode::extractSources(
}
}
-void QmakePriFileNode::extractValues(
- const EvalInput &input, ProFile *proFile, PriFileEvalResult &result)
-{
- // Figure out DEPLOYMENT and INSTALL folders.
- // Ignore stuff from cumulative parse, as we are recursively enumerating
- // all the files from those folders and add watchers for them. That's too
- // dangerous if we get the folders wrong and enumerate the whole project
- // tree multiple times.
- QStringList dynamicVariables = dynamicVarNames(input.readerExact);
- foreach (const QString &dynamicVar, dynamicVariables)
- result.folders += input.readerExact->values(dynamicVar, proFile);
-
- for (int i=0; i < result.folders.size(); ++i) {
- const QFileInfo fi(result.folders.at(i));
- if (fi.isRelative())
- result.folders[i] = QDir::cleanPath(input.projectDir + QLatin1Char('/') + result.folders.at(i));
+void QmakePriFileNode::extractInstalls(
+ QHash<const ProFile *, PriFileEvalResult *> proToResult, PriFileEvalResult *fallback,
+ const InstallsList &installList)
+{
+ for (const InstallsItem &item : installList.items) {
+ for (const ProFileEvaluator::SourceFile &source : item.files) {
+ auto *result = proToResult.value(source.proFile);
+ if (!result)
+ result = fallback;
+ result->folders << source.fileName;
+ }
}
+}
+void QmakePriFileNode::processValues(PriFileEvalResult &result)
+{
result.folders.removeDuplicates();
// Remove non existing items and non folders
@@ -1456,19 +1454,6 @@ QStringList QmakePriFileNode::varNamesForRemoving()
return vars;
}
-QStringList QmakePriFileNode::dynamicVarNames(QtSupport::ProFileReader *reader)
-{
- QStringList result;
-
- // Figure out INSTALLS (and DEPLOYMENT, as it's aliased)
- const QString installs = QLatin1String("INSTALLS");
- const QString files = QLatin1String(".files");
- foreach (const QString &var, reader->values(installs))
- result << (var + files);
- result.removeDuplicates();
- return result;
-}
-
QSet<FileName> QmakePriFileNode::filterFilesProVariables(FileType fileType, const QSet<FileName> &files)
{
if (fileType != QMLType && fileType != UnknownFileType)
@@ -1952,11 +1937,18 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
}
}
+ // This is used for two things:
+ // - Actual deployment, in which case we need exact values.
+ // - The project tree, in which case we also want exact values to avoid recursively
+ // watching bogus paths. However, we accept the values even if the evaluation
+ // failed, to at least have a best-effort result.
+ result->installsList = installsList(exactBuildPassReader, input.projectFilePath.toString(),
+ input.projectDir, input.buildDirectory);
+ extractInstalls(proToResult, &result->includedFiles.result, result->installsList);
+
if (result->state == EvalResult::EvalOk) {
result->targetInformation = targetInformation(input.readerExact, exactBuildPassReader,
input.buildDirectory, input.projectFilePath.toString());
- result->installsList = installsList(exactBuildPassReader, input.projectFilePath.toString(),
- input.projectDir, input.buildDirectory);
// update other variables
result->newVarValues[DefinesVar] = exactReader->values(QLatin1String("DEFINES"));
@@ -1977,8 +1969,8 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
result->newVarValues[ExactResourceVar] = fileListForVar(exactSourceFiles, QLatin1String("RESOURCES"));
result->newVarValues[CumulativeResourceVar] = fileListForVar(cumulativeSourceFiles, QLatin1String("RESOURCES"));
result->newVarValues[PkgConfigVar] = exactReader->values(QLatin1String("PKGCONFIG"));
- result->newVarValues[PrecompiledHeaderVar] = exactReader->fixifiedValues(
- QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory);
+ result->newVarValues[PrecompiledHeaderVar] = ProFileEvaluator::sourcesToFiles(exactReader->fixifiedValues(
+ QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory));
result->newVarValues[LibDirectoriesVar] = libDirectories(exactReader);
result->newVarValues[ConfigVar] = exactReader->values(QLatin1String("CONFIG"));
result->newVarValues[QmlImportPathVar] = exactReader->absolutePathValues(
@@ -2007,11 +1999,10 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
if (result->state == EvalResult::EvalOk || result->state == EvalResult::EvalPartial) {
- // extract values for each .pri file and add it to IncludedPriFiles structure
QList<IncludedPriFile *> toExtract = { &result->includedFiles };
while (!toExtract.isEmpty()) {
IncludedPriFile *current = toExtract.takeFirst();
- extractValues(input, current->proFile, current->result);
+ processValues(current->result);
toExtract.append(current->children.values());
}
}
@@ -2295,8 +2286,10 @@ QStringList QmakeProFileNode::includePaths(QtSupport::ProFileReader *reader, con
paths.append(cxxflags.mid(2));
}
- foreach (const QString &el, reader->fixifiedValues(QLatin1String("INCLUDEPATH"), projectDir, buildDir))
- paths << sysrootify(el, sysroot, projectDir, buildDir);
+ foreach (const ProFileEvaluator::SourceFile &el,
+ reader->fixifiedValues(QLatin1String("INCLUDEPATH"), projectDir, buildDir)) {
+ paths << sysrootify(el.fileName, sysroot, projectDir, buildDir);
+ }
// paths already contains moc dir and ui dir, due to corrrectly parsing uic.prf and moc.prf
// except if those directories don't exist at the time of parsing
// thus we add those directories manually (without checking for existence)
@@ -2411,8 +2404,8 @@ InstallsList QmakeProFileNode::installsList(const QtSupport::ProFileReader *read
return result;
const QStringList &itemList = reader->values(QLatin1String("INSTALLS"));
foreach (const QString &item, itemList) {
- if (reader->values(item + QLatin1String(".CONFIG")).contains(QLatin1String("no_default_install")))
- continue;
+ bool active = !reader->values(item + QLatin1String(".CONFIG"))
+ .contains(QLatin1String("no_default_install"));
QString itemPath;
const QString pathVar = item + QLatin1String(".path");
const QStringList &itemPaths = reader->values(pathVar);
@@ -2428,11 +2421,12 @@ InstallsList QmakeProFileNode::installsList(const QtSupport::ProFileReader *read
itemPath = itemPaths.last();
if (item == QLatin1String("target")) {
- result.targetPath = itemPath;
+ if (active)
+ result.targetPath = itemPath;
} else {
- const QStringList &itemFiles = reader->fixifiedValues(
+ const auto &itemFiles = reader->fixifiedValues(
item + QLatin1String(".files"), projectDir, buildDir);
- result.items << InstallsItem(itemPath, itemFiles);
+ result.items << InstallsItem(itemPath, itemFiles, active);
}
}
return result;
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h
index 4dd307b4ad2..e7d3a3f8b25 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -115,6 +115,8 @@ class EvalResult;
class PriFileEvalResult;
}
+struct InstallsList;
+
// Implements ProjectNode for qmake .pri files
class QMAKEPROJECTMANAGER_EXPORT QmakePriFileNode : public ProjectExplorer::ProjectNode
{
@@ -164,7 +166,6 @@ protected:
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
static QStringList varNamesForRemoving();
static QString varNameForAdding(const QString &mimeType);
- static QStringList dynamicVarNames(QtSupport::ProFileReader *readerExact);
static QSet<Utils::FileName> filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
static QSet<Utils::FileName> filterFilesRecursiveEnumerata(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
@@ -201,8 +202,11 @@ private:
QHash<const ProFile *, Internal::PriFileEvalResult *> proToResult,
Internal::PriFileEvalResult *fallback,
QVector<ProFileEvaluator::SourceFile> sourceFiles, ProjectExplorer::FileType type);
- static void extractValues(
- const Internal::EvalInput &input, ProFile *proFile, Internal::PriFileEvalResult &result);
+ static void extractInstalls(
+ QHash<const ProFile *, Internal::PriFileEvalResult *> proToResult,
+ Internal::PriFileEvalResult *fallback,
+ const InstallsList &installList);
+ static void processValues(Internal::PriFileEvalResult &result);
void watchFolders(const QSet<QString> &folders);
QmakeProject *m_project;
@@ -294,9 +298,11 @@ public:
struct QMAKEPROJECTMANAGER_EXPORT InstallsItem {
InstallsItem() = default;
- InstallsItem(QString p, QStringList f) : path(p), files(f) {}
+ InstallsItem(QString p, QVector<ProFileEvaluator::SourceFile> f, bool a)
+ : path(p), files(f), active(a) {}
QString path;
- QStringList files;
+ QVector<ProFileEvaluator::SourceFile> files;
+ bool active;
};
struct QMAKEPROJECTMANAGER_EXPORT InstallsList {
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index f3cd7dbffa3..4a06be86ade 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -1388,8 +1388,10 @@ void QmakeProject::collectData(const QmakeProFileNode *node, DeploymentData &dep
const InstallsList &installsList = node->installsList();
foreach (const InstallsItem &item, installsList.items) {
- foreach (const QString &localFile, item.files)
- deploymentData.addFile(localFile, item.path);
+ if (!item.active)
+ continue;
+ foreach (const auto &localFile, item.files)
+ deploymentData.addFile(localFile.fileName, item.path);
}
switch (node->projectType()) {
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index 3124b273319..f60c6afa2c8 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -76,36 +76,35 @@ QStringList ProFileEvaluator::values(const QString &variableName) const
return ret;
}
-QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const
-{
- // It makes no sense to put any kind of magic into expanding these
- const ProStringList &values = d->m_valuemapStack.first().value(ProKey(variableName));
- QStringList ret;
- ret.reserve(values.size());
- foreach (const ProString &str, values)
- if (str.sourceFile() == pro)
- ret << d->m_option->expandEnvVars(str.toQString());
- return ret;
-}
-
-QStringList ProFileEvaluator::fixifiedValues(
+QVector<ProFileEvaluator::SourceFile> ProFileEvaluator::fixifiedValues(
const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const
{
- QStringList result;
- foreach (const QString &el, values(variable)) {
+ QVector<SourceFile> result;
+ foreach (const ProString &str, d->values(ProKey(variable))) {
+ const QString &el = d->m_option->expandEnvVars(str.toQString());
if (IoUtils::isAbsolutePath(el)) {
- result << el;
+ result << SourceFile{ el, str.sourceFile() };
} else {
QString fn = QDir::cleanPath(baseDirectory + QLatin1Char('/') + el);
if (IoUtils::exists(fn))
- result << fn;
+ result << SourceFile{ fn, str.sourceFile() };
else
- result << QDir::cleanPath(buildDirectory + QLatin1Char('/') + el);
+ result << SourceFile{ QDir::cleanPath(buildDirectory + QLatin1Char('/') + el),
+ str.sourceFile() };
}
}
return result;
}
+QStringList ProFileEvaluator::sourcesToFiles(const QVector<ProFileEvaluator::SourceFile> &sources)
+{
+ QStringList result;
+ result.reserve(sources.size());
+ for (const auto &src : sources)
+ result << src.fileName;
+ return result;
+}
+
// VFS note: all search paths are assumed to be real.
QStringList ProFileEvaluator::absolutePathValues(
const QString &variable, const QString &baseDirectory) const
diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h
index a356dadaf7a..d001c9d7b0d 100644
--- a/src/shared/proparser/profileevaluator.h
+++ b/src/shared/proparser/profileevaluator.h
@@ -80,14 +80,14 @@ public:
bool contains(const QString &variableName) const;
QString value(const QString &variableName) const;
QStringList values(const QString &variableName) const;
- QStringList values(const QString &variableName, const ProFile *pro) const;
- QStringList fixifiedValues(
+ QVector<SourceFile> fixifiedValues(
const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const;
QStringList absolutePathValues(const QString &variable, const QString &baseDirectory) const;
QVector<SourceFile> absoluteFileValues(
const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
QHash<ProString, bool> *handled) const;
QString propertyValue(const QString &val) const;
+ static QStringList sourcesToFiles(const QVector<SourceFile> &sources);
private:
QMakeEvaluator *d;