From b9a7cfcaa1f058c6d6b123c6d9abaa9da92d9f5a Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Mon, 20 Oct 2014 17:23:07 +0200 Subject: [PATCH] Detect qt sub projects and special case their build directory Check every project's path against the source paths of all existing qts. If we find a match, make it build in the right place by default. Works for both in source and shadow builds. Note: There's a quadratic algorithm since foreach kit we check against all qt versions. That's unlikely to be a problem and non trivial to fix. Change-Id: I9f3456f3e835ee6adc35c26fe5c328c01387a8aa Reviewed-by: Tobias Hunger --- .../qmakebuildconfiguration.cpp | 19 +++++++++++++++--- .../qmakeprojectmanager/qmakeproject.cpp | 20 +++++++++++++++++++ .../qmakeprojectmanager/qmakeproject.h | 1 + src/plugins/qtsupport/baseqtversion.cpp | 16 +++++++++++++++ src/plugins/qtsupport/baseqtversion.h | 2 ++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 83063dc2282..37f871cb2a2 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -648,8 +648,22 @@ QmakeBuildInfo *QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k, // Leave info->buildDirectory unset; info->kitId = k->id(); info->supportsShadowBuild = (version && version->supportsShadowBuilds()); - info->buildDirectory - = defaultBuildDirectory(info->supportsShadowBuild, projectPath, k, suffix); + + // check if this project is in the source directory: + Utils::FileName projectFilePath = Utils::FileName::fromString(projectPath); + if (version->isInSourceDirectory(projectFilePath)) { + // assemble build directory + QString projectDirectory = projectFilePath.toFileInfo().absolutePath(); + QDir qtSourceDir = QDir(version->sourcePath().toString()); + QString relativeProjectPath = qtSourceDir.relativeFilePath(projectDirectory); + QString qtBuildDir = version->versionInfo().value(QStringLiteral("QT_INSTALL_PREFIX")); + QString absoluteBuildPath = QDir::cleanPath(qtBuildDir + QLatin1Char('/') + relativeProjectPath); + + info->buildDirectory = Utils::FileName::fromString(absoluteBuildPath); + } else { + info->buildDirectory + = defaultBuildDirectory(info->supportsShadowBuild, projectPath, k, suffix); + } info->type = type; return info; } @@ -682,7 +696,6 @@ QList QmakeBuildConfigurationFactory::availableSetups(const Kit *k, QList result; result << createBuildInfo(k, projectPath, ProjectExplorer::BuildConfiguration::Debug); result << createBuildInfo(k, projectPath, ProjectExplorer::BuildConfiguration::Release); - return result; } diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 945a8d814dc..625e83e5971 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -362,6 +363,10 @@ QmakeProject::QmakeProject(QmakeManager *manager, const QString &fileName) : connect(BuildManager::instance(), SIGNAL(buildQueueFinished(bool)), SLOT(buildFinished(bool))); + + setPreferredKitMatcher(KitMatcher([this](const Kit *kit) -> bool { + return matchesKit(kit); + })); } QmakeProject::~QmakeProject() @@ -1605,6 +1610,21 @@ void QmakeProject::collectLibraryData(const QmakeProFileNode *node, DeploymentDa } } +bool QmakeProject::matchesKit(const Kit *kit) +{ + QList parentQts; + Utils::FileName filePath = projectFilePath(); + foreach (QtSupport::BaseQtVersion *version, QtSupport::QtVersionManager::validVersions()) { + if (version->isInSourceDirectory(filePath)) + parentQts.append(version); + } + + QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit); + if (!parentQts.isEmpty()) + return parentQts.contains(version); + return true; +} + QString QmakeProject::executableFor(const QmakeProFileNode *node) { const ProjectExplorer::Kit * const kit = activeTarget()->kit(); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index 2e0892a1aa6..92457e383d5 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -177,6 +177,7 @@ private: ProjectExplorer::DeploymentData &deploymentData); void collectLibraryData(const QmakeProFileNode *node, ProjectExplorer::DeploymentData &deploymentData); + bool matchesKit(const ProjectExplorer::Kit *kit); QmakeManager *m_manager; QmakeProFileNode *m_rootProjectNode; diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 430c1d49e2e..423f79da1cb 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1450,6 +1450,10 @@ FileName BaseQtVersion::mkspecFromVersionInfo(const QHash &ver FileName BaseQtVersion::sourcePath(const QHash &versionInfo) { + const QString qt5Source = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX/src"); + if (!qt5Source.isEmpty()) + return Utils::FileName::fromString(qt5Source); + const QString installData = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX"); QString sourcePath = installData; QFile qmakeCache(installData + QLatin1String("/.qmake.cache")); @@ -1471,6 +1475,18 @@ FileName BaseQtVersion::sourcePath(const QHash &versionInfo) return FileName::fromUserInput(sourcePath); } +bool BaseQtVersion::isInSourceDirectory(const Utils::FileName &filePath) +{ + const Utils::FileName &source = sourcePath(); + if (source.isEmpty()) + return false; + QDir dir = QDir(source.toString()); + if (dir.dirName() == QLatin1String("qtbase")) + dir.cdUp(); + + return filePath.isChildOf(dir); +} + bool BaseQtVersion::isQmlDebuggingSupported(Kit *k, QString *reason) { QTC_ASSERT(k, return false); diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h index e2016cf47ca..a04510d0ba6 100644 --- a/src/plugins/qtsupport/baseqtversion.h +++ b/src/plugins/qtsupport/baseqtversion.h @@ -124,6 +124,8 @@ public: virtual Utils::Environment qmakeRunEnvironment() const; virtual Utils::FileName sourcePath() const; + bool isInSourceDirectory(const Utils::FileName &filePath); + // used by UiCodeModelSupport virtual QString uicCommand() const; virtual QString designerCommand() const;