CMake: Move code from CMakeProject into BuildDirManager

This is in preparation for having support for cmake's server
mode.

Change-Id: I6cc04fe7c5132c491c3f3c0f46560b8ad88808e8
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2016-10-06 11:31:15 +02:00
parent 414b816b0c
commit 9b40c1fc04
8 changed files with 90 additions and 106 deletions

View File

@@ -28,9 +28,11 @@
#include "cmakekitinformation.h" #include "cmakekitinformation.h"
#include "cmakeparser.h" #include "cmakeparser.h"
#include "cmakeprojectmanager.h" #include "cmakeprojectmanager.h"
#include "cmakeprojectnodes.h"
#include "cmaketool.h" #include "cmaketool.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/documentmanager.h>
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/kit.h> #include <projectexplorer/kit.h>
@@ -54,6 +56,8 @@
#include <QSet> #include <QSet>
#include <QTemporaryDir> #include <QTemporaryDir>
using namespace ProjectExplorer;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Helper: // Helper:
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@@ -61,7 +65,7 @@
namespace CMakeProjectManager { namespace CMakeProjectManager {
namespace Internal { namespace Internal {
static QStringList toArguments(const CMakeConfig &config, const ProjectExplorer::Kit *k) { static QStringList toArguments(const CMakeConfig &config, const Kit *k) {
return Utils::transform(config, [k](const CMakeConfigItem &i) -> QString { return Utils::transform(config, [k](const CMakeConfigItem &i) -> QString {
QString a = QString::fromLatin1("-D"); QString a = QString::fromLatin1("-D");
a.append(QString::fromUtf8(i.key)); a.append(QString::fromUtf8(i.key));
@@ -110,10 +114,11 @@ BuildDirManager::~BuildDirManager()
{ {
stopProcess(); stopProcess();
resetData(); resetData();
qDeleteAll(m_watchedFiles);
delete m_tempDir; delete m_tempDir;
} }
const ProjectExplorer::Kit *BuildDirManager::kit() const const Kit *BuildDirManager::kit() const
{ {
return m_buildConfiguration->target()->kit(); return m_buildConfiguration->target()->kit();
} }
@@ -202,6 +207,38 @@ bool BuildDirManager::persistCMakeState()
return true; return true;
} }
void BuildDirManager::generateProjectTree(CMakeProjectNode *root)
{
root->setDisplayName(m_projectName);
// Delete no longer necessary file watcher:
const QSet<Utils::FileName> currentWatched
= Utils::transform(m_watchedFiles, [](CMakeFile *cmf) { return cmf->filePath(); });
const QSet<Utils::FileName> toWatch = m_cmakeFiles;
QSet<Utils::FileName> toDelete = currentWatched;
toDelete.subtract(toWatch);
m_watchedFiles = Utils::filtered(m_watchedFiles, [&toDelete](Internal::CMakeFile *cmf) {
if (toDelete.contains(cmf->filePath())) {
delete cmf;
return false;
}
return true;
});
// Add new file watchers:
QSet<Utils::FileName> toAdd = toWatch;
toAdd.subtract(currentWatched);
foreach (const Utils::FileName &fn, toAdd) {
CMakeFile *cm = new CMakeFile(this, fn);
Core::DocumentManager::addDocument(cm);
m_watchedFiles.insert(cm);
}
QList<FileNode *> fileNodes = m_files;
root->buildTree(fileNodes);
m_files.clear(); // Some of the FileNodes in files() were deleted!
}
void BuildDirManager::parse() void BuildDirManager::parse()
{ {
checkConfiguration(); checkConfiguration();
@@ -247,31 +284,11 @@ void BuildDirManager::clearCache()
forceReparse(); forceReparse();
} }
QString BuildDirManager::projectName() const
{
return m_projectName;
}
QList<CMakeBuildTarget> BuildDirManager::buildTargets() const QList<CMakeBuildTarget> BuildDirManager::buildTargets() const
{ {
return m_buildTargets; return m_buildTargets;
} }
QList<ProjectExplorer::FileNode *> BuildDirManager::files()
{
return m_files;
}
QSet<Utils::FileName> BuildDirManager::cmakeFiles()
{
return m_cmakeFiles;
}
void BuildDirManager::clearFiles()
{
m_files.clear();
}
CMakeConfig BuildDirManager::parsedConfiguration() const CMakeConfig BuildDirManager::parsedConfiguration() const
{ {
if (m_cmakeCache.isEmpty()) { if (m_cmakeCache.isEmpty()) {
@@ -350,7 +367,7 @@ void BuildDirManager::extractData()
resetData(); resetData();
m_projectName = sourceDirectory().fileName(); m_projectName = sourceDirectory().fileName();
m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); m_files.append(new FileNode(topCMake, ProjectFileType, false));
// Do not insert topCMake into m_cmakeFiles: The project already watches that! // Do not insert topCMake into m_cmakeFiles: The project already watches that!
// Find cbp file // Find cbp file
@@ -376,13 +393,13 @@ void BuildDirManager::extractData()
m_files = cbpparser.fileList(); m_files = cbpparser.fileList();
if (cbpparser.hasCMakeFiles()) { if (cbpparser.hasCMakeFiles()) {
m_files.append(cbpparser.cmakeFileList()); m_files.append(cbpparser.cmakeFileList());
foreach (const ProjectExplorer::FileNode *node, cbpparser.cmakeFileList()) foreach (const FileNode *node, cbpparser.cmakeFileList())
m_cmakeFiles.insert(node->filePath()); m_cmakeFiles.insert(node->filePath());
} }
// Make sure the top cmakelists.txt file is always listed: // Make sure the top cmakelists.txt file is always listed:
if (!Utils::contains(m_files, [topCMake](ProjectExplorer::FileNode *fn) { return fn->filePath() == topCMake; })) { if (!Utils::contains(m_files, [topCMake](FileNode *fn) { return fn->filePath() == topCMake; })) {
m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); m_files.append(new FileNode(topCMake, ProjectFileType, false));
} }
m_buildTargets = cbpparser.buildTargets(); m_buildTargets = cbpparser.buildTargets();
@@ -409,14 +426,14 @@ void BuildDirManager::startCMake(CMakeTool *tool, const QStringList &generatorAr
m_parser = new CMakeParser; m_parser = new CMakeParser;
QDir source = QDir(sourceDirectory().toString()); QDir source = QDir(sourceDirectory().toString());
connect(m_parser, &ProjectExplorer::IOutputParser::addTask, m_parser, connect(m_parser, &IOutputParser::addTask, m_parser,
[source](const ProjectExplorer::Task &task) { [source](const Task &task) {
if (task.file.isEmpty() || task.file.toFileInfo().isAbsolute()) { if (task.file.isEmpty() || task.file.toFileInfo().isAbsolute()) {
ProjectExplorer::TaskHub::addTask(task); TaskHub::addTask(task);
} else { } else {
ProjectExplorer::Task t = task; Task t = task;
t.file = Utils::FileName::fromString(source.absoluteFilePath(task.file.toString())); t.file = Utils::FileName::fromString(source.absoluteFilePath(task.file.toString()));
ProjectExplorer::TaskHub::addTask(t); TaskHub::addTask(t);
} }
}); });
@@ -440,7 +457,7 @@ void BuildDirManager::startCMake(CMakeTool *tool, const QStringList &generatorAr
Utils::QtcProcess::addArgs(&args, generatorArgs); Utils::QtcProcess::addArgs(&args, generatorArgs);
Utils::QtcProcess::addArgs(&args, toArguments(config, kit())); Utils::QtcProcess::addArgs(&args, toArguments(config, kit()));
ProjectExplorer::TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
Core::MessageManager::write(tr("Running \"%1 %2\" in %3.") Core::MessageManager::write(tr("Running \"%1 %2\" in %3.")
.arg(tool->cmakeExecutable().toUserOutput()) .arg(tool->cmakeExecutable().toUserOutput())
@@ -478,8 +495,7 @@ void BuildDirManager::cmakeFinished(int code, QProcess::ExitStatus status)
if (!msg.isEmpty()) { if (!msg.isEmpty()) {
Core::MessageManager::write(msg); Core::MessageManager::write(msg);
ProjectExplorer::TaskHub::addTask(ProjectExplorer::Task::Error, msg, TaskHub::addTask(Task::Error, msg, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
m_future->reportCanceled(); m_future->reportCanceled();
} else { } else {
m_future->setProgressValue(1); m_future->setProgressValue(1);
@@ -526,7 +542,7 @@ void BuildDirManager::checkConfiguration()
if (m_tempDir) // always throw away changes in the tmpdir! if (m_tempDir) // always throw away changes in the tmpdir!
return; return;
ProjectExplorer::Kit *k = m_buildConfiguration->target()->kit(); Kit *k = m_buildConfiguration->target()->kit();
const CMakeConfig cache = parsedConfiguration(); const CMakeConfig cache = parsedConfiguration();
if (cache.isEmpty()) if (cache.isEmpty())
return; // No cache file yet. return; // No cache file yet.
@@ -664,6 +680,15 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile
return result; return result;
} }
void BuildDirManager::handleCmakeFileChange()
{
Target *t = m_buildConfiguration->target()->project()->activeTarget();
BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr;
if (m_buildConfiguration->target() == t && m_buildConfiguration == bc)
cmakeFilesChanged();
}
void BuildDirManager::maybeForceReparse() void BuildDirManager::maybeForceReparse()
{ {
checkConfiguration(); checkConfiguration();

View File

@@ -27,6 +27,7 @@
#include "cmakecbpparser.h" #include "cmakecbpparser.h"
#include "cmakeconfigitem.h" #include "cmakeconfigitem.h"
#include "cmakefile.h"
#include <projectexplorer/task.h> #include <projectexplorer/task.h>
@@ -66,15 +67,8 @@ public:
BuildDirManager(CMakeBuildConfiguration *bc); BuildDirManager(CMakeBuildConfiguration *bc);
~BuildDirManager() override; ~BuildDirManager() override;
const ProjectExplorer::Kit *kit() const;
const Utils::FileName buildDirectory() const;
const Utils::FileName workDirectory() const;
const Utils::FileName sourceDirectory() const;
const CMakeConfig intendedConfiguration() const;
bool isParsing() const; bool isParsing() const;
void cmakeFilesChanged();
void parse(); void parse();
void clearCache(); void clearCache();
void forceReparse(); void forceReparse();
@@ -82,24 +76,33 @@ public:
void resetData(); void resetData();
bool persistCMakeState(); bool persistCMakeState();
QString projectName() const; void generateProjectTree(CMakeProjectNode *root);
QList<CMakeBuildTarget> buildTargets() const; QList<CMakeBuildTarget> buildTargets() const;
QList<ProjectExplorer::FileNode *> files();
QSet<Utils::FileName> cmakeFiles();
void clearFiles();
CMakeConfig parsedConfiguration() const; CMakeConfig parsedConfiguration() const;
void checkConfiguration(); void checkConfiguration();
static CMakeConfig parseConfiguration(const Utils::FileName &cacheFile, void handleCmakeFileChange();
QString *errorMessage);
signals: signals:
void configurationStarted() const; void configurationStarted() const;
void dataAvailable() const; void dataAvailable() const;
void errorOccured(const QString &err) const; void errorOccured(const QString &err) const;
protected:
static CMakeConfig parseConfiguration(const Utils::FileName &cacheFile,
QString *errorMessage);
const ProjectExplorer::Kit *kit() const;
const Utils::FileName buildDirectory() const;
const Utils::FileName workDirectory() const;
const Utils::FileName sourceDirectory() const;
const CMakeConfig intendedConfiguration() const;
private: private:
void cmakeFilesChanged();
void stopProcess(); void stopProcess();
void cleanUpProcess(); void cleanUpProcess();
void extractData(); void extractData();
@@ -127,6 +130,8 @@ private:
QFutureInterface<void> *m_future = nullptr; QFutureInterface<void> *m_future = nullptr;
QTimer m_reparseTimer; QTimer m_reparseTimer;
QSet<Internal::CMakeFile *> m_watchedFiles;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -71,11 +71,6 @@ CMakeBuildConfiguration::~CMakeBuildConfiguration()
m_buildDirManager->deleteLater(); // Do not block while waiting for cmake... m_buildDirManager->deleteLater(); // Do not block while waiting for cmake...
} }
void CMakeBuildConfiguration::cmakeFilesChanged()
{
m_buildDirManager->cmakeFilesChanged();
}
bool CMakeBuildConfiguration::isEnabled() const bool CMakeBuildConfiguration::isEnabled() const
{ {
return m_error.isEmpty(); return m_error.isEmpty();

View File

@@ -52,8 +52,6 @@ public:
CMakeBuildConfiguration(ProjectExplorer::Target *parent); CMakeBuildConfiguration(ProjectExplorer::Target *parent);
~CMakeBuildConfiguration(); ~CMakeBuildConfiguration();
void cmakeFilesChanged();
bool isEnabled() const override; bool isEnabled() const override;
QString disabledReason() const override; QString disabledReason() const override;

View File

@@ -24,7 +24,8 @@
****************************************************************************/ ****************************************************************************/
#include "cmakefile.h" #include "cmakefile.h"
#include "cmakeproject.h"
#include "builddirmanager.h"
#include "cmakeprojectconstants.h" #include "cmakeprojectconstants.h"
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
@@ -36,7 +37,7 @@ using namespace Utils;
namespace CMakeProjectManager { namespace CMakeProjectManager {
namespace Internal { namespace Internal {
CMakeFile::CMakeFile(CMakeProject *project, const FileName &fileName) : m_project(project) CMakeFile::CMakeFile(BuildDirManager *bdm, const FileName &fileName) : m_buildDirManager(bdm)
{ {
setId("Cmake.ProjectFile"); setId("Cmake.ProjectFile");
setMimeType(QLatin1String(Constants::CMAKEPROJECTMIMETYPE)); setMimeType(QLatin1String(Constants::CMAKEPROJECTMIMETYPE));
@@ -56,7 +57,7 @@ bool CMakeFile::reload(QString *errorString, Core::IDocument::ReloadFlag flag, C
Q_UNUSED(flag); Q_UNUSED(flag);
if (type != TypePermissions) if (type != TypePermissions)
m_project->handleCmakeFileChanged(); m_buildDirManager->handleCmakeFileChange();
return true; return true;
} }

View File

@@ -28,20 +28,20 @@
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
namespace CMakeProjectManager { namespace CMakeProjectManager {
class CMakeProject;
namespace Internal { namespace Internal {
class BuildDirManager;
class CMakeFile : public Core::IDocument class CMakeFile : public Core::IDocument
{ {
public: public:
CMakeFile(CMakeProject *project, const Utils::FileName &fileName); CMakeFile(BuildDirManager *bdm, const Utils::FileName &fileName);
ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override;
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override; bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
private: private:
CMakeProject *m_project; BuildDirManager *m_buildDirManager;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -53,6 +53,7 @@
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <qtsupport/baseqtversion.h> #include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
#include <texteditor/textdocument.h>
#include <cpptools/generatedcodemodelsupport.h> #include <cpptools/generatedcodemodelsupport.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
@@ -89,13 +90,13 @@ CMakeProject::CMakeProject(CMakeManager *manager, const FileName &fileName)
{ {
setId(Constants::CMAKEPROJECT_ID); setId(Constants::CMAKEPROJECT_ID);
setProjectManager(manager); setProjectManager(manager);
setDocument(new Internal::CMakeFile(this, fileName)); setDocument(new TextEditor::TextDocument);
document()->setFilePath(fileName);
setRootProjectNode(new CMakeProjectNode(Utils::FileName::fromString(fileName.toFileInfo().absolutePath()))); setRootProjectNode(new CMakeProjectNode(Utils::FileName::fromString(fileName.toFileInfo().absolutePath())));
setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT));
setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX));
Core::DocumentManager::addDocument(document());
rootProjectNode()->setDisplayName(fileName.parentDir().fileName()); rootProjectNode()->setDisplayName(fileName.parentDir().fileName());
connect(this, &CMakeProject::activeTargetChanged, this, &CMakeProject::handleActiveTargetChanged); connect(this, &CMakeProject::activeTargetChanged, this, &CMakeProject::handleActiveTargetChanged);
@@ -105,7 +106,6 @@ CMakeProject::~CMakeProject()
{ {
setRootProjectNode(nullptr); setRootProjectNode(nullptr);
m_codeModelFuture.cancel(); m_codeModelFuture.cancel();
qDeleteAll(m_watchedFiles);
qDeleteAll(m_extraCompilers); qDeleteAll(m_extraCompilers);
} }
@@ -219,34 +219,7 @@ void CMakeProject::updateProjectData()
BuildDirManager *bdm = cmakeBc->buildDirManager(); BuildDirManager *bdm = cmakeBc->buildDirManager();
QTC_ASSERT(bdm, return); QTC_ASSERT(bdm, return);
rootProjectNode()->setDisplayName(bdm->projectName()); bdm->generateProjectTree(static_cast<CMakeProjectNode *>(rootProjectNode()));
// Delete no longer necessary file watcher:
const QSet<Utils::FileName> currentWatched
= Utils::transform(m_watchedFiles, [](CMakeFile *cmf) { return cmf->filePath(); });
const QSet<Utils::FileName> toWatch = bdm->cmakeFiles();
QSet<Utils::FileName> toDelete = currentWatched;
toDelete.subtract(toWatch);
m_watchedFiles = Utils::filtered(m_watchedFiles, [&toDelete](Internal::CMakeFile *cmf) {
if (toDelete.contains(cmf->filePath())) {
delete cmf;
return false;
}
return true;
});
// Add new file watchers:
QSet<Utils::FileName> toAdd = toWatch;
toAdd.subtract(currentWatched);
foreach (const Utils::FileName &fn, toAdd) {
CMakeFile *cm = new CMakeFile(this, fn);
Core::DocumentManager::addDocument(cm);
m_watchedFiles.insert(cm);
}
QList<FileNode *> fileNodes = bdm->files();
rootProjectNode()->buildTree(fileNodes);
bdm->clearFiles(); // Some of the FileNodes in files() were deleted!
updateApplicationAndDeploymentTargets(); updateApplicationAndDeploymentTargets();
updateTargetRunConfigurations(t); updateTargetRunConfigurations(t);
@@ -459,15 +432,6 @@ bool CMakeProject::setupTarget(Target *t)
return true; return true;
} }
void CMakeProject::handleCmakeFileChanged()
{
if (Target *t = activeTarget()) {
if (auto bc = qobject_cast<CMakeBuildConfiguration *>(t->activeBuildConfiguration())) {
bc->cmakeFilesChanged();
}
}
}
void CMakeProject::handleActiveTargetChanged() void CMakeProject::handleActiveTargetChanged()
{ {
if (m_connectedTarget) { if (m_connectedTarget) {

View File

@@ -110,8 +110,6 @@ protected:
bool setupTarget(ProjectExplorer::Target *t) final; bool setupTarget(ProjectExplorer::Target *t) final;
private: private:
void handleCmakeFileChanged();
void handleActiveTargetChanged(); void handleActiveTargetChanged();
void handleActiveBuildConfigurationChanged(); void handleActiveBuildConfigurationChanged();
void handleParsingStarted(); void handleParsingStarted();
@@ -133,8 +131,6 @@ private:
QFuture<void> m_codeModelFuture; QFuture<void> m_codeModelFuture;
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers; QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
QSet<Internal::CMakeFile *> m_watchedFiles;
friend class Internal::CMakeBuildConfiguration; friend class Internal::CMakeBuildConfiguration;
friend class Internal::CMakeFile; friend class Internal::CMakeFile;
}; };