CMake: Trigger cmake run *before* build when files changed

Make sure to run cmake *before* cmake --build when cmake files just
got saved. This helps e.g. when editing CMakeLists.txt files and the
hitting "Built" and "Save all" (or "Always save before build").

Task-number: QTCREATORBUG-16187
Change-Id: I16b1d02eb342a447003380946ce7a9d785476a0e
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Tobias Hunger
2016-10-06 15:55:55 +02:00
parent 4d7420fe49
commit b17c98ad6f
5 changed files with 42 additions and 6 deletions

View File

@@ -34,6 +34,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/documentmanager.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/project.h>
@@ -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'))

View File

@@ -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:

View File

@@ -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())

View File

@@ -76,6 +76,7 @@ public:
void maybeForceReparse();
void resetData();
bool persistCMakeState();
bool updateCMakeStateBeforeBuild();
void runCMake();
void clearCache();
@@ -111,7 +112,7 @@ private:
mutable QList<CMakeConfigItem> m_completeConfigurationCache;
BuildDirManager *m_buildDirManager = nullptr;
BuildDirManager *const m_buildDirManager = nullptr;
friend class CMakeBuildSettingsWidget;
friend class CMakeProjectManager::CMakeProject;

View File

@@ -235,9 +235,18 @@ void CMakeBuildStep::run(QFutureInterface<bool> &fi)
bc = qobject_cast<CMakeBuildConfiguration *>(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,