diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index b5f6e8d230d..dfee2040b68 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -1298,7 +1298,7 @@ bool QmakeProFile::isFileFromWildcard(const QString &filePath) const QmakeEvalInput QmakeProFile::evalInput() const { QmakeEvalInput input; - input.projectDir = directoryPath().toString(); + input.projectDir = directoryPath().toFSPathString(); input.projectFilePath = filePath(); input.buildDirectory = m_buildSystem->buildDir(m_filePath); 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 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. - bpReader->setOutputDir(input.buildDirectory.path()); + bpReader->setOutputDir(input.buildDirectory.toFSPathString()); bpReader->setCumulative(cumulative); bpReader->setExtraVars(basevars); bpReader->setExtraConfigs(basecfgs); @@ -1369,7 +1368,7 @@ QmakeEvalResultPtr QmakeProFile::evaluate(const QmakeEvalInput &input) QtSupport::ProFileReader *exactBuildPassReader = nullptr; QtSupport::ProFileReader *cumulativeBuildPassReader = nullptr; 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 cumulOk = evaluateOne(input, pro, input.readerCumulative, true, &cumulativeBuildPassReader); pro->deref(); @@ -1473,9 +1472,9 @@ QmakeEvalResultPtr QmakeProFile::evaluate(const QmakeEvalInput &input) QHash> cumulativeSourceFiles; const QStringList baseVPathsExact - = baseVPaths(exactReader, input.projectDir, input.buildDirectory.toString()); + = baseVPaths(exactReader, input.projectDir, input.buildDirectory.toFSPathString()); const QStringList baseVPathsCumulative - = baseVPaths(cumulativeReader, input.projectDir, input.buildDirectory.toString()); + = baseVPaths(cumulativeReader, input.projectDir, input.buildDirectory.toFSPathString()); for (int i = 0; i < static_cast(FileType::FileTypeSize); ++i) { const auto type = static_cast(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 // 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.toString()); + result->installsList = installsList(exactBuildPassReader, + input.projectFilePath.toFSPathString(), + input.projectDir, + input.buildDirectory.toFSPathString()); extractInstalls(proToResult, &result->includedFiles.result, result->installsList); 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::PkgConfig] = exactReader->values(QLatin1String("PKGCONFIG")); 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::Config] = exactReader->values(QLatin1String("CONFIG")); 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")); if (QFileInfo(path).isRelative()) - path = QDir::cleanPath(buildDir.toString() + QLatin1Char('/') + path); + path = QDir::cleanPath(buildDir.toFSPathString() + QLatin1Char('/') + path); return path; } @@ -1790,7 +1791,7 @@ QString QmakeProFile::mocDirPath(QtSupport::ProFileReader *reader, const FilePat { QString path = reader->value(QLatin1String("MOC_DIR")); if (QFileInfo(path).isRelative()) - path = QDir::cleanPath(buildDir.toString() + QLatin1Char('/') + path); + path = QDir::cleanPath(buildDir.toFSPathString() + QLatin1Char('/') + path); return path; } @@ -1835,10 +1836,11 @@ QStringList QmakeProFile::includePaths(QtSupport::ProFileReader *reader, const F const QString uiDir = uiDirPath(reader, buildDir); const QVector elList = reader->fixifiedValues( - QLatin1String("INCLUDEPATH"), projectDir, buildDir.toString(), false); + QLatin1String("INCLUDEPATH"), projectDir, buildDir.toFSPathString(), false); for (const ProFileEvaluator::SourceFile &el : elList) { - const QString sysrootifiedPath = sysrootify(el.fileName, sysroot.toString(), projectDir, - buildDir.toString()); + const QString sysrootifiedPath = sysrootify(el.fileName, sysroot.toFSPathString(), + projectDir, + buildDir.toFSPathString()); if (IoUtils::isAbsolutePath(sysrootifiedPath) && (IoUtils::exists(sysrootifiedPath) || sysrootifiedPath == mocDir || sysrootifiedPath == uiDir)) { diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 6c8103c52b1..86b7a3c8c55 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -801,14 +801,31 @@ static FileNode *fileNodeOf(FolderNode *in, const FilePath &fileName) 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(); - FilePath buildDir = buildConfigBuildDir.isEmpty() + const FilePath buildDir = buildConfigBuildDir.isEmpty() ? projectDirectory() : 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) @@ -837,17 +854,19 @@ QtSupport::ProFileReader *QmakeBuildSystem::createProFileReader(const QmakeProFi m_qmakeSysroot = SysRootKitAspect::sysRoot(k).toString(); 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()); } - 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(); for (; eit != eend; ++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(); QtSupport::ProFileCacheManager::instance()->incRefCount(); @@ -870,9 +889,8 @@ QtSupport::ProFileReader *QmakeBuildSystem::createProFileReader(const QmakeProFi auto reader = new QtSupport::ProFileReader(m_qmakeGlobals.get(), m_qmakeVfs); - // FIXME: Currently intentional. // 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; } diff --git a/src/shared/proparser/ioutils.cpp b/src/shared/proparser/ioutils.cpp index e23f2361909..4bd00ccaf93 100644 --- a/src/shared/proparser/ioutils.cpp +++ b/src/shared/proparser/ioutils.cpp @@ -24,24 +24,28 @@ QT_BEGIN_NAMESPACE using namespace QMakeInternal; +static bool isGenericPath(const QStringView fileName) +{ + static const QString specialRoot = QDir::rootPath() + "__qtc_devices__/"; + return fileName.startsWith(specialRoot); +} + IoUtils::FileType IoUtils::fileType(const QString &fileName) { - // FIXME: - if (fileName.startsWith("docker:/")) { - 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 (isGenericPath(fileName)) { + QFileInfo fi(fileName); + if (fi.isDir()) + return FileIsDir; + if (fi.isFile()) + return FileIsRegular; + return FileNotFound; } - if (!QFileInfo::exists(fileName)) // FIXME make pro parser work with non-local + if (!QFileInfo::exists(fileName)) return FileNotFound; Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName)); + #ifdef Q_OS_WIN DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16()); if (attr == INVALID_FILE_ATTRIBUTES) @@ -61,6 +65,10 @@ bool IoUtils::isRelativePath(const QString &path) if (path.startsWith(QLatin1String(":/"))) return false; #endif + + if (isGenericPath(path)) + return QFileInfo(path).isRelative(); + #ifdef Q_OS_WIN // Unlike QFileInfo, this considers only paths with both a drive prefix and // a subsequent (back-)slash absolute: @@ -95,6 +103,10 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName) { if (fileName.isEmpty()) return QString(); + + if (isGenericPath(fileName)) + return baseDir + '/' + fileName; + if (isAbsolutePath(fileName)) return QDir::cleanPath(fileName); #ifdef Q_OS_WIN // Add drive to otherwise-absolute path: