Commit b17c98ad authored by Tobias Hunger's avatar Tobias Hunger

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's avatarTobias Hunger <tobias.hunger@qt.io>
parent 4d7420fe
......@@ -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'))
......
......@@ -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:
......
......@@ -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())
......
......@@ -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;
......
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment