forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -660,24 +660,22 @@ void QmakePriFileNode::extractSources(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmakePriFileNode::extractValues(
|
void QmakePriFileNode::extractInstalls(
|
||||||
const EvalInput &input, ProFile *proFile, PriFileEvalResult &result)
|
QHash<const ProFile *, PriFileEvalResult *> proToResult, PriFileEvalResult *fallback,
|
||||||
|
const InstallsList &installList)
|
||||||
{
|
{
|
||||||
// Figure out DEPLOYMENT and INSTALL folders.
|
for (const InstallsItem &item : installList.items) {
|
||||||
// Ignore stuff from cumulative parse, as we are recursively enumerating
|
for (const ProFileEvaluator::SourceFile &source : item.files) {
|
||||||
// all the files from those folders and add watchers for them. That's too
|
auto *result = proToResult.value(source.proFile);
|
||||||
// dangerous if we get the folders wrong and enumerate the whole project
|
if (!result)
|
||||||
// tree multiple times.
|
result = fallback;
|
||||||
QStringList dynamicVariables = dynamicVarNames(input.readerExact);
|
result->folders << source.fileName;
|
||||||
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::processValues(PriFileEvalResult &result)
|
||||||
|
{
|
||||||
result.folders.removeDuplicates();
|
result.folders.removeDuplicates();
|
||||||
|
|
||||||
// Remove non existing items and non folders
|
// Remove non existing items and non folders
|
||||||
@@ -1456,19 +1454,6 @@ QStringList QmakePriFileNode::varNamesForRemoving()
|
|||||||
return vars;
|
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)
|
QSet<FileName> QmakePriFileNode::filterFilesProVariables(FileType fileType, const QSet<FileName> &files)
|
||||||
{
|
{
|
||||||
if (fileType != QMLType && fileType != UnknownFileType)
|
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) {
|
if (result->state == EvalResult::EvalOk) {
|
||||||
result->targetInformation = targetInformation(input.readerExact, exactBuildPassReader,
|
result->targetInformation = targetInformation(input.readerExact, exactBuildPassReader,
|
||||||
input.buildDirectory, input.projectFilePath.toString());
|
input.buildDirectory, input.projectFilePath.toString());
|
||||||
result->installsList = installsList(exactBuildPassReader, input.projectFilePath.toString(),
|
|
||||||
input.projectDir, input.buildDirectory);
|
|
||||||
|
|
||||||
// update other variables
|
// update other variables
|
||||||
result->newVarValues[DefinesVar] = exactReader->values(QLatin1String("DEFINES"));
|
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[ExactResourceVar] = fileListForVar(exactSourceFiles, QLatin1String("RESOURCES"));
|
||||||
result->newVarValues[CumulativeResourceVar] = fileListForVar(cumulativeSourceFiles, QLatin1String("RESOURCES"));
|
result->newVarValues[CumulativeResourceVar] = fileListForVar(cumulativeSourceFiles, QLatin1String("RESOURCES"));
|
||||||
result->newVarValues[PkgConfigVar] = exactReader->values(QLatin1String("PKGCONFIG"));
|
result->newVarValues[PkgConfigVar] = exactReader->values(QLatin1String("PKGCONFIG"));
|
||||||
result->newVarValues[PrecompiledHeaderVar] = exactReader->fixifiedValues(
|
result->newVarValues[PrecompiledHeaderVar] = ProFileEvaluator::sourcesToFiles(exactReader->fixifiedValues(
|
||||||
QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory);
|
QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory));
|
||||||
result->newVarValues[LibDirectoriesVar] = libDirectories(exactReader);
|
result->newVarValues[LibDirectoriesVar] = libDirectories(exactReader);
|
||||||
result->newVarValues[ConfigVar] = exactReader->values(QLatin1String("CONFIG"));
|
result->newVarValues[ConfigVar] = exactReader->values(QLatin1String("CONFIG"));
|
||||||
result->newVarValues[QmlImportPathVar] = exactReader->absolutePathValues(
|
result->newVarValues[QmlImportPathVar] = exactReader->absolutePathValues(
|
||||||
@@ -2007,11 +1999,10 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
|
|||||||
|
|
||||||
if (result->state == EvalResult::EvalOk || result->state == EvalResult::EvalPartial) {
|
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 };
|
QList<IncludedPriFile *> toExtract = { &result->includedFiles };
|
||||||
while (!toExtract.isEmpty()) {
|
while (!toExtract.isEmpty()) {
|
||||||
IncludedPriFile *current = toExtract.takeFirst();
|
IncludedPriFile *current = toExtract.takeFirst();
|
||||||
extractValues(input, current->proFile, current->result);
|
processValues(current->result);
|
||||||
toExtract.append(current->children.values());
|
toExtract.append(current->children.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2295,8 +2286,10 @@ QStringList QmakeProFileNode::includePaths(QtSupport::ProFileReader *reader, con
|
|||||||
paths.append(cxxflags.mid(2));
|
paths.append(cxxflags.mid(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QString &el, reader->fixifiedValues(QLatin1String("INCLUDEPATH"), projectDir, buildDir))
|
foreach (const ProFileEvaluator::SourceFile &el,
|
||||||
paths << sysrootify(el, sysroot, projectDir, buildDir);
|
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
|
// 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
|
// except if those directories don't exist at the time of parsing
|
||||||
// thus we add those directories manually (without checking for existence)
|
// thus we add those directories manually (without checking for existence)
|
||||||
@@ -2411,8 +2404,8 @@ InstallsList QmakeProFileNode::installsList(const QtSupport::ProFileReader *read
|
|||||||
return result;
|
return result;
|
||||||
const QStringList &itemList = reader->values(QLatin1String("INSTALLS"));
|
const QStringList &itemList = reader->values(QLatin1String("INSTALLS"));
|
||||||
foreach (const QString &item, itemList) {
|
foreach (const QString &item, itemList) {
|
||||||
if (reader->values(item + QLatin1String(".CONFIG")).contains(QLatin1String("no_default_install")))
|
bool active = !reader->values(item + QLatin1String(".CONFIG"))
|
||||||
continue;
|
.contains(QLatin1String("no_default_install"));
|
||||||
QString itemPath;
|
QString itemPath;
|
||||||
const QString pathVar = item + QLatin1String(".path");
|
const QString pathVar = item + QLatin1String(".path");
|
||||||
const QStringList &itemPaths = reader->values(pathVar);
|
const QStringList &itemPaths = reader->values(pathVar);
|
||||||
@@ -2428,11 +2421,12 @@ InstallsList QmakeProFileNode::installsList(const QtSupport::ProFileReader *read
|
|||||||
itemPath = itemPaths.last();
|
itemPath = itemPaths.last();
|
||||||
|
|
||||||
if (item == QLatin1String("target")) {
|
if (item == QLatin1String("target")) {
|
||||||
|
if (active)
|
||||||
result.targetPath = itemPath;
|
result.targetPath = itemPath;
|
||||||
} else {
|
} else {
|
||||||
const QStringList &itemFiles = reader->fixifiedValues(
|
const auto &itemFiles = reader->fixifiedValues(
|
||||||
item + QLatin1String(".files"), projectDir, buildDir);
|
item + QLatin1String(".files"), projectDir, buildDir);
|
||||||
result.items << InstallsItem(itemPath, itemFiles);
|
result.items << InstallsItem(itemPath, itemFiles, active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ class EvalResult;
|
|||||||
class PriFileEvalResult;
|
class PriFileEvalResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct InstallsList;
|
||||||
|
|
||||||
// Implements ProjectNode for qmake .pri files
|
// Implements ProjectNode for qmake .pri files
|
||||||
class QMAKEPROJECTMANAGER_EXPORT QmakePriFileNode : public ProjectExplorer::ProjectNode
|
class QMAKEPROJECTMANAGER_EXPORT QmakePriFileNode : public ProjectExplorer::ProjectNode
|
||||||
{
|
{
|
||||||
@@ -164,7 +166,6 @@ protected:
|
|||||||
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
|
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
|
||||||
static QStringList varNamesForRemoving();
|
static QStringList varNamesForRemoving();
|
||||||
static QString varNameForAdding(const QString &mimeType);
|
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> filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
|
||||||
static QSet<Utils::FileName> filterFilesRecursiveEnumerata(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,
|
QHash<const ProFile *, Internal::PriFileEvalResult *> proToResult,
|
||||||
Internal::PriFileEvalResult *fallback,
|
Internal::PriFileEvalResult *fallback,
|
||||||
QVector<ProFileEvaluator::SourceFile> sourceFiles, ProjectExplorer::FileType type);
|
QVector<ProFileEvaluator::SourceFile> sourceFiles, ProjectExplorer::FileType type);
|
||||||
static void extractValues(
|
static void extractInstalls(
|
||||||
const Internal::EvalInput &input, ProFile *proFile, Internal::PriFileEvalResult &result);
|
QHash<const ProFile *, Internal::PriFileEvalResult *> proToResult,
|
||||||
|
Internal::PriFileEvalResult *fallback,
|
||||||
|
const InstallsList &installList);
|
||||||
|
static void processValues(Internal::PriFileEvalResult &result);
|
||||||
void watchFolders(const QSet<QString> &folders);
|
void watchFolders(const QSet<QString> &folders);
|
||||||
|
|
||||||
QmakeProject *m_project;
|
QmakeProject *m_project;
|
||||||
@@ -294,9 +298,11 @@ public:
|
|||||||
|
|
||||||
struct QMAKEPROJECTMANAGER_EXPORT InstallsItem {
|
struct QMAKEPROJECTMANAGER_EXPORT InstallsItem {
|
||||||
InstallsItem() = default;
|
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;
|
QString path;
|
||||||
QStringList files;
|
QVector<ProFileEvaluator::SourceFile> files;
|
||||||
|
bool active;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QMAKEPROJECTMANAGER_EXPORT InstallsList {
|
struct QMAKEPROJECTMANAGER_EXPORT InstallsList {
|
||||||
|
|||||||
@@ -1388,8 +1388,10 @@ void QmakeProject::collectData(const QmakeProFileNode *node, DeploymentData &dep
|
|||||||
|
|
||||||
const InstallsList &installsList = node->installsList();
|
const InstallsList &installsList = node->installsList();
|
||||||
foreach (const InstallsItem &item, installsList.items) {
|
foreach (const InstallsItem &item, installsList.items) {
|
||||||
foreach (const QString &localFile, item.files)
|
if (!item.active)
|
||||||
deploymentData.addFile(localFile, item.path);
|
continue;
|
||||||
|
foreach (const auto &localFile, item.files)
|
||||||
|
deploymentData.addFile(localFile.fileName, item.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (node->projectType()) {
|
switch (node->projectType()) {
|
||||||
|
|||||||
@@ -76,36 +76,35 @@ QStringList ProFileEvaluator::values(const QString &variableName) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const
|
QVector<ProFileEvaluator::SourceFile> ProFileEvaluator::fixifiedValues(
|
||||||
{
|
|
||||||
// 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(
|
|
||||||
const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const
|
const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const
|
||||||
{
|
{
|
||||||
QStringList result;
|
QVector<SourceFile> result;
|
||||||
foreach (const QString &el, values(variable)) {
|
foreach (const ProString &str, d->values(ProKey(variable))) {
|
||||||
|
const QString &el = d->m_option->expandEnvVars(str.toQString());
|
||||||
if (IoUtils::isAbsolutePath(el)) {
|
if (IoUtils::isAbsolutePath(el)) {
|
||||||
result << el;
|
result << SourceFile{ el, str.sourceFile() };
|
||||||
} else {
|
} else {
|
||||||
QString fn = QDir::cleanPath(baseDirectory + QLatin1Char('/') + el);
|
QString fn = QDir::cleanPath(baseDirectory + QLatin1Char('/') + el);
|
||||||
if (IoUtils::exists(fn))
|
if (IoUtils::exists(fn))
|
||||||
result << fn;
|
result << SourceFile{ fn, str.sourceFile() };
|
||||||
else
|
else
|
||||||
result << QDir::cleanPath(buildDirectory + QLatin1Char('/') + el);
|
result << SourceFile{ QDir::cleanPath(buildDirectory + QLatin1Char('/') + el),
|
||||||
|
str.sourceFile() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
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.
|
// VFS note: all search paths are assumed to be real.
|
||||||
QStringList ProFileEvaluator::absolutePathValues(
|
QStringList ProFileEvaluator::absolutePathValues(
|
||||||
const QString &variable, const QString &baseDirectory) const
|
const QString &variable, const QString &baseDirectory) const
|
||||||
|
|||||||
@@ -80,14 +80,14 @@ public:
|
|||||||
bool contains(const QString &variableName) const;
|
bool contains(const QString &variableName) const;
|
||||||
QString value(const QString &variableName) const;
|
QString value(const QString &variableName) const;
|
||||||
QStringList values(const QString &variableName) const;
|
QStringList values(const QString &variableName) const;
|
||||||
QStringList values(const QString &variableName, const ProFile *pro) const;
|
QVector<SourceFile> fixifiedValues(
|
||||||
QStringList fixifiedValues(
|
|
||||||
const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const;
|
const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const;
|
||||||
QStringList absolutePathValues(const QString &variable, const QString &baseDirectory) const;
|
QStringList absolutePathValues(const QString &variable, const QString &baseDirectory) const;
|
||||||
QVector<SourceFile> absoluteFileValues(
|
QVector<SourceFile> absoluteFileValues(
|
||||||
const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
|
const QString &variable, const QString &baseDirectory, const QStringList &searchDirs,
|
||||||
QHash<ProString, bool> *handled) const;
|
QHash<ProString, bool> *handled) const;
|
||||||
QString propertyValue(const QString &val) const;
|
QString propertyValue(const QString &val) const;
|
||||||
|
static QStringList sourcesToFiles(const QVector<SourceFile> &sources);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMakeEvaluator *d;
|
QMakeEvaluator *d;
|
||||||
|
|||||||
Reference in New Issue
Block a user