QMakeProjectManager: Progress towards reading remote .pro files

Change-Id: I26d6d47ac7cd44ec2877243d562de1d90ba45054
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
hjk
2022-11-28 17:19:08 +01:00
parent 3537c9974e
commit 669242b9d8
3 changed files with 68 additions and 36 deletions

View File

@@ -1298,7 +1298,7 @@ bool QmakeProFile::isFileFromWildcard(const QString &filePath) const
QmakeEvalInput QmakeProFile::evalInput() const QmakeEvalInput QmakeProFile::evalInput() const
{ {
QmakeEvalInput input; QmakeEvalInput input;
input.projectDir = directoryPath().toString(); input.projectDir = directoryPath().toFSPathString();
input.projectFilePath = filePath(); input.projectFilePath = filePath();
input.buildDirectory = m_buildSystem->buildDir(m_filePath); input.buildDirectory = m_buildSystem->buildDir(m_filePath);
input.sysroot = FilePath::fromString(m_buildSystem->qmakeSysroot()); input.sysroot = FilePath::fromString(m_buildSystem->qmakeSysroot());
@@ -1347,9 +1347,8 @@ static bool evaluateOne(const QmakeEvalInput &input, ProFile *pro,
// We don't increase/decrease m_qmakeGlobalsRefCnt here, because the outer profilereaders keep m_qmakeGlobals alive anyway // We don't increase/decrease m_qmakeGlobalsRefCnt here, because the outer profilereaders keep m_qmakeGlobals alive anyway
auto bpReader = new QtSupport::ProFileReader(input.qmakeGlobals, input.qmakeVfs); // needs to access m_qmakeGlobals, m_qmakeVfs auto bpReader = new QtSupport::ProFileReader(input.qmakeGlobals, input.qmakeVfs); // needs to access m_qmakeGlobals, m_qmakeVfs
// FIXME: Currently intentional.
// Core parts of the ProParser hard-assert on non-local items. // Core parts of the ProParser hard-assert on non-local items.
bpReader->setOutputDir(input.buildDirectory.path()); bpReader->setOutputDir(input.buildDirectory.toFSPathString());
bpReader->setCumulative(cumulative); bpReader->setCumulative(cumulative);
bpReader->setExtraVars(basevars); bpReader->setExtraVars(basevars);
bpReader->setExtraConfigs(basecfgs); bpReader->setExtraConfigs(basecfgs);
@@ -1369,7 +1368,7 @@ QmakeEvalResultPtr QmakeProFile::evaluate(const QmakeEvalInput &input)
QtSupport::ProFileReader *exactBuildPassReader = nullptr; QtSupport::ProFileReader *exactBuildPassReader = nullptr;
QtSupport::ProFileReader *cumulativeBuildPassReader = nullptr; QtSupport::ProFileReader *cumulativeBuildPassReader = nullptr;
ProFile *pro; ProFile *pro;
if ((pro = input.readerExact->parsedProFile(input.projectFilePath.toString()))) { if ((pro = input.readerExact->parsedProFile(input.projectFilePath.toFSPathString()))) {
bool exactOk = evaluateOne(input, pro, input.readerExact, false, &exactBuildPassReader); bool exactOk = evaluateOne(input, pro, input.readerExact, false, &exactBuildPassReader);
bool cumulOk = evaluateOne(input, pro, input.readerCumulative, true, &cumulativeBuildPassReader); bool cumulOk = evaluateOne(input, pro, input.readerCumulative, true, &cumulativeBuildPassReader);
pro->deref(); pro->deref();
@@ -1473,9 +1472,9 @@ QmakeEvalResultPtr QmakeProFile::evaluate(const QmakeEvalInput &input)
QHash<QString, QVector<ProFileEvaluator::SourceFile>> cumulativeSourceFiles; QHash<QString, QVector<ProFileEvaluator::SourceFile>> cumulativeSourceFiles;
const QStringList baseVPathsExact const QStringList baseVPathsExact
= baseVPaths(exactReader, input.projectDir, input.buildDirectory.toString()); = baseVPaths(exactReader, input.projectDir, input.buildDirectory.toFSPathString());
const QStringList baseVPathsCumulative const QStringList baseVPathsCumulative
= baseVPaths(cumulativeReader, input.projectDir, input.buildDirectory.toString()); = baseVPaths(cumulativeReader, input.projectDir, input.buildDirectory.toFSPathString());
for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) { for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) {
const auto type = static_cast<FileType>(i); const auto type = static_cast<FileType>(i);
@@ -1504,8 +1503,10 @@ QmakeEvalResultPtr QmakeProFile::evaluate(const QmakeEvalInput &input)
// - The project tree, in which case we also want exact values to avoid recursively // - 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 // watching bogus paths. However, we accept the values even if the evaluation
// failed, to at least have a best-effort result. // failed, to at least have a best-effort result.
result->installsList = installsList(exactBuildPassReader, input.projectFilePath.toString(), result->installsList = installsList(exactBuildPassReader,
input.projectDir, input.buildDirectory.toString()); input.projectFilePath.toFSPathString(),
input.projectDir,
input.buildDirectory.toFSPathString());
extractInstalls(proToResult, &result->includedFiles.result, result->installsList); extractInstalls(proToResult, &result->includedFiles.result, result->installsList);
if (result->state == QmakeEvalResult::EvalOk) { if (result->state == QmakeEvalResult::EvalOk) {
@@ -1534,7 +1535,7 @@ QmakeEvalResultPtr QmakeProFile::evaluate(const QmakeEvalInput &input)
result->newVarValues[Variable::CumulativeResource] = fileListForVar(cumulativeSourceFiles, QLatin1String("RESOURCES")); result->newVarValues[Variable::CumulativeResource] = fileListForVar(cumulativeSourceFiles, QLatin1String("RESOURCES"));
result->newVarValues[Variable::PkgConfig] = exactReader->values(QLatin1String("PKGCONFIG")); result->newVarValues[Variable::PkgConfig] = exactReader->values(QLatin1String("PKGCONFIG"));
result->newVarValues[Variable::PrecompiledHeader] = ProFileEvaluator::sourcesToFiles(exactReader->fixifiedValues( result->newVarValues[Variable::PrecompiledHeader] = ProFileEvaluator::sourcesToFiles(exactReader->fixifiedValues(
QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory.toString(), false)); QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory.toFSPathString(), false));
result->newVarValues[Variable::LibDirectories] = libDirectories(exactReader); result->newVarValues[Variable::LibDirectories] = libDirectories(exactReader);
result->newVarValues[Variable::Config] = exactReader->values(QLatin1String("CONFIG")); result->newVarValues[Variable::Config] = exactReader->values(QLatin1String("CONFIG"));
result->newVarValues[Variable::QmlImportPath] = exactReader->absolutePathValues( result->newVarValues[Variable::QmlImportPath] = exactReader->absolutePathValues(
@@ -1782,7 +1783,7 @@ QString QmakeProFile::uiDirPath(QtSupport::ProFileReader *reader, const FilePath
{ {
QString path = reader->value(QLatin1String("UI_DIR")); QString path = reader->value(QLatin1String("UI_DIR"));
if (QFileInfo(path).isRelative()) if (QFileInfo(path).isRelative())
path = QDir::cleanPath(buildDir.toString() + QLatin1Char('/') + path); path = QDir::cleanPath(buildDir.toFSPathString() + QLatin1Char('/') + path);
return path; return path;
} }
@@ -1790,7 +1791,7 @@ QString QmakeProFile::mocDirPath(QtSupport::ProFileReader *reader, const FilePat
{ {
QString path = reader->value(QLatin1String("MOC_DIR")); QString path = reader->value(QLatin1String("MOC_DIR"));
if (QFileInfo(path).isRelative()) if (QFileInfo(path).isRelative())
path = QDir::cleanPath(buildDir.toString() + QLatin1Char('/') + path); path = QDir::cleanPath(buildDir.toFSPathString() + QLatin1Char('/') + path);
return path; return path;
} }
@@ -1835,10 +1836,11 @@ QStringList QmakeProFile::includePaths(QtSupport::ProFileReader *reader, const F
const QString uiDir = uiDirPath(reader, buildDir); const QString uiDir = uiDirPath(reader, buildDir);
const QVector<ProFileEvaluator::SourceFile> elList = reader->fixifiedValues( const QVector<ProFileEvaluator::SourceFile> elList = reader->fixifiedValues(
QLatin1String("INCLUDEPATH"), projectDir, buildDir.toString(), false); QLatin1String("INCLUDEPATH"), projectDir, buildDir.toFSPathString(), false);
for (const ProFileEvaluator::SourceFile &el : elList) { for (const ProFileEvaluator::SourceFile &el : elList) {
const QString sysrootifiedPath = sysrootify(el.fileName, sysroot.toString(), projectDir, const QString sysrootifiedPath = sysrootify(el.fileName, sysroot.toFSPathString(),
buildDir.toString()); projectDir,
buildDir.toFSPathString());
if (IoUtils::isAbsolutePath(sysrootifiedPath) if (IoUtils::isAbsolutePath(sysrootifiedPath)
&& (IoUtils::exists(sysrootifiedPath) || sysrootifiedPath == mocDir && (IoUtils::exists(sysrootifiedPath) || sysrootifiedPath == mocDir
|| sysrootifiedPath == uiDir)) { || sysrootifiedPath == uiDir)) {

View File

@@ -801,14 +801,31 @@ static FileNode *fileNodeOf(FolderNode *in, const FilePath &fileName)
FilePath QmakeBuildSystem::buildDir(const FilePath &proFilePath) const FilePath QmakeBuildSystem::buildDir(const FilePath &proFilePath) const
{ {
const QDir srcDirRoot = QDir(projectDirectory().toString());
const QString relativeDir = srcDirRoot.relativeFilePath(proFilePath.parentDir().toString());
const FilePath buildConfigBuildDir = buildConfiguration()->buildDirectory(); const FilePath buildConfigBuildDir = buildConfiguration()->buildDirectory();
FilePath buildDir = buildConfigBuildDir.isEmpty() const FilePath buildDir = buildConfigBuildDir.isEmpty()
? projectDirectory() ? projectDirectory()
: buildConfigBuildDir; : buildConfigBuildDir;
// FIXME: Convoluted.
return buildDir.withNewPath(QDir::cleanPath(QDir(buildDir.path()).absoluteFilePath(relativeDir))); // The remote version below is actually generic, but I don't dare to touch
// the convoluted existing local version for now.
// For starters, compute a 'new' version to check what it would look like,
// but don't use it.
if (!proFilePath.needsDevice()) {
// This branch should not exist.
const QDir srcDirRoot = QDir(projectDirectory().toString());
const QString relativeDir = srcDirRoot.relativeFilePath(proFilePath.parentDir().toString());
// FIXME: Convoluted. Try to migrate to newRes once we feel confident enough.
const FilePath oldResult = buildDir.withNewPath(
QDir::cleanPath(QDir(buildDir.path()).absoluteFilePath(relativeDir)));
const FilePath newResult = buildDir.resolvePath(relativeDir);
QTC_ASSERT(oldResult == newResult,
qDebug() << "New build dir construction failed. Not equal:"
<< oldResult.toString() << newResult.toString());
return oldResult;
}
const FilePath relativeDir = proFilePath.parentDir().relativePathFrom(projectDirectory());
return buildDir.resolvePath(relativeDir).canonicalPath();
} }
void QmakeBuildSystem::proFileParseError(const QString &errorMessage, const FilePath &filePath) void QmakeBuildSystem::proFileParseError(const QString &errorMessage, const FilePath &filePath)
@@ -837,17 +854,19 @@ QtSupport::ProFileReader *QmakeBuildSystem::createProFileReader(const QmakeProFi
m_qmakeSysroot = SysRootKitAspect::sysRoot(k).toString(); m_qmakeSysroot = SysRootKitAspect::sysRoot(k).toString();
if (qtVersion && qtVersion->isValid()) { if (qtVersion && qtVersion->isValid()) {
m_qmakeGlobals->qmake_abslocation = QDir::cleanPath(qtVersion->qmakeFilePath().toString()); m_qmakeGlobals->qmake_abslocation =
QDir::cleanPath(qtVersion->qmakeFilePath().toString());
qtVersion->applyProperties(m_qmakeGlobals.get()); qtVersion->applyProperties(m_qmakeGlobals.get());
} }
m_qmakeGlobals->setDirectories(rootProFile()->sourceDir().toString(),
buildDir(rootProFile()->filePath()).toString()); QString rootProFileName = buildDir(rootProFile()->filePath()).toFSPathString();
m_qmakeGlobals->setDirectories(rootProFile()->sourceDir().toFSPathString(), rootProFileName);
Environment::const_iterator eit = env.constBegin(), eend = env.constEnd(); Environment::const_iterator eit = env.constBegin(), eend = env.constEnd();
for (; eit != eend; ++eit) for (; eit != eend; ++eit)
m_qmakeGlobals->environment.insert(env.key(eit), env.expandedValueForKey(env.key(eit))); m_qmakeGlobals->environment.insert(env.key(eit), env.expandedValueForKey(env.key(eit)));
m_qmakeGlobals->setCommandLineArguments(buildDir(rootProFile()->filePath()).toString(), qmakeArgs); m_qmakeGlobals->setCommandLineArguments(rootProFileName, qmakeArgs);
m_qmakeGlobals->runSystemFunction = bc->runSystemFunction(); m_qmakeGlobals->runSystemFunction = bc->runSystemFunction();
QtSupport::ProFileCacheManager::instance()->incRefCount(); QtSupport::ProFileCacheManager::instance()->incRefCount();
@@ -870,9 +889,8 @@ QtSupport::ProFileReader *QmakeBuildSystem::createProFileReader(const QmakeProFi
auto reader = new QtSupport::ProFileReader(m_qmakeGlobals.get(), m_qmakeVfs); auto reader = new QtSupport::ProFileReader(m_qmakeGlobals.get(), m_qmakeVfs);
// FIXME: Currently intentional.
// Core parts of the ProParser hard-assert on non-local items // Core parts of the ProParser hard-assert on non-local items
reader->setOutputDir(buildDir(qmakeProFile->filePath()).path()); reader->setOutputDir(buildDir(qmakeProFile->filePath()).toFSPathString());
return reader; return reader;
} }

View File

@@ -24,24 +24,28 @@ QT_BEGIN_NAMESPACE
using namespace QMakeInternal; using namespace QMakeInternal;
IoUtils::FileType IoUtils::fileType(const QString &fileName) static bool isGenericPath(const QStringView fileName)
{ {
// FIXME: static const QString specialRoot = QDir::rootPath() + "__qtc_devices__/";
if (fileName.startsWith("docker:/")) { return fileName.startsWith(specialRoot);
if (!fileName.startsWith("docker://"))
qWarning("File name not canonical");
int pos = fileName.indexOf('/', 10);
if (pos == 0) {
qWarning("File name not canonical");
return FileNotFound;
}
return fileType(fileName.mid(pos));
} }
if (!QFileInfo::exists(fileName)) // FIXME make pro parser work with non-local IoUtils::FileType IoUtils::fileType(const QString &fileName)
{
if (isGenericPath(fileName)) {
QFileInfo fi(fileName);
if (fi.isDir())
return FileIsDir;
if (fi.isFile())
return FileIsRegular;
return FileNotFound;
}
if (!QFileInfo::exists(fileName))
return FileNotFound; return FileNotFound;
Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName)); Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName));
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16()); DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16());
if (attr == INVALID_FILE_ATTRIBUTES) if (attr == INVALID_FILE_ATTRIBUTES)
@@ -61,6 +65,10 @@ bool IoUtils::isRelativePath(const QString &path)
if (path.startsWith(QLatin1String(":/"))) if (path.startsWith(QLatin1String(":/")))
return false; return false;
#endif #endif
if (isGenericPath(path))
return QFileInfo(path).isRelative();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Unlike QFileInfo, this considers only paths with both a drive prefix and // Unlike QFileInfo, this considers only paths with both a drive prefix and
// a subsequent (back-)slash absolute: // a subsequent (back-)slash absolute:
@@ -95,6 +103,10 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
{ {
if (fileName.isEmpty()) if (fileName.isEmpty())
return QString(); return QString();
if (isGenericPath(fileName))
return baseDir + '/' + fileName;
if (isAbsolutePath(fileName)) if (isAbsolutePath(fileName))
return QDir::cleanPath(fileName); return QDir::cleanPath(fileName);
#ifdef Q_OS_WIN // Add drive to otherwise-absolute path: #ifdef Q_OS_WIN // Add drive to otherwise-absolute path: