forked from qt-creator/qt-creator
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:
@@ -34,6 +34,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
#include <projectexplorer/kit.h>
|
#include <projectexplorer/kit.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
@@ -106,8 +107,10 @@ BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) :
|
|||||||
m_projectName = sourceDirectory().fileName();
|
m_projectName = sourceDirectory().fileName();
|
||||||
|
|
||||||
m_reparseTimer.setSingleShot(true);
|
m_reparseTimer.setSingleShot(true);
|
||||||
m_reparseTimer.setInterval(2000);
|
|
||||||
connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse);
|
connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse);
|
||||||
|
connect(Core::EditorManager::instance(), &Core::EditorManager::aboutToSave,
|
||||||
|
this, &BuildDirManager::handleDocumentSaves);
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildDirManager::~BuildDirManager()
|
BuildDirManager::~BuildDirManager()
|
||||||
@@ -164,7 +167,7 @@ void BuildDirManager::cmakeFilesChanged()
|
|||||||
if (!tool->isAutoRun())
|
if (!tool->isAutoRun())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_reparseTimer.start();
|
m_reparseTimer.start(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildDirManager::forceReparse()
|
void BuildDirManager::forceReparse()
|
||||||
@@ -191,6 +194,11 @@ void BuildDirManager::resetData()
|
|||||||
m_files.clear();
|
m_files.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BuildDirManager::updateCMakeStateBeforeBuild()
|
||||||
|
{
|
||||||
|
return m_reparseTimer.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
bool BuildDirManager::persistCMakeState()
|
bool BuildDirManager::persistCMakeState()
|
||||||
{
|
{
|
||||||
if (!m_tempDir)
|
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) {
|
static QByteArray trimCMakeCacheLine(const QByteArray &in) {
|
||||||
int start = 0;
|
int start = 0;
|
||||||
while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t'))
|
while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t'))
|
||||||
|
@@ -44,6 +44,8 @@
|
|||||||
QT_FORWARD_DECLARE_CLASS(QTemporaryDir);
|
QT_FORWARD_DECLARE_CLASS(QTemporaryDir);
|
||||||
QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher);
|
QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher);
|
||||||
|
|
||||||
|
namespace Core { class IDocument; }
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class FileNode;
|
class FileNode;
|
||||||
class IOutputParser;
|
class IOutputParser;
|
||||||
@@ -74,6 +76,7 @@ public:
|
|||||||
void forceReparse();
|
void forceReparse();
|
||||||
void maybeForceReparse(); // Only reparse if the configuration has changed...
|
void maybeForceReparse(); // Only reparse if the configuration has changed...
|
||||||
void resetData();
|
void resetData();
|
||||||
|
bool updateCMakeStateBeforeBuild();
|
||||||
bool persistCMakeState();
|
bool persistCMakeState();
|
||||||
|
|
||||||
void generateProjectTree(CMakeProjectNode *root);
|
void generateProjectTree(CMakeProjectNode *root);
|
||||||
@@ -83,6 +86,7 @@ public:
|
|||||||
|
|
||||||
void checkConfiguration();
|
void checkConfiguration();
|
||||||
|
|
||||||
|
void handleDocumentSaves(Core::IDocument *document);
|
||||||
void handleCmakeFileChange();
|
void handleCmakeFileChange();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@@ -61,7 +61,8 @@ const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.In
|
|||||||
const char CONFIGURATION_KEY[] = "CMake.Configuration";
|
const char CONFIGURATION_KEY[] = "CMake.Configuration";
|
||||||
|
|
||||||
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) :
|
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();
|
ctor();
|
||||||
}
|
}
|
||||||
@@ -84,7 +85,8 @@ QString CMakeBuildConfiguration::disabledReason() const
|
|||||||
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent,
|
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent,
|
||||||
CMakeBuildConfiguration *source) :
|
CMakeBuildConfiguration *source) :
|
||||||
BuildConfiguration(parent, source),
|
BuildConfiguration(parent, source),
|
||||||
m_configuration(source->m_configuration)
|
m_configuration(source->m_configuration),
|
||||||
|
m_buildDirManager(new BuildDirManager(this))
|
||||||
{
|
{
|
||||||
ctor();
|
ctor();
|
||||||
cloneSteps(source);
|
cloneSteps(source);
|
||||||
@@ -137,7 +139,6 @@ void CMakeBuildConfiguration::ctor()
|
|||||||
target()->kit(),
|
target()->kit(),
|
||||||
displayName(), BuildConfiguration::Unknown));
|
displayName(), BuildConfiguration::Unknown));
|
||||||
|
|
||||||
m_buildDirManager = new BuildDirManager(this);
|
|
||||||
connect(m_buildDirManager, &BuildDirManager::dataAvailable,
|
connect(m_buildDirManager, &BuildDirManager::dataAvailable,
|
||||||
this, &CMakeBuildConfiguration::dataAvailable);
|
this, &CMakeBuildConfiguration::dataAvailable);
|
||||||
connect(m_buildDirManager, &BuildDirManager::errorOccured,
|
connect(m_buildDirManager, &BuildDirManager::errorOccured,
|
||||||
@@ -174,6 +175,11 @@ bool CMakeBuildConfiguration::persistCMakeState()
|
|||||||
return m_buildDirManager->persistCMakeState();
|
return m_buildDirManager->persistCMakeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CMakeBuildConfiguration::updateCMakeStateBeforeBuild()
|
||||||
|
{
|
||||||
|
return m_buildDirManager->updateCMakeStateBeforeBuild();
|
||||||
|
}
|
||||||
|
|
||||||
void CMakeBuildConfiguration::runCMake()
|
void CMakeBuildConfiguration::runCMake()
|
||||||
{
|
{
|
||||||
if (!m_buildDirManager || m_buildDirManager->isParsing())
|
if (!m_buildDirManager || m_buildDirManager->isParsing())
|
||||||
|
@@ -76,6 +76,7 @@ public:
|
|||||||
void maybeForceReparse();
|
void maybeForceReparse();
|
||||||
void resetData();
|
void resetData();
|
||||||
bool persistCMakeState();
|
bool persistCMakeState();
|
||||||
|
bool updateCMakeStateBeforeBuild();
|
||||||
void runCMake();
|
void runCMake();
|
||||||
void clearCache();
|
void clearCache();
|
||||||
|
|
||||||
@@ -111,7 +112,7 @@ private:
|
|||||||
|
|
||||||
mutable QList<CMakeConfigItem> m_completeConfigurationCache;
|
mutable QList<CMakeConfigItem> m_completeConfigurationCache;
|
||||||
|
|
||||||
BuildDirManager *m_buildDirManager = nullptr;
|
BuildDirManager *const m_buildDirManager = nullptr;
|
||||||
|
|
||||||
friend class CMakeBuildSettingsWidget;
|
friend class CMakeBuildSettingsWidget;
|
||||||
friend class CMakeProjectManager::CMakeProject;
|
friend class CMakeProjectManager::CMakeProject;
|
||||||
|
@@ -235,9 +235,18 @@ void CMakeBuildStep::run(QFutureInterface<bool> &fi)
|
|||||||
bc = qobject_cast<CMakeBuildConfiguration *>(target()->activeBuildConfiguration());
|
bc = qobject_cast<CMakeBuildConfiguration *>(target()->activeBuildConfiguration());
|
||||||
QTC_ASSERT(bc, return);
|
QTC_ASSERT(bc, return);
|
||||||
|
|
||||||
|
bool mustDelay = false;
|
||||||
if (bc->persistCMakeState()) {
|
if (bc->persistCMakeState()) {
|
||||||
emit addOutput(tr("Persisting CMake state..."), BuildStep::MessageOutput);
|
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,
|
m_runTrigger = connect(bc, &CMakeBuildConfiguration::dataAvailable,
|
||||||
this, [this, &fi]() { runImpl(fi); });
|
this, [this, &fi]() { runImpl(fi); });
|
||||||
m_errorTrigger = connect(bc, &CMakeBuildConfiguration::errorOccured,
|
m_errorTrigger = connect(bc, &CMakeBuildConfiguration::errorOccured,
|
||||||
|
Reference in New Issue
Block a user