chuck sysroot handling out of ProFileEvaluator

qmake doesn't do anything with sysroots at this level, so this code
plain does not belong here.

sysrootification is used when resolving INCLUDEPATH, which is emulating
compiler behavior. this is done by higher-level code.

Task-number: QTCREATORBUG-11944
Change-Id: Ia25f0b6ef713e9809d974e3f3e49ba308b8c933f
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Oswald Buddenhagen
2016-10-21 20:23:07 +02:00
parent c42b12c98e
commit 1589ce3ce8
12 changed files with 61 additions and 53 deletions

View File

@@ -66,6 +66,7 @@
#include <utils/theme/theme.h>
#include <proparser/prowriter.h>
#include <proparser/qmakevfs.h>
#include <proparser/ioutils.h>
#include <QApplication>
#include <QDebug>
@@ -80,6 +81,7 @@
using namespace Core;
using namespace ProjectExplorer;
using namespace Utils;
using namespace QMakeInternal;
// Static cached data in struct QmakeNodeStaticData providing information and icons
// for file types and the project. Do some magic via qAddPostRoutine()
@@ -195,9 +197,10 @@ public:
QString projectDir;
FileName projectFilePath;
QString buildDirectory;
QString sysroot;
QtSupport::ProFileReader *readerExact;
QtSupport::ProFileReader *readerCumulative;
ProFileGlobals *qmakeGlobals;
QMakeGlobals *qmakeGlobals;
QMakeVfs *qmakeVfs;
};
@@ -1773,6 +1776,7 @@ EvalInput QmakeProFileNode::evalInput() const
input.projectDir = m_projectDir;
input.projectFilePath = m_projectFilePath;
input.buildDirectory = buildDir();
input.sysroot = m_project->qmakeSysroot();
input.readerExact = m_readerExact;
input.readerCumulative = m_readerCumulative;
input.qmakeGlobals = m_project->qmakeGlobals();
@@ -1937,7 +1941,8 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
// update other variables
result->newVarValues[DefinesVar] = input.readerExact->values(QLatin1String("DEFINES"));
result->newVarValues[IncludePathVar] = includePaths(input.readerExact, input.buildDirectory, input.projectDir);
result->newVarValues[IncludePathVar] = includePaths(input.readerExact, input.sysroot,
input.buildDirectory, input.projectDir);
result->newVarValues[CppFlagsVar] = input.readerExact->values(QLatin1String("QMAKE_CXXFLAGS"));
result->newVarValues[CppHeaderVar] = fileListForVar(input.readerExact, input.readerCumulative,
QLatin1String("HEADERS"), input.projectDir, input.buildDirectory);
@@ -2298,7 +2303,24 @@ QString QmakeProFileNode::mocDirPath(QtSupport::ProFileReader *reader, const QSt
return path;
}
QStringList QmakeProFileNode::includePaths(QtSupport::ProFileReader *reader, const QString &buildDir, const QString &projectDir)
QString QmakeProFileNode::sysrootify(const QString &path, const QString &sysroot,
const QString &baseDir, const QString &outputDir)
{
#ifdef Q_OS_WIN
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
#else
Qt::CaseSensitivity cs = Qt::CaseSensitive;
#endif
if (sysroot.isEmpty() || path.startsWith(sysroot, cs)
|| path.startsWith(baseDir, cs) || path.startsWith(outputDir, cs)) {
return path;
}
QString sysrooted = QDir::cleanPath(sysroot + path);
return !IoUtils::exists(sysrooted) ? path : sysrooted;
}
QStringList QmakeProFileNode::includePaths(QtSupport::ProFileReader *reader, const QString &sysroot,
const QString &buildDir, const QString &projectDir)
{
QStringList paths;
foreach (const QString &cxxflags, reader->values(QLatin1String("QMAKE_CXXFLAGS"))) {
@@ -2306,7 +2328,8 @@ QStringList QmakeProFileNode::includePaths(QtSupport::ProFileReader *reader, con
paths.append(cxxflags.mid(2));
}
paths.append(reader->fixifiedValues(QLatin1String("INCLUDEPATH"), projectDir, buildDir));
foreach (const QString &el, reader->fixifiedValues(QLatin1String("INCLUDEPATH"), projectDir, buildDir))
paths << sysrootify(el, 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)

View File

@@ -393,7 +393,8 @@ private:
const QString &varName, const QString &projectDir, const QString &buildDir);
static QString uiDirPath(QtSupport::ProFileReader *reader, const QString &buildDir);
static QString mocDirPath(QtSupport::ProFileReader *reader, const QString &buildDir);
static QStringList includePaths(QtSupport::ProFileReader *reader, const QString &buildDir, const QString &projectDir);
static QString sysrootify(const QString &path, const QString &sysroot, const QString &baseDir, const QString &outputDir);
static QStringList includePaths(QtSupport::ProFileReader *reader, const QString &sysroot, const QString &buildDir, const QString &projectDir);
static QStringList libDirectories(QtSupport::ProFileReader *reader);
static Utils::FileNameList subDirsPaths(QtSupport::ProFileReader *reader, const QString &projectDir, QStringList *subProjectsNotToDeploy, QStringList *errors);

View File

@@ -891,7 +891,7 @@ void QmakeProject::proFileParseError(const QString &errorMessage)
QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFileNode *qmakeProFileNode, QmakeBuildConfiguration *bc)
{
if (!m_qmakeGlobals) {
m_qmakeGlobals = new ProFileGlobals;
m_qmakeGlobals = new QMakeGlobals;
m_qmakeGlobalsRefCnt = 0;
Kit *k;
@@ -912,7 +912,7 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFileNo
}
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
QString systemRoot = SysRootKitInformation::hasSysRoot(k)
m_qmakeSysroot = SysRootKitInformation::hasSysRoot(k)
? SysRootKitInformation::sysRoot(k).toString() : QString();
if (qtVersion && qtVersion->isValid()) {
@@ -920,7 +920,6 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFileNo
m_qmakeGlobals->setProperties(qtVersion->versionInfo());
}
m_qmakeGlobals->setDirectories(rootProjectNode()->sourceDir(), rootProjectNode()->buildDir());
m_qmakeGlobals->sysroot = systemRoot;
Environment::const_iterator eit = env.constBegin(), eend = env.constEnd();
for (; eit != eend; ++eit)
@@ -953,7 +952,7 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFileNo
return reader;
}
ProFileGlobals *QmakeProject::qmakeGlobals()
QMakeGlobals *QmakeProject::qmakeGlobals()
{
return m_qmakeGlobals;
}
@@ -963,6 +962,11 @@ QMakeVfs *QmakeProject::qmakeVfs()
return m_qmakeVfs;
}
QString QmakeProject::qmakeSysroot()
{
return m_qmakeSysroot;
}
void QmakeProject::destroyProFileReader(QtSupport::ProFileReader *reader)
{
delete reader;

View File

@@ -38,7 +38,7 @@
#include <QFuture>
QT_BEGIN_NAMESPACE
class ProFileGlobals;
class QMakeGlobals;
class QMakeVfs;
QT_END_NAMESPACE
@@ -91,10 +91,12 @@ public:
/// \internal
QtSupport::ProFileReader *createProFileReader(const QmakeProFileNode *qmakeProFileNode, QmakeBuildConfiguration *bc = 0);
/// \internal
ProFileGlobals *qmakeGlobals();
QMakeGlobals *qmakeGlobals();
/// \internal
QMakeVfs *qmakeVfs();
/// \internal
QString qmakeSysroot();
/// \internal
void destroyProFileReader(QtSupport::ProFileReader *reader);
/// \internal
@@ -188,9 +190,11 @@ private:
QMakeVfs *m_qmakeVfs = nullptr;
// cached data during project rescan
ProFileGlobals *m_qmakeGlobals = nullptr;
QMakeGlobals *m_qmakeGlobals = nullptr;
int m_qmakeGlobalsRefCnt = 0;
QString m_qmakeSysroot;
QTimer m_asyncUpdateTimer;
QFutureInterface<void> *m_asyncUpdateFutureInterface = nullptr;
int m_pendingEvaluateFuturesCount = 0;

View File

@@ -1009,7 +1009,7 @@ void BaseQtVersion::ensureMkSpecParsed() const
return;
QMakeVfs vfs;
ProFileGlobals option;
QMakeGlobals option;
option.setProperties(versionInfo());
option.environment = qmakeRunEnvironment().toProcessEnvironment();
ProMessageHandler msgHandler(true);

View File

@@ -74,7 +74,7 @@ void ProMessageHandler::fileMessage(int type, const QString &msg)
}
ProFileReader::ProFileReader(ProFileGlobals *option, QMakeVfs *vfs)
ProFileReader::ProFileReader(QMakeGlobals *option, QMakeVfs *vfs)
: QMakeParser(ProFileCacheManager::instance()->cache(), vfs, this)
, ProFileEvaluator(option, this, vfs, this)
, m_ignoreLevel(0)

View File

@@ -68,7 +68,7 @@ class QTSUPPORT_EXPORT ProFileReader : public ProMessageHandler, public QMakePar
Q_OBJECT
public:
ProFileReader(ProFileGlobals *option, QMakeVfs *vfs);
ProFileReader(QMakeGlobals *option, QMakeVfs *vfs);
~ProFileReader();
void setCumulative(bool on);

View File

@@ -54,7 +54,7 @@ BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath(const Utils::FileN
Utils::FileName mkspec = BaseQtVersion::mkspecFromVersionInfo(versionInfo);
QMakeVfs vfs;
ProFileGlobals globals;
QMakeGlobals globals;
globals.setProperties(versionInfo);
ProMessageHandler msgHandler(false);
ProFileCacheManager::instance()->incRefCount();

View File

@@ -25,6 +25,8 @@
#pragma once
#include "qmake_global.h"
#include <qstring.h>
QT_BEGIN_NAMESPACE
@@ -35,7 +37,7 @@ namespace QMakeInternal {
This class provides replacement functionality for QFileInfo, QFile & QDir,
as these are abysmally slow.
*/
class IoUtils {
class QMAKE_EXPORT IoUtils {
public:
enum FileType {
FileNotFound = 0,

View File

@@ -39,7 +39,7 @@ void ProFileEvaluator::initialize()
QMakeEvaluator::initStatics();
}
ProFileEvaluator::ProFileEvaluator(ProFileGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
ProFileEvaluator::ProFileEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
QMakeHandler *handler)
: d(new QMakeEvaluator(option, parser, vfs, handler))
{
@@ -86,29 +86,13 @@ QStringList ProFileEvaluator::values(const QString &variableName, const ProFile
return ret;
}
QString ProFileEvaluator::sysrootify(const QString &path, const QString &baseDir) const
{
ProFileGlobals *option = static_cast<ProFileGlobals *>(d->m_option);
#ifdef Q_OS_WIN
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
#else
Qt::CaseSensitivity cs = Qt::CaseSensitive;
#endif
const bool isHostSystemPath =
option->sysroot.isEmpty() || path.startsWith(option->sysroot, cs)
|| path.startsWith(baseDir, cs) || path.startsWith(d->m_outputDir, cs)
|| !QFileInfo::exists(option->sysroot + path);
return isHostSystemPath ? path : option->sysroot + path;
}
QStringList ProFileEvaluator::fixifiedValues(
const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const
{
QStringList result;
foreach (const QString &el, values(variable)) {
if (IoUtils::isAbsolutePath(el)) {
result << sysrootify(el, baseDirectory);
result << el;
} else {
QString fn = QDir::cleanPath(baseDirectory + QLatin1Char('/') + el);
if (IoUtils::exists(fn))
@@ -125,10 +109,9 @@ QStringList ProFileEvaluator::absolutePathValues(
{
QStringList result;
foreach (const QString &el, values(variable)) {
QString absEl = IoUtils::isAbsolutePath(el)
? sysrootify(el, baseDirectory) : IoUtils::resolvePath(baseDirectory, el);
QString absEl = IoUtils::resolvePath(baseDirectory, el);
if (IoUtils::fileType(absEl) == IoUtils::FileIsDir)
result << QDir::cleanPath(absEl);
result << absEl;
}
return result;
}
@@ -141,12 +124,11 @@ QStringList ProFileEvaluator::absoluteFileValues(
foreach (const QString &el, pro ? values(variable, pro) : values(variable)) {
QString absEl;
if (IoUtils::isAbsolutePath(el)) {
const QString elWithSysroot = sysrootify(el, baseDirectory);
if (IoUtils::exists(elWithSysroot)) {
result << QDir::cleanPath(elWithSysroot);
if (IoUtils::exists(el)) {
result << el;
goto next;
}
absEl = elWithSysroot;
absEl = el;
} else {
foreach (const QString &dir, searchDirs) {
QString fn = dir + QLatin1Char('/') + el;

View File

@@ -40,12 +40,6 @@ class QMakeParser;
class QMakeEvaluator;
class QMakeHandler;
class QMAKE_EXPORT ProFileGlobals : public QMakeGlobals
{
public:
QString sysroot;
};
class QMAKE_EXPORT ProFileEvaluator
{
public:
@@ -62,7 +56,7 @@ public:
// Call this from a concurrency-free context
static void initialize();
ProFileEvaluator(ProFileGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
ProFileEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
QMakeHandler *handler);
~ProFileEvaluator();
@@ -91,8 +85,6 @@ public:
QString propertyValue(const QString &val) const;
private:
QString sysrootify(const QString &path, const QString &baseDir) const;
QMakeEvaluator *d;
};

View File

@@ -66,7 +66,7 @@ public:
static EvalHandler evalHandler;
static int evaluate(const QString &fileName, const QString &in_pwd, const QString &out_pwd,
bool cumulative, ProFileGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
bool cumulative, QMakeGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
int level)
{
static QSet<QString> visited;
@@ -140,7 +140,7 @@ int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
ProFileGlobals option;
QMakeGlobals option;
QString qmake = QString::fromLocal8Bit(qgetenv("TESTREADER_QMAKE"));
if (qmake.isEmpty())
qmake = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmake");