diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 34011b5118a..2f874da3bde 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -106,8 +107,10 @@ BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) : m_projectName = sourceDirectory().fileName(); m_reparseTimer.setSingleShot(true); - m_reparseTimer.setInterval(2000); + connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse); + connect(Core::EditorManager::instance(), &Core::EditorManager::aboutToSave, + this, &BuildDirManager::handleDocumentSaves); } BuildDirManager::~BuildDirManager() @@ -164,7 +167,7 @@ void BuildDirManager::cmakeFilesChanged() if (!tool->isAutoRun()) return; - m_reparseTimer.start(); + m_reparseTimer.start(1000); } void BuildDirManager::forceReparse() @@ -191,6 +194,11 @@ void BuildDirManager::resetData() m_files.clear(); } +bool BuildDirManager::updateCMakeStateBeforeBuild() +{ + return m_reparseTimer.isActive(); +} + bool BuildDirManager::persistCMakeState() { if (!m_tempDir) @@ -592,6 +600,14 @@ void BuildDirManager::checkConfiguration() } } +void BuildDirManager::handleDocumentSaves(Core::IDocument *document) +{ + if (!m_cmakeFiles.contains(document->filePath())) + return; + + m_reparseTimer.start(100); +} + static QByteArray trimCMakeCacheLine(const QByteArray &in) { int start = 0; while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t')) diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index cadb88a9e2e..9d1ee2b10ef 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -44,6 +44,8 @@ QT_FORWARD_DECLARE_CLASS(QTemporaryDir); QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher); +namespace Core { class IDocument; } + namespace ProjectExplorer { class FileNode; class IOutputParser; @@ -74,6 +76,7 @@ public: void forceReparse(); void maybeForceReparse(); // Only reparse if the configuration has changed... void resetData(); + bool updateCMakeStateBeforeBuild(); bool persistCMakeState(); void generateProjectTree(CMakeProjectNode *root); @@ -83,6 +86,7 @@ public: void checkConfiguration(); + void handleDocumentSaves(Core::IDocument *document); void handleCmakeFileChange(); signals: diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 8d16cee12c0..4291eec4de7 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -61,7 +61,8 @@ const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.In const char CONFIGURATION_KEY[] = "CMake.Configuration"; CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) : - BuildConfiguration(parent, Core::Id(Constants::CMAKE_BC_ID)) + BuildConfiguration(parent, Core::Id(Constants::CMAKE_BC_ID)), + m_buildDirManager(new BuildDirManager(this)) { ctor(); } @@ -84,7 +85,8 @@ QString CMakeBuildConfiguration::disabledReason() const CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration *source) : BuildConfiguration(parent, source), - m_configuration(source->m_configuration) + m_configuration(source->m_configuration), + m_buildDirManager(new BuildDirManager(this)) { ctor(); cloneSteps(source); @@ -137,7 +139,6 @@ void CMakeBuildConfiguration::ctor() target()->kit(), displayName(), BuildConfiguration::Unknown)); - m_buildDirManager = new BuildDirManager(this); connect(m_buildDirManager, &BuildDirManager::dataAvailable, this, &CMakeBuildConfiguration::dataAvailable); connect(m_buildDirManager, &BuildDirManager::errorOccured, @@ -174,6 +175,11 @@ bool CMakeBuildConfiguration::persistCMakeState() return m_buildDirManager->persistCMakeState(); } +bool CMakeBuildConfiguration::updateCMakeStateBeforeBuild() +{ + return m_buildDirManager->updateCMakeStateBeforeBuild(); +} + void CMakeBuildConfiguration::runCMake() { if (!m_buildDirManager || m_buildDirManager->isParsing()) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index a4798cc1992..ea98c7b1ba9 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -76,6 +76,7 @@ public: void maybeForceReparse(); void resetData(); bool persistCMakeState(); + bool updateCMakeStateBeforeBuild(); void runCMake(); void clearCache(); @@ -111,7 +112,7 @@ private: mutable QList m_completeConfigurationCache; - BuildDirManager *m_buildDirManager = nullptr; + BuildDirManager *const m_buildDirManager = nullptr; friend class CMakeBuildSettingsWidget; friend class CMakeProjectManager::CMakeProject; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index a89020f034c..accdfc84034 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -235,9 +235,18 @@ void CMakeBuildStep::run(QFutureInterface &fi) bc = qobject_cast(target()->activeBuildConfiguration()); QTC_ASSERT(bc, return); + bool mustDelay = false; if (bc->persistCMakeState()) { emit addOutput(tr("Persisting CMake state..."), BuildStep::MessageOutput); + mustDelay = true; + } else if (bc->updateCMakeStateBeforeBuild()) { + emit addOutput(tr("Running CMake in preparation to build..."), BuildStep::MessageOutput); + mustDelay = true; + } else { + mustDelay = false; + } + if (mustDelay) { m_runTrigger = connect(bc, &CMakeBuildConfiguration::dataAvailable, this, [this, &fi]() { runImpl(fi); }); m_errorTrigger = connect(bc, &CMakeBuildConfiguration::errorOccured,