forked from qt-creator/qt-creator
CMake: Remove BuildDirManager
The BuildDirManager was used to switch between different BuildDirReaders. Now that only the FileApiReader is left, that infrastructure is no longer needed. Change-Id: I2d339a3407bb633cff6a8f7502b7b09094f63fef Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -3,7 +3,6 @@ add_qtc_plugin(CMakeProjectManager
|
|||||||
PLUGIN_DEPENDS Core CppTools ProjectExplorer TextEditor QtSupport
|
PLUGIN_DEPENDS Core CppTools ProjectExplorer TextEditor QtSupport
|
||||||
PLUGIN_RECOMMENDS Designer
|
PLUGIN_RECOMMENDS Designer
|
||||||
SOURCES
|
SOURCES
|
||||||
builddirmanager.cpp builddirmanager.h
|
|
||||||
builddirparameters.cpp builddirparameters.h
|
builddirparameters.cpp builddirparameters.h
|
||||||
cmake_global.h
|
cmake_global.h
|
||||||
cmakeautocompleter.cpp cmakeautocompleter.h
|
cmakeautocompleter.cpp cmakeautocompleter.h
|
||||||
|
@@ -1,567 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "builddirmanager.h"
|
|
||||||
|
|
||||||
#include "cmakebuildconfiguration.h"
|
|
||||||
#include "cmakebuildstep.h"
|
|
||||||
#include "cmakebuildsystem.h"
|
|
||||||
#include "cmakeprojectnodes.h"
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
|
||||||
#include <projectexplorer/taskhub.h>
|
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include <app/app_version.h>
|
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
|
||||||
using namespace Utils;
|
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(cmakeBuildDirManagerLog, "qtc.cmake.builddirmanager", QtWarningMsg);
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
// BuildDirManager:
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
BuildDirManager::BuildDirManager(CMakeBuildSystem *buildSystem)
|
|
||||||
: m_buildSystem(buildSystem)
|
|
||||||
{
|
|
||||||
assert(buildSystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildDirManager::~BuildDirManager() = default;
|
|
||||||
|
|
||||||
FilePath BuildDirManager::workDirectory(const BuildDirParameters ¶meters) const
|
|
||||||
{
|
|
||||||
const Utils::FilePath bdir = parameters.buildDirectory;
|
|
||||||
const CMakeTool *cmake = parameters.cmakeTool();
|
|
||||||
if (bdir.exists()) {
|
|
||||||
m_buildDirToTempDir.erase(bdir);
|
|
||||||
return bdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmake && cmake->autoCreateBuildDirectory()) {
|
|
||||||
if (!m_buildSystem->buildConfiguration()->createBuildDirectory())
|
|
||||||
emitErrorOccurred(
|
|
||||||
tr("Failed to create build directory \"%1\".").arg(bdir.toUserOutput()));
|
|
||||||
return bdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto tmpDirIt = m_buildDirToTempDir.find(bdir);
|
|
||||||
if (tmpDirIt == m_buildDirToTempDir.end()) {
|
|
||||||
auto ret = m_buildDirToTempDir.emplace(std::make_pair(bdir, std::make_unique<Utils::TemporaryDirectory>("qtc-cmake-XXXXXXXX")));
|
|
||||||
QTC_ASSERT(ret.second, return bdir);
|
|
||||||
tmpDirIt = ret.first;
|
|
||||||
|
|
||||||
if (!tmpDirIt->second->isValid()) {
|
|
||||||
emitErrorOccurred(tr("Failed to create temporary directory \"%1\".")
|
|
||||||
.arg(QDir::toNativeSeparators(tmpDirIt->second->path())));
|
|
||||||
return bdir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Utils::FilePath::fromString(tmpDirIt->second->path());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::updateReparseParameters(const int parameters)
|
|
||||||
{
|
|
||||||
m_reparseParameters |= parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BuildDirManager::takeReparseParameters()
|
|
||||||
{
|
|
||||||
int result = m_reparseParameters;
|
|
||||||
m_reparseParameters = REPARSE_DEFAULT;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::emitDataAvailable()
|
|
||||||
{
|
|
||||||
if (!isParsing())
|
|
||||||
emit dataAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::emitErrorOccurred(const QString &message) const
|
|
||||||
{
|
|
||||||
m_isHandlingError = true;
|
|
||||||
emit errorOccurred(message);
|
|
||||||
m_isHandlingError = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::emitReparseRequest() const
|
|
||||||
{
|
|
||||||
if (m_reparseParameters & REPARSE_URGENT) {
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "emitting requestReparse";
|
|
||||||
emit requestReparse();
|
|
||||||
} else {
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "emitting requestDelayedReparse";
|
|
||||||
emit requestDelayedReparse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildDirManager::hasConfigChanged()
|
|
||||||
{
|
|
||||||
checkConfiguration();
|
|
||||||
|
|
||||||
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
|
|
||||||
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
|
|
||||||
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
|
|
||||||
const QByteArray CMAKE_C_COMPILER_KEY = "CMAKE_C_COMPILER";
|
|
||||||
const QByteArray CMAKE_CXX_COMPILER_KEY = "CMAKE_CXX_COMPILER";
|
|
||||||
|
|
||||||
const QByteArrayList criticalKeys
|
|
||||||
= {GENERATOR_KEY, CMAKE_COMMAND_KEY, CMAKE_C_COMPILER_KEY, CMAKE_CXX_COMPILER_KEY};
|
|
||||||
|
|
||||||
QString errorMessage;
|
|
||||||
const CMakeConfig currentConfig = takeCMakeConfiguration(errorMessage);
|
|
||||||
if (!errorMessage.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const CMakeTool *tool = m_parameters.cmakeTool();
|
|
||||||
QTC_ASSERT(tool, return false); // No cmake... we should not have ended up here in the first place
|
|
||||||
const QString extraKitGenerator = m_parameters.extraGenerator;
|
|
||||||
const QString mainKitGenerator = m_parameters.generator;
|
|
||||||
CMakeConfig targetConfig = m_parameters.configuration;
|
|
||||||
targetConfig.append(CMakeConfigItem(GENERATOR_KEY, CMakeConfigItem::INTERNAL,
|
|
||||||
QByteArray(), mainKitGenerator.toUtf8()));
|
|
||||||
if (!extraKitGenerator.isEmpty())
|
|
||||||
targetConfig.append(CMakeConfigItem(EXTRA_GENERATOR_KEY, CMakeConfigItem::INTERNAL,
|
|
||||||
QByteArray(), extraKitGenerator.toUtf8()));
|
|
||||||
targetConfig.append(CMakeConfigItem(CMAKE_COMMAND_KEY, CMakeConfigItem::INTERNAL,
|
|
||||||
QByteArray(), tool->cmakeExecutable().toUserOutput().toUtf8()));
|
|
||||||
Utils::sort(targetConfig, CMakeConfigItem::sortOperator());
|
|
||||||
|
|
||||||
bool mustReparse = false;
|
|
||||||
auto ccit = currentConfig.constBegin();
|
|
||||||
auto kcit = targetConfig.constBegin();
|
|
||||||
|
|
||||||
while (ccit != currentConfig.constEnd() && kcit != targetConfig.constEnd()) {
|
|
||||||
if (ccit->key == kcit->key) {
|
|
||||||
if (ccit->value != kcit->value) {
|
|
||||||
if (criticalKeys.contains(kcit->key)) {
|
|
||||||
clearCache();
|
|
||||||
return false; // no need to trigger a new reader, clearCache will do that
|
|
||||||
}
|
|
||||||
mustReparse = true;
|
|
||||||
}
|
|
||||||
++ccit;
|
|
||||||
++kcit;
|
|
||||||
} else {
|
|
||||||
if (ccit->key < kcit->key) {
|
|
||||||
++ccit;
|
|
||||||
} else {
|
|
||||||
++kcit;
|
|
||||||
mustReparse = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have keys that do not exist yet, then reparse.
|
|
||||||
//
|
|
||||||
// The critical keys *must* be set in cmake configuration, so those were already
|
|
||||||
// handled above.
|
|
||||||
return mustReparse || kcit != targetConfig.constEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(expander, return );
|
|
||||||
|
|
||||||
const FilePath buildDir = workDirectory(m_parameters);
|
|
||||||
QTC_ASSERT(buildDir.exists(), return );
|
|
||||||
|
|
||||||
const FilePath settingsFile = buildDir.pathAppended("qtcsettings.cmake");
|
|
||||||
|
|
||||||
QByteArray contents;
|
|
||||||
contents.append("# This file is managed by Qt Creator, do not edit!\n\n");
|
|
||||||
contents.append(
|
|
||||||
transform(m_parameters.configuration,
|
|
||||||
[expander](const CMakeConfigItem &item) { return item.toCMakeSetLine(expander); })
|
|
||||||
.join('\n')
|
|
||||||
.toUtf8());
|
|
||||||
|
|
||||||
QFile file(settingsFile.toString());
|
|
||||||
QTC_ASSERT(file.open(QFile::WriteOnly | QFile::Truncate), return );
|
|
||||||
file.write(contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildDirManager::isParsing() const
|
|
||||||
{
|
|
||||||
return m_reader && m_reader->isParsing();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::stopParsingAndClearState()
|
|
||||||
{
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "stopping parsing run!";
|
|
||||||
m_reader.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
|
||||||
const int reparseParameters)
|
|
||||||
{
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "setting parameters and requesting reparse";
|
|
||||||
if (!parameters.cmakeTool()) {
|
|
||||||
TaskHub::addTask(BuildSystemTask(Task::Error, tr(
|
|
||||||
"The kit needs to define a CMake tool to parse this project.")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QTC_ASSERT(parameters.isValid(), return );
|
|
||||||
|
|
||||||
m_parameters = parameters;
|
|
||||||
m_parameters.workDirectory = workDirectory(parameters);
|
|
||||||
updateReparseParameters(reparseParameters);
|
|
||||||
|
|
||||||
QTC_CHECK(!m_reader); // The parsing should have stopped at this time already!
|
|
||||||
m_reader = std::make_unique<FileApiReader>();
|
|
||||||
|
|
||||||
connect(m_reader.get(),
|
|
||||||
&FileApiReader::configurationStarted,
|
|
||||||
this,
|
|
||||||
&BuildDirManager::parsingStarted);
|
|
||||||
connect(m_reader.get(),
|
|
||||||
&FileApiReader::dataAvailable,
|
|
||||||
this,
|
|
||||||
&BuildDirManager::emitDataAvailable);
|
|
||||||
connect(m_reader.get(),
|
|
||||||
&FileApiReader::errorOccurred,
|
|
||||||
this,
|
|
||||||
&BuildDirManager::emitErrorOccurred);
|
|
||||||
connect(m_reader.get(), &FileApiReader::dirty, this, &BuildDirManager::becameDirty);
|
|
||||||
|
|
||||||
m_reader->setParameters(m_parameters);
|
|
||||||
emitReparseRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
CMakeBuildSystem *BuildDirManager::buildSystem() const
|
|
||||||
{
|
|
||||||
return m_buildSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePath BuildDirManager::buildDirectory() const
|
|
||||||
{
|
|
||||||
return m_parameters.buildDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::becameDirty()
|
|
||||||
{
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "BuildDirManager: becameDirty was triggered.";
|
|
||||||
if (isParsing() || !buildSystem())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const CMakeTool *tool = m_parameters.cmakeTool();
|
|
||||||
if (!tool->isAutoRun())
|
|
||||||
return;
|
|
||||||
|
|
||||||
updateReparseParameters(REPARSE_CHECK_CONFIGURATION | REPARSE_SCAN);
|
|
||||||
emit requestReparse();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::resetData()
|
|
||||||
{
|
|
||||||
m_reader.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildDirManager::persistCMakeState()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_parameters.isValid(), return false);
|
|
||||||
|
|
||||||
if (m_parameters.workDirectory == m_parameters.buildDirectory)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!m_buildSystem->buildConfiguration()->createBuildDirectory())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
BuildDirParameters newParameters = m_parameters;
|
|
||||||
newParameters.workDirectory.clear();
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "Requesting parse due to persisting CMake State";
|
|
||||||
setParametersAndRequestParse(newParameters,
|
|
||||||
REPARSE_URGENT | REPARSE_FORCE_CMAKE_RUN
|
|
||||||
| REPARSE_FORCE_CONFIGURATION | REPARSE_CHECK_CONFIGURATION);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::requestFilesystemScan()
|
|
||||||
{
|
|
||||||
updateReparseParameters(REPARSE_SCAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildDirManager::isFilesystemScanRequested() const
|
|
||||||
{
|
|
||||||
return m_reparseParameters & REPARSE_SCAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::parse()
|
|
||||||
{
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "parsing!";
|
|
||||||
QTC_ASSERT(m_parameters.isValid(), return );
|
|
||||||
QTC_ASSERT(m_reader, return );
|
|
||||||
QTC_ASSERT(!m_reader->isParsing(), return );
|
|
||||||
|
|
||||||
m_reader->stop();
|
|
||||||
|
|
||||||
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
|
||||||
|
|
||||||
int reparseParameters = takeReparseParameters();
|
|
||||||
|
|
||||||
qCDebug(cmakeBuildDirManagerLog)
|
|
||||||
<< "Parse called with flags:" << flagsString(reparseParameters);
|
|
||||||
|
|
||||||
const QString cache = m_parameters.workDirectory.pathAppended("CMakeCache.txt").toString();
|
|
||||||
if (!QFileInfo::exists(cache)) {
|
|
||||||
reparseParameters |= REPARSE_FORCE_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN;
|
|
||||||
qCDebug(cmakeBuildDirManagerLog)
|
|
||||||
<< "No" << cache << "file found, new flags:" << flagsString(reparseParameters);
|
|
||||||
} else if (reparseParameters & REPARSE_CHECK_CONFIGURATION) {
|
|
||||||
if (checkConfiguration()) {
|
|
||||||
reparseParameters |= REPARSE_FORCE_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN;
|
|
||||||
qCDebug(cmakeBuildDirManagerLog)
|
|
||||||
<< "Config check triggered flags change:" << flagsString(reparseParameters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeConfigurationIntoBuildDirectory(m_parameters.expander);
|
|
||||||
|
|
||||||
qCDebug(cmakeBuildDirManagerLog) << "Asking reader to parse";
|
|
||||||
m_reader->parse(reparseParameters & REPARSE_FORCE_CMAKE_RUN,
|
|
||||||
reparseParameters & REPARSE_FORCE_CONFIGURATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSet<FilePath> BuildDirManager::projectFilesToWatch() const
|
|
||||||
{
|
|
||||||
QTC_ASSERT(!m_isHandlingError, return {});
|
|
||||||
QTC_ASSERT(m_reader, return {});
|
|
||||||
|
|
||||||
Utils::FilePath sourceDir = m_parameters.sourceDirectory;
|
|
||||||
Utils::FilePath buildDir = m_parameters.workDirectory;
|
|
||||||
|
|
||||||
return Utils::filtered(m_reader->projectFilesToWatch(),
|
|
||||||
[&sourceDir,
|
|
||||||
&buildDir](const Utils::FilePath &p) {
|
|
||||||
return p.isChildOf(sourceDir)
|
|
||||||
|| p.isChildOf(buildDir);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<CMakeProjectNode> BuildDirManager::generateProjectTree(
|
|
||||||
const QList<const FileNode *> &allFiles, QString &errorMessage) const
|
|
||||||
{
|
|
||||||
QTC_ASSERT(!m_isHandlingError, return {});
|
|
||||||
QTC_ASSERT(m_reader, return {});
|
|
||||||
|
|
||||||
return m_reader->generateProjectTree(allFiles, errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
RawProjectParts BuildDirManager::createRawProjectParts(QString &errorMessage) const
|
|
||||||
{
|
|
||||||
QTC_ASSERT(!m_isHandlingError, return {});
|
|
||||||
QTC_ASSERT(m_reader, return {});
|
|
||||||
return m_reader->createRawProjectParts(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildDirManager::clearCache()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_parameters.isValid(), return);
|
|
||||||
QTC_ASSERT(!m_isHandlingError, return);
|
|
||||||
|
|
||||||
const FilePath cmakeCache = m_parameters.workDirectory / "CMakeCache.txt";
|
|
||||||
const FilePath cmakeFiles = m_parameters.workDirectory / "CMakeFiles";
|
|
||||||
|
|
||||||
const bool mustCleanUp = cmakeCache.exists() || cmakeFiles.exists();
|
|
||||||
if (!mustCleanUp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Utils::FileUtils::removeRecursively(cmakeCache);
|
|
||||||
Utils::FileUtils::removeRecursively(cmakeFiles);
|
|
||||||
|
|
||||||
m_reader.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
static CMakeBuildTarget utilityTarget(const QString &title, const BuildDirManager *bdm)
|
|
||||||
{
|
|
||||||
CMakeBuildTarget target;
|
|
||||||
|
|
||||||
target.title = title;
|
|
||||||
target.targetType = UtilityType;
|
|
||||||
target.workingDirectory = bdm->buildDirectory();
|
|
||||||
target.sourceDirectory = bdm->buildSystem()->project()->projectDirectory();
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<CMakeBuildTarget> BuildDirManager::takeBuildTargets(QString &errorMessage) const
|
|
||||||
{
|
|
||||||
QList<CMakeBuildTarget> result = { utilityTarget(CMakeBuildStep::allTarget(), this),
|
|
||||||
utilityTarget(CMakeBuildStep::cleanTarget(), this),
|
|
||||||
utilityTarget(CMakeBuildStep::installTarget(), this),
|
|
||||||
utilityTarget(CMakeBuildStep::testTarget(), this) };
|
|
||||||
QTC_ASSERT(!m_isHandlingError, return result);
|
|
||||||
|
|
||||||
if (m_reader) {
|
|
||||||
QList<CMakeBuildTarget> readerTargets
|
|
||||||
= Utils::filtered(m_reader->takeBuildTargets(errorMessage),
|
|
||||||
[](const CMakeBuildTarget &bt) {
|
|
||||||
return bt.title != CMakeBuildStep::allTarget()
|
|
||||||
&& bt.title != CMakeBuildStep::cleanTarget()
|
|
||||||
&& bt.title != CMakeBuildStep::installTarget()
|
|
||||||
&& bt.title != CMakeBuildStep::testTarget();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Guess at the target definition position when no details are known
|
|
||||||
for (CMakeBuildTarget &t : readerTargets) {
|
|
||||||
if (t.backtrace.isEmpty()) {
|
|
||||||
t.backtrace.append(
|
|
||||||
FolderNode::LocationInfo(tr("CMakeLists.txt in source directory"),
|
|
||||||
t.sourceDirectory.pathAppended("CMakeLists.txt")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.append(readerTargets);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMakeConfig BuildDirManager::takeCMakeConfiguration(QString &errorMessage) const
|
|
||||||
{
|
|
||||||
if (!m_reader)
|
|
||||||
return CMakeConfig();
|
|
||||||
|
|
||||||
CMakeConfig result = m_reader->takeParsedConfiguration(errorMessage);
|
|
||||||
for (auto &ci : result)
|
|
||||||
ci.inCMakeCache = true;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMakeConfig BuildDirManager::parseCMakeConfiguration(const Utils::FilePath &cacheFile,
|
|
||||||
QString *errorMessage)
|
|
||||||
{
|
|
||||||
if (!cacheFile.exists()) {
|
|
||||||
if (errorMessage)
|
|
||||||
*errorMessage = tr("CMakeCache.txt file not found.");
|
|
||||||
return { };
|
|
||||||
}
|
|
||||||
CMakeConfig result = CMakeConfigItem::itemsFromFile(cacheFile, errorMessage);
|
|
||||||
if (!errorMessage->isEmpty())
|
|
||||||
return { };
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString BuildDirManager::flagsString(int reparseFlags)
|
|
||||||
{
|
|
||||||
QString result;
|
|
||||||
if (reparseFlags == REPARSE_DEFAULT) {
|
|
||||||
result = "<NONE>";
|
|
||||||
} else {
|
|
||||||
if (reparseFlags & REPARSE_URGENT)
|
|
||||||
result += " URGENT";
|
|
||||||
if (reparseFlags & REPARSE_FORCE_CMAKE_RUN)
|
|
||||||
result += " FORCE_CMAKE_RUN";
|
|
||||||
if (reparseFlags & REPARSE_FORCE_CONFIGURATION)
|
|
||||||
result += " FORCE_CONFIG";
|
|
||||||
if (reparseFlags & REPARSE_CHECK_CONFIGURATION)
|
|
||||||
result += " CHECK_CONFIG";
|
|
||||||
if (reparseFlags & REPARSE_SCAN)
|
|
||||||
result += " SCAN";
|
|
||||||
}
|
|
||||||
return result.trimmed();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildDirManager::checkConfiguration()
|
|
||||||
{
|
|
||||||
if (m_parameters.workDirectory != m_parameters.buildDirectory) // always throw away changes in the tmpdir!
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const CMakeConfig cache = m_buildSystem->cmakeBuildConfiguration()->configurationFromCMake();
|
|
||||||
if (cache.isEmpty())
|
|
||||||
return false; // No cache file yet.
|
|
||||||
|
|
||||||
CMakeConfig newConfig;
|
|
||||||
QHash<QString, QPair<QString, QString>> changedKeys;
|
|
||||||
foreach (const CMakeConfigItem &projectItem, m_parameters.configuration) {
|
|
||||||
const QString projectKey = QString::fromUtf8(projectItem.key);
|
|
||||||
const QString projectValue = projectItem.expandedValue(m_parameters.expander);
|
|
||||||
const CMakeConfigItem &cmakeItem
|
|
||||||
= Utils::findOrDefault(cache, [&projectItem](const CMakeConfigItem &i) { return i.key == projectItem.key; });
|
|
||||||
const QString iCacheValue = QString::fromUtf8(cmakeItem.value);
|
|
||||||
if (cmakeItem.isNull()) {
|
|
||||||
changedKeys.insert(projectKey, qMakePair(tr("<removed>"), projectValue));
|
|
||||||
} else if (iCacheValue != projectValue) {
|
|
||||||
changedKeys.insert(projectKey, qMakePair(iCacheValue, projectValue));
|
|
||||||
newConfig.append(cmakeItem);
|
|
||||||
} else {
|
|
||||||
newConfig.append(projectItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!changedKeys.isEmpty()) {
|
|
||||||
QStringList keyList = changedKeys.keys();
|
|
||||||
Utils::sort(keyList);
|
|
||||||
QString table = QString::fromLatin1("<table><tr><th>%1</th><th>%2</th><th>%3</th></tr>")
|
|
||||||
.arg(tr("Key"))
|
|
||||||
.arg(tr("%1 Project").arg(Core::Constants::IDE_DISPLAY_NAME))
|
|
||||||
.arg(tr("Changed value"));
|
|
||||||
foreach (const QString &k, keyList) {
|
|
||||||
const QPair<QString, QString> data = changedKeys.value(k);
|
|
||||||
table += QString::fromLatin1("\n<tr><td>%1</td><td>%2</td><td>%3</td></tr>")
|
|
||||||
.arg(k)
|
|
||||||
.arg(data.second.toHtmlEscaped())
|
|
||||||
.arg(data.first.toHtmlEscaped());
|
|
||||||
}
|
|
||||||
table += QLatin1String("\n</table>");
|
|
||||||
|
|
||||||
QPointer<QMessageBox> box = new QMessageBox(Core::ICore::mainWindow());
|
|
||||||
box->setText(tr("The project has been changed outside of %1.")
|
|
||||||
.arg(Core::Constants::IDE_DISPLAY_NAME));
|
|
||||||
box->setInformativeText(table);
|
|
||||||
auto *defaultButton = box->addButton(tr("Discard External Changes"),
|
|
||||||
QMessageBox::RejectRole);
|
|
||||||
auto *applyButton = box->addButton(tr("Adapt %1 Project to Changes")
|
|
||||||
.arg(Core::Constants::IDE_DISPLAY_NAME),
|
|
||||||
QMessageBox::ApplyRole);
|
|
||||||
box->setDefaultButton(defaultButton);
|
|
||||||
|
|
||||||
box->exec();
|
|
||||||
if (box->clickedButton() == applyButton) {
|
|
||||||
m_parameters.configuration = newConfig;
|
|
||||||
QSignalBlocker blocker(m_buildSystem->buildConfiguration());
|
|
||||||
m_buildSystem->cmakeBuildConfiguration()->setConfigurationForCMake(newConfig);
|
|
||||||
return false;
|
|
||||||
} else if (box->clickedButton() == defaultButton)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace CMakeProjectManager
|
|
@@ -1,134 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "builddirparameters.h"
|
|
||||||
#include "cmakebuildtarget.h"
|
|
||||||
#include "fileapireader.h"
|
|
||||||
|
|
||||||
#include <projectexplorer/rawprojectpart.h>
|
|
||||||
|
|
||||||
#include <utils/fileutils.h>
|
|
||||||
#include <utils/temporarydirectory.h>
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace ProjectExplorer { class FileNode; }
|
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class CMakeBuildConfiguration;
|
|
||||||
class CMakeBuildSystem;
|
|
||||||
class CMakeProjectNode;
|
|
||||||
|
|
||||||
class BuildDirManager final : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum ReparseParameters {
|
|
||||||
REPARSE_DEFAULT = 0, // Nothing special:-)
|
|
||||||
REPARSE_FORCE_CMAKE_RUN = (1 << 0), // Force cmake to run
|
|
||||||
REPARSE_FORCE_CONFIGURATION = (1 << 1), // Force configuration arguments to cmake
|
|
||||||
REPARSE_CHECK_CONFIGURATION = (1 << 2), // Check for on-disk config and QtC config diff
|
|
||||||
REPARSE_SCAN = (1 << 3), // Run filesystem scan
|
|
||||||
REPARSE_URGENT = (1 << 4), // Do not delay the parser run by 1s
|
|
||||||
};
|
|
||||||
|
|
||||||
static QString flagsString(int reparseFlags);
|
|
||||||
|
|
||||||
explicit BuildDirManager(CMakeBuildSystem *buildSystem);
|
|
||||||
~BuildDirManager() final;
|
|
||||||
|
|
||||||
bool isParsing() const;
|
|
||||||
|
|
||||||
void stopParsingAndClearState();
|
|
||||||
|
|
||||||
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
|
||||||
const int reparseOptions);
|
|
||||||
// nullptr if the BC is not active anymore!
|
|
||||||
CMakeBuildSystem *buildSystem() const;
|
|
||||||
Utils::FilePath buildDirectory() const;
|
|
||||||
|
|
||||||
void clearCache();
|
|
||||||
|
|
||||||
void resetData();
|
|
||||||
bool persistCMakeState();
|
|
||||||
|
|
||||||
void requestFilesystemScan();
|
|
||||||
bool isFilesystemScanRequested() const;
|
|
||||||
void parse();
|
|
||||||
|
|
||||||
QSet<Utils::FilePath> projectFilesToWatch() const;
|
|
||||||
std::unique_ptr<CMakeProjectNode> generateProjectTree(const QList<const ProjectExplorer::FileNode *> &allFiles,
|
|
||||||
QString &errorMessage) const;
|
|
||||||
ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage) const;
|
|
||||||
|
|
||||||
QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) const;
|
|
||||||
CMakeConfig takeCMakeConfiguration(QString &errorMessage) const;
|
|
||||||
|
|
||||||
static CMakeConfig parseCMakeConfiguration(const Utils::FilePath &cacheFile,
|
|
||||||
QString *errorMessage);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void requestReparse() const;
|
|
||||||
void requestDelayedReparse() const;
|
|
||||||
void parsingStarted() const;
|
|
||||||
void dataAvailable() const;
|
|
||||||
void errorOccurred(const QString &err) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updateReparseParameters(const int parameters);
|
|
||||||
int takeReparseParameters();
|
|
||||||
|
|
||||||
void emitDataAvailable();
|
|
||||||
void emitErrorOccurred(const QString &message) const;
|
|
||||||
void emitReparseRequest() const;
|
|
||||||
bool checkConfiguration();
|
|
||||||
|
|
||||||
Utils::FilePath workDirectory(const BuildDirParameters ¶meters) const;
|
|
||||||
|
|
||||||
bool hasConfigChanged();
|
|
||||||
|
|
||||||
void writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander);
|
|
||||||
|
|
||||||
void becameDirty();
|
|
||||||
|
|
||||||
BuildDirParameters m_parameters;
|
|
||||||
int m_reparseParameters;
|
|
||||||
CMakeBuildSystem *m_buildSystem = nullptr;
|
|
||||||
mutable std::unordered_map<Utils::FilePath, std::unique_ptr<Utils::TemporaryDirectory>> m_buildDirToTempDir;
|
|
||||||
mutable std::unique_ptr<FileApiReader> m_reader;
|
|
||||||
mutable bool m_isHandlingError = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace CMakeProjectManager
|
|
@@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "cmakebuildconfiguration.h"
|
#include "cmakebuildconfiguration.h"
|
||||||
|
|
||||||
#include "builddirmanager.h"
|
|
||||||
#include "cmakebuildsettingswidget.h"
|
#include "cmakebuildsettingswidget.h"
|
||||||
#include "cmakebuildstep.h"
|
#include "cmakebuildstep.h"
|
||||||
#include "cmakebuildsystem.h"
|
#include "cmakebuildsystem.h"
|
||||||
|
@@ -35,7 +35,6 @@ class CMakeProject;
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class BuildDirManager;
|
|
||||||
class CMakeBuildSystem;
|
class CMakeBuildSystem;
|
||||||
class CMakeBuildSettingsWidget;
|
class CMakeBuildSettingsWidget;
|
||||||
|
|
||||||
@@ -97,7 +96,6 @@ private:
|
|||||||
friend class CMakeBuildSettingsWidget;
|
friend class CMakeBuildSettingsWidget;
|
||||||
friend class CMakeBuildSystem;
|
friend class CMakeBuildSystem;
|
||||||
friend class CMakeProject;
|
friend class CMakeProject;
|
||||||
friend class BuildDirManager;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMakeProjectImporter;
|
class CMakeProjectImporter;
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "cmakebuildsystem.h"
|
#include "cmakebuildsystem.h"
|
||||||
|
|
||||||
|
#include "builddirparameters.h"
|
||||||
#include "cmakebuildconfiguration.h"
|
#include "cmakebuildconfiguration.h"
|
||||||
#include "cmakekitinformation.h"
|
#include "cmakekitinformation.h"
|
||||||
#include "cmakeprojectconstants.h"
|
#include "cmakeprojectconstants.h"
|
||||||
@@ -42,10 +43,12 @@
|
|||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/taskhub.h>
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
|
||||||
#include <qtsupport/qtcppkitinfo.h>
|
#include <qtsupport/qtcppkitinfo.h>
|
||||||
|
|
||||||
|
#include <app/app_version.h>
|
||||||
|
|
||||||
#include <utils/checkablemessagebox.h>
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/mimetypes/mimetype.h>
|
#include <utils/mimetypes/mimetype.h>
|
||||||
@@ -55,6 +58,7 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -138,7 +142,6 @@ static Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarnin
|
|||||||
|
|
||||||
CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
|
CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
|
||||||
: BuildSystem(bc)
|
: BuildSystem(bc)
|
||||||
, m_buildDirManager(this)
|
|
||||||
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
|
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
|
||||||
{
|
{
|
||||||
// TreeScanner:
|
// TreeScanner:
|
||||||
@@ -177,26 +180,17 @@ CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
|
|||||||
return type;
|
return type;
|
||||||
});
|
});
|
||||||
|
|
||||||
// BuildDirManager:
|
connect(&m_reader, &FileApiReader::configurationStarted, this, [this]() {
|
||||||
connect(&m_buildDirManager, &BuildDirManager::requestReparse, this, [this] {
|
|
||||||
if (cmakeBuildConfiguration()->isActive())
|
|
||||||
requestParse();
|
|
||||||
});
|
|
||||||
connect(&m_buildDirManager, &BuildDirManager::requestDelayedReparse, this, [this] {
|
|
||||||
if (cmakeBuildConfiguration()->isActive())
|
|
||||||
requestDelayedParse();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(&m_buildDirManager, &BuildDirManager::dataAvailable,
|
|
||||||
this, &CMakeBuildSystem::handleParsingSucceeded);
|
|
||||||
|
|
||||||
connect(&m_buildDirManager, &BuildDirManager::errorOccurred,
|
|
||||||
this, &CMakeBuildSystem::handleParsingFailed);
|
|
||||||
|
|
||||||
connect(&m_buildDirManager, &BuildDirManager::parsingStarted, this, [this]() {
|
|
||||||
cmakeBuildConfiguration()->clearError(CMakeBuildConfiguration::ForceEnabledChanged::True);
|
cmakeBuildConfiguration()->clearError(CMakeBuildConfiguration::ForceEnabledChanged::True);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(&m_reader,
|
||||||
|
&FileApiReader::dataAvailable,
|
||||||
|
this,
|
||||||
|
&CMakeBuildSystem::handleParsingSucceeded);
|
||||||
|
connect(&m_reader, &FileApiReader::errorOccurred, this, &CMakeBuildSystem::handleParsingFailed);
|
||||||
|
connect(&m_reader, &FileApiReader::dirty, this, &CMakeBuildSystem::becameDirty);
|
||||||
|
|
||||||
connect(SessionManager::instance(),
|
connect(SessionManager::instance(),
|
||||||
&SessionManager::projectAdded,
|
&SessionManager::projectAdded,
|
||||||
this,
|
this,
|
||||||
@@ -225,22 +219,25 @@ void CMakeBuildSystem::triggerParsing()
|
|||||||
// This can legitimately trigger if e.g. Build->Run CMake
|
// This can legitimately trigger if e.g. Build->Run CMake
|
||||||
// is selected while this here is already running.
|
// is selected while this here is already running.
|
||||||
|
|
||||||
// FIXME: Instead of aborting the second run here we could try to
|
// Stop old parse run and keep that ParseGuard!
|
||||||
// cancel the first one in the Build->Run CMake handler and then
|
stopParsingAndClearState();
|
||||||
// continue to here normally. This here could then be an Assert.
|
} else {
|
||||||
return;
|
// Use new ParseGuard
|
||||||
|
m_currentGuard = std::move(guard);
|
||||||
}
|
}
|
||||||
|
QTC_ASSERT(!m_reader.isParsing(), return );
|
||||||
|
|
||||||
m_currentGuard = std::move(guard);
|
qCDebug(cmakeBuildSystemLog) << "ParseGuard acquired.";
|
||||||
|
|
||||||
if (m_allFiles.isEmpty())
|
if (m_allFiles.isEmpty())
|
||||||
m_buildDirManager.requestFilesystemScan();
|
updateReparseParameters(REPARSE_SCAN);
|
||||||
|
|
||||||
m_waitingForScan = m_buildDirManager.isFilesystemScanRequested();
|
m_waitingForScan = (m_reparseParameters | REPARSE_SCAN) != 0;
|
||||||
m_waitingForParse = true;
|
m_waitingForParse = true;
|
||||||
m_combinedScanAndParseResult = true;
|
m_combinedScanAndParseResult = true;
|
||||||
|
|
||||||
if (m_waitingForScan) {
|
if (m_waitingForScan) {
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "Starting TreeScanner";
|
||||||
QTC_CHECK(m_treeScanner.isFinished());
|
QTC_CHECK(m_treeScanner.isFinished());
|
||||||
m_treeScanner.asyncScanForFiles(projectDirectory());
|
m_treeScanner.asyncScanForFiles(projectDirectory());
|
||||||
Core::ProgressManager::addTask(m_treeScanner.future(),
|
Core::ProgressManager::addTask(m_treeScanner.future(),
|
||||||
@@ -249,7 +246,34 @@ void CMakeBuildSystem::triggerParsing()
|
|||||||
"CMake.Scan.Tree");
|
"CMake.Scan.Tree");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_buildDirManager.parse();
|
QTC_ASSERT(m_parameters.isValid(), return );
|
||||||
|
|
||||||
|
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
||||||
|
|
||||||
|
int reparseParameters = takeReparseParameters();
|
||||||
|
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "Parse called with flags:"
|
||||||
|
<< reparseParametersString(reparseParameters);
|
||||||
|
|
||||||
|
const QString cache = m_parameters.workDirectory.pathAppended("CMakeCache.txt").toString();
|
||||||
|
if (!QFileInfo::exists(cache)) {
|
||||||
|
reparseParameters |= REPARSE_FORCE_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN;
|
||||||
|
qCDebug(cmakeBuildSystemLog)
|
||||||
|
<< "No" << cache
|
||||||
|
<< "file found, new flags:" << reparseParametersString(reparseParameters);
|
||||||
|
} else if (reparseParameters & REPARSE_CHECK_CONFIGURATION) {
|
||||||
|
if (checkConfiguration()) {
|
||||||
|
reparseParameters |= REPARSE_FORCE_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN;
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "Config check triggered flags change:"
|
||||||
|
<< reparseParametersString(reparseParameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeConfigurationIntoBuildDirectory(m_parameters.expander);
|
||||||
|
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "Asking reader to parse";
|
||||||
|
m_reader.parse(reparseParameters & REPARSE_FORCE_CMAKE_RUN,
|
||||||
|
reparseParameters & REPARSE_FORCE_CONFIGURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
bool CMakeBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
||||||
@@ -312,23 +336,89 @@ QStringList CMakeBuildSystem::filesGeneratedFrom(const QString &sourceFile) cons
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CMakeBuildSystem::reparseParametersString(int reparseFlags)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
if (reparseFlags == REPARSE_DEFAULT) {
|
||||||
|
result = "<NONE>";
|
||||||
|
} else {
|
||||||
|
if (reparseFlags & REPARSE_URGENT)
|
||||||
|
result += " URGENT";
|
||||||
|
if (reparseFlags & REPARSE_FORCE_CMAKE_RUN)
|
||||||
|
result += " FORCE_CMAKE_RUN";
|
||||||
|
if (reparseFlags & REPARSE_FORCE_CONFIGURATION)
|
||||||
|
result += " FORCE_CONFIG";
|
||||||
|
if (reparseFlags & REPARSE_CHECK_CONFIGURATION)
|
||||||
|
result += " CHECK_CONFIG";
|
||||||
|
if (reparseFlags & REPARSE_SCAN)
|
||||||
|
result += " SCAN";
|
||||||
|
}
|
||||||
|
return result.trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
||||||
|
const int reparseParameters)
|
||||||
|
{
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "setting parameters and requesting reparse";
|
||||||
|
if (!parameters.cmakeTool()) {
|
||||||
|
TaskHub::addTask(
|
||||||
|
BuildSystemTask(Task::Error,
|
||||||
|
tr("The kit needs to define a CMake tool to parse this project.")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QTC_ASSERT(parameters.isValid(), return );
|
||||||
|
|
||||||
|
m_parameters = parameters;
|
||||||
|
m_parameters.workDirectory = workDirectory(parameters);
|
||||||
|
updateReparseParameters(reparseParameters);
|
||||||
|
|
||||||
|
m_reader.setParameters(m_parameters);
|
||||||
|
|
||||||
|
if (reparseParameters & REPARSE_URGENT) {
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "calling requestReparse";
|
||||||
|
requestParse();
|
||||||
|
} else {
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "calling requestDelayedReparse";
|
||||||
|
requestDelayedParse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(expander, return );
|
||||||
|
|
||||||
|
const FilePath buildDir = workDirectory(m_parameters);
|
||||||
|
QTC_ASSERT(buildDir.exists(), return );
|
||||||
|
|
||||||
|
const FilePath settingsFile = buildDir.pathAppended("qtcsettings.cmake");
|
||||||
|
|
||||||
|
QByteArray contents;
|
||||||
|
contents.append("# This file is managed by Qt Creator, do not edit!\n\n");
|
||||||
|
contents.append(
|
||||||
|
transform(m_parameters.configuration,
|
||||||
|
[expander](const CMakeConfigItem &item) { return item.toCMakeSetLine(expander); })
|
||||||
|
.join('\n')
|
||||||
|
.toUtf8());
|
||||||
|
|
||||||
|
QFile file(settingsFile.toString());
|
||||||
|
QTC_ASSERT(file.open(QFile::WriteOnly | QFile::Truncate), return );
|
||||||
|
file.write(contents);
|
||||||
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::runCMake()
|
void CMakeBuildSystem::runCMake()
|
||||||
{
|
{
|
||||||
BuildDirParameters parameters(cmakeBuildConfiguration());
|
BuildDirParameters parameters(cmakeBuildConfiguration());
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due \"Run CMake\" command";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due \"Run CMake\" command";
|
||||||
m_buildDirManager.setParametersAndRequestParse(parameters,
|
setParametersAndRequestParse(parameters,
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION
|
REPARSE_CHECK_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN
|
||||||
| BuildDirManager::REPARSE_FORCE_CMAKE_RUN
|
| REPARSE_URGENT);
|
||||||
| BuildDirManager::REPARSE_URGENT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::runCMakeAndScanProjectTree()
|
void CMakeBuildSystem::runCMakeAndScanProjectTree()
|
||||||
{
|
{
|
||||||
BuildDirParameters parameters(cmakeBuildConfiguration());
|
BuildDirParameters parameters(cmakeBuildConfiguration());
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to \"Rescan Project\" command";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to \"Rescan Project\" command";
|
||||||
m_buildDirManager.setParametersAndRequestParse(parameters,
|
setParametersAndRequestParse(parameters, REPARSE_CHECK_CONFIGURATION | REPARSE_SCAN);
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION
|
|
||||||
| BuildDirManager::REPARSE_SCAN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::buildCMakeTarget(const QString &buildTarget)
|
void CMakeBuildSystem::buildCMakeTarget(const QString &buildTarget)
|
||||||
@@ -351,19 +441,44 @@ void CMakeBuildSystem::handleTreeScanningFinished()
|
|||||||
|
|
||||||
bool CMakeBuildSystem::persistCMakeState()
|
bool CMakeBuildSystem::persistCMakeState()
|
||||||
{
|
{
|
||||||
return m_buildDirManager.persistCMakeState();
|
QTC_ASSERT(m_parameters.isValid(), return false);
|
||||||
|
|
||||||
|
if (m_parameters.workDirectory == m_parameters.buildDirectory)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!buildConfiguration()->createBuildDirectory())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BuildDirParameters newParameters = m_parameters;
|
||||||
|
newParameters.workDirectory.clear();
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to persisting CMake State";
|
||||||
|
setParametersAndRequestParse(newParameters,
|
||||||
|
REPARSE_URGENT | REPARSE_FORCE_CMAKE_RUN
|
||||||
|
| REPARSE_FORCE_CONFIGURATION | REPARSE_CHECK_CONFIGURATION);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::clearCMakeCache()
|
void CMakeBuildSystem::clearCMakeCache()
|
||||||
{
|
{
|
||||||
m_buildDirManager.clearCache();
|
QTC_ASSERT(m_parameters.isValid(), return );
|
||||||
|
QTC_ASSERT(!m_isHandlingError, return );
|
||||||
|
|
||||||
|
stopParsingAndClearState();
|
||||||
|
|
||||||
|
const FilePath cmakeCache = m_parameters.workDirectory / "CMakeCache.txt";
|
||||||
|
const FilePath cmakeFiles = m_parameters.workDirectory / "CMakeFiles";
|
||||||
|
|
||||||
|
if (cmakeCache.exists())
|
||||||
|
Utils::FileUtils::removeRecursively(cmakeCache);
|
||||||
|
if (cmakeFiles.exists())
|
||||||
|
Utils::FileUtils::removeRecursively(cmakeFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CMakeProjectNode>
|
std::unique_ptr<CMakeProjectNode>
|
||||||
CMakeBuildSystem::generateProjectTree(const QList<const FileNode *> &allFiles)
|
CMakeBuildSystem::generateProjectTree(const QList<const FileNode *> &allFiles)
|
||||||
{
|
{
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
auto root = m_buildDirManager.generateProjectTree(allFiles, errorMessage);
|
auto root = m_reader.generateProjectTree(allFiles, errorMessage);
|
||||||
checkAndReportError(errorMessage);
|
checkAndReportError(errorMessage);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
@@ -380,6 +495,8 @@ void CMakeBuildSystem::combineScanAndParse()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_reader.resetData();
|
||||||
|
|
||||||
m_currentGuard = {};
|
m_currentGuard = {};
|
||||||
|
|
||||||
emitBuildSystemUpdated();
|
emitBuildSystemUpdated();
|
||||||
@@ -397,10 +514,9 @@ void CMakeBuildSystem::updateProjectData()
|
|||||||
{
|
{
|
||||||
qCDebug(cmakeBuildSystemLog) << "Updating CMake project data";
|
qCDebug(cmakeBuildSystemLog) << "Updating CMake project data";
|
||||||
|
|
||||||
QTC_ASSERT(m_treeScanner.isFinished() && !m_buildDirManager.isParsing(), return);
|
QTC_ASSERT(m_treeScanner.isFinished() && !m_reader.isParsing(), return );
|
||||||
|
|
||||||
cmakeBuildConfiguration()->project()->setExtraProjectFiles(
|
cmakeBuildConfiguration()->project()->setExtraProjectFiles(m_reader.projectFilesToWatch());
|
||||||
m_buildDirManager.projectFilesToWatch());
|
|
||||||
|
|
||||||
CMakeConfig patchedConfig = cmakeBuildConfiguration()->configurationFromCMake();
|
CMakeConfig patchedConfig = cmakeBuildConfiguration()->configurationFromCMake();
|
||||||
{
|
{
|
||||||
@@ -469,7 +585,7 @@ void CMakeBuildSystem::updateProjectData()
|
|||||||
|
|
||||||
{
|
{
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
RawProjectParts rpps = m_buildDirManager.createRawProjectParts(errorMessage);
|
RawProjectParts rpps = m_reader.createRawProjectParts(errorMessage);
|
||||||
if (!errorMessage.isEmpty())
|
if (!errorMessage.isEmpty())
|
||||||
cmakeBuildConfiguration()->setError(errorMessage);
|
cmakeBuildConfiguration()->setError(errorMessage);
|
||||||
qCDebug(cmakeBuildSystemLog) << "Raw project parts created." << errorMessage;
|
qCDebug(cmakeBuildSystemLog) << "Raw project parts created." << errorMessage;
|
||||||
@@ -491,15 +607,13 @@ void CMakeBuildSystem::updateProjectData()
|
|||||||
|
|
||||||
emit cmakeBuildConfiguration()->buildTypeChanged();
|
emit cmakeBuildConfiguration()->buildTypeChanged();
|
||||||
|
|
||||||
m_buildDirManager.resetData();
|
|
||||||
|
|
||||||
qCDebug(cmakeBuildSystemLog) << "All CMake project data up to date.";
|
qCDebug(cmakeBuildSystemLog) << "All CMake project data up to date.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::handleParsingSucceeded()
|
void CMakeBuildSystem::handleParsingSucceeded()
|
||||||
{
|
{
|
||||||
if (!cmakeBuildConfiguration()->isActive()) {
|
if (!cmakeBuildConfiguration()->isActive()) {
|
||||||
m_buildDirManager.stopParsingAndClearState();
|
stopParsingAndClearState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,14 +621,16 @@ void CMakeBuildSystem::handleParsingSucceeded()
|
|||||||
|
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
{
|
{
|
||||||
m_buildTargets = m_buildDirManager.takeBuildTargets(errorMessage);
|
m_buildTargets = m_reader.takeBuildTargets(errorMessage);
|
||||||
checkAndReportError(errorMessage);
|
checkAndReportError(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const CMakeConfig cmakeConfig = m_buildDirManager.takeCMakeConfiguration(errorMessage);
|
CMakeConfig cmakeConfig = m_reader.takeParsedConfiguration(errorMessage);
|
||||||
checkAndReportError(errorMessage);
|
for (auto &ci : cmakeConfig)
|
||||||
|
ci.inCMakeCache = true;
|
||||||
cmakeBuildConfiguration()->setConfigurationFromCMake(cmakeConfig);
|
cmakeBuildConfiguration()->setConfigurationFromCMake(cmakeConfig);
|
||||||
|
checkAndReportError(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
setApplicationTargets(appTargets());
|
setApplicationTargets(appTargets());
|
||||||
@@ -531,8 +647,10 @@ void CMakeBuildSystem::handleParsingFailed(const QString &msg)
|
|||||||
cmakeBuildConfiguration()->setError(msg);
|
cmakeBuildConfiguration()->setError(msg);
|
||||||
|
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
cmakeBuildConfiguration()->setConfigurationFromCMake(
|
CMakeConfig cmakeConfig = m_reader.takeParsedConfiguration(errorMessage);
|
||||||
m_buildDirManager.takeCMakeConfiguration(errorMessage));
|
for (auto &ci : cmakeConfig)
|
||||||
|
ci.inCMakeCache = true;
|
||||||
|
cmakeBuildConfiguration()->setConfigurationFromCMake(cmakeConfig);
|
||||||
// ignore errorMessage here, we already got one.
|
// ignore errorMessage here, we already got one.
|
||||||
|
|
||||||
QTC_CHECK(m_waitingForParse);
|
QTC_CHECK(m_waitingForParse);
|
||||||
@@ -559,8 +677,8 @@ void CMakeBuildSystem::wireUpConnections(const Project *p)
|
|||||||
// Build configuration has not changed, but Kit settings might have:
|
// Build configuration has not changed, but Kit settings might have:
|
||||||
// reparse and check the configuration, independent of whether the reader has changed
|
// reparse and check the configuration, independent of whether the reader has changed
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to kit being updated";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to kit being updated";
|
||||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
CMakeBuildSystem::REPARSE_CHECK_CONFIGURATION);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Became active/inactive:
|
// Became active/inactive:
|
||||||
@@ -570,11 +688,10 @@ void CMakeBuildSystem::wireUpConnections(const Project *p)
|
|||||||
// * Check configuration if reader changes due to it not existing yet:-)
|
// * Check configuration if reader changes due to it not existing yet:-)
|
||||||
// * run cmake without configuration arguments if the reader stays
|
// * run cmake without configuration arguments if the reader stays
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active target changed";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active target changed";
|
||||||
m_buildDirManager
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
CMakeBuildSystem::REPARSE_CHECK_CONFIGURATION);
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
|
||||||
} else {
|
} else {
|
||||||
m_buildDirManager.stopParsingAndClearState();
|
stopParsingAndClearState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(target(), &Target::activeBuildConfigurationChanged, this, [this](BuildConfiguration *bc) {
|
connect(target(), &Target::activeBuildConfigurationChanged, this, [this](BuildConfiguration *bc) {
|
||||||
@@ -584,11 +701,10 @@ void CMakeBuildSystem::wireUpConnections(const Project *p)
|
|||||||
// * Check configuration if reader changes due to it not existing yet:-)
|
// * Check configuration if reader changes due to it not existing yet:-)
|
||||||
// * run cmake without configuration arguments if the reader stays
|
// * run cmake without configuration arguments if the reader stays
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active BC changed";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to active BC changed";
|
||||||
m_buildDirManager
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
CMakeBuildSystem::REPARSE_CHECK_CONFIGURATION);
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
|
||||||
} else {
|
} else {
|
||||||
m_buildDirManager.stopParsingAndClearState();
|
stopParsingAndClearState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -600,9 +716,8 @@ void CMakeBuildSystem::wireUpConnections(const Project *p)
|
|||||||
// * Error out if the reader updates, cannot happen since all BCs share a target/kit.
|
// * Error out if the reader updates, cannot happen since all BCs share a target/kit.
|
||||||
// * run cmake without configuration arguments if the reader stays
|
// * run cmake without configuration arguments if the reader stays
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to environment change";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to environment change";
|
||||||
m_buildDirManager
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
CMakeBuildSystem::REPARSE_CHECK_CONFIGURATION);
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(cmakeBuildConfiguration(), &CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
|
connect(cmakeBuildConfiguration(), &CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
|
||||||
@@ -613,9 +728,8 @@ void CMakeBuildSystem::wireUpConnections(const Project *p)
|
|||||||
// If no configuration exists, then the arguments will get added automatically by
|
// If no configuration exists, then the arguments will get added automatically by
|
||||||
// the reader.
|
// the reader.
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to build directory change";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to build directory change";
|
||||||
m_buildDirManager
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
CMakeBuildSystem::REPARSE_CHECK_CONFIGURATION);
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(cmakeBuildConfiguration(),
|
connect(cmakeBuildConfiguration(),
|
||||||
@@ -628,9 +742,8 @@ void CMakeBuildSystem::wireUpConnections(const Project *p)
|
|||||||
// * run cmake with configuration arguments if the reader stays
|
// * run cmake with configuration arguments if the reader stays
|
||||||
qCDebug(cmakeBuildSystemLog)
|
qCDebug(cmakeBuildSystemLog)
|
||||||
<< "Requesting parse due to cmake configuration change";
|
<< "Requesting parse due to cmake configuration change";
|
||||||
m_buildDirManager
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
CMakeBuildSystem::REPARSE_FORCE_CONFIGURATION);
|
||||||
BuildDirManager::REPARSE_FORCE_CONFIGURATION);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -639,16 +752,224 @@ void CMakeBuildSystem::wireUpConnections(const Project *p)
|
|||||||
const auto cmake = CMakeKitAspect::cmakeTool(cmakeBuildConfiguration()->target()->kit());
|
const auto cmake = CMakeKitAspect::cmakeTool(cmakeBuildConfiguration()->target()->kit());
|
||||||
if (cmake && cmake->isAutoRun()) {
|
if (cmake && cmake->isAutoRun()) {
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to dirty project file";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to dirty project file";
|
||||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
cmakeBuildConfiguration()),
|
CMakeBuildSystem::REPARSE_DEFAULT);
|
||||||
BuildDirManager::REPARSE_DEFAULT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Force initial parsing run:
|
// Force initial parsing run:
|
||||||
m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
if (cmakeBuildConfiguration()->isActive())
|
||||||
BuildDirManager::REPARSE_CHECK_CONFIGURATION);
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
|
CMakeBuildSystem::REPARSE_CHECK_CONFIGURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath CMakeBuildSystem::workDirectory(const BuildDirParameters ¶meters)
|
||||||
|
{
|
||||||
|
const Utils::FilePath bdir = parameters.buildDirectory;
|
||||||
|
const CMakeTool *cmake = parameters.cmakeTool();
|
||||||
|
if (bdir.exists()) {
|
||||||
|
m_buildDirToTempDir.erase(bdir);
|
||||||
|
return bdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmake && cmake->autoCreateBuildDirectory()) {
|
||||||
|
if (!cmakeBuildConfiguration()->createBuildDirectory())
|
||||||
|
handleParsingFailed(
|
||||||
|
tr("Failed to create build directory \"%1\".").arg(bdir.toUserOutput()));
|
||||||
|
return bdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tmpDirIt = m_buildDirToTempDir.find(bdir);
|
||||||
|
if (tmpDirIt == m_buildDirToTempDir.end()) {
|
||||||
|
auto ret = m_buildDirToTempDir.emplace(
|
||||||
|
std::make_pair(bdir, std::make_unique<Utils::TemporaryDirectory>("qtc-cmake-XXXXXXXX")));
|
||||||
|
QTC_ASSERT(ret.second, return bdir);
|
||||||
|
tmpDirIt = ret.first;
|
||||||
|
|
||||||
|
if (!tmpDirIt->second->isValid()) {
|
||||||
|
handleParsingFailed(tr("Failed to create temporary directory \"%1\".")
|
||||||
|
.arg(QDir::toNativeSeparators(tmpDirIt->second->path())));
|
||||||
|
return bdir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Utils::FilePath::fromString(tmpDirIt->second->path());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::stopParsingAndClearState()
|
||||||
|
{
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "stopping parsing run!";
|
||||||
|
m_reader.stop();
|
||||||
|
m_reader.resetData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::becameDirty()
|
||||||
|
{
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "CMakeBuildSystem: becameDirty was triggered.";
|
||||||
|
if (isParsing())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const CMakeTool *tool = m_parameters.cmakeTool();
|
||||||
|
if (!tool->isAutoRun())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()),
|
||||||
|
REPARSE_CHECK_CONFIGURATION | REPARSE_SCAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::updateReparseParameters(const int parameters)
|
||||||
|
{
|
||||||
|
m_reparseParameters |= parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMakeBuildSystem::takeReparseParameters()
|
||||||
|
{
|
||||||
|
int result = m_reparseParameters;
|
||||||
|
m_reparseParameters = REPARSE_DEFAULT;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMakeBuildSystem::hasConfigChanged()
|
||||||
|
{
|
||||||
|
checkConfiguration();
|
||||||
|
|
||||||
|
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
|
||||||
|
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
|
||||||
|
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
|
||||||
|
const QByteArray CMAKE_C_COMPILER_KEY = "CMAKE_C_COMPILER";
|
||||||
|
const QByteArray CMAKE_CXX_COMPILER_KEY = "CMAKE_CXX_COMPILER";
|
||||||
|
|
||||||
|
const QByteArrayList criticalKeys = {GENERATOR_KEY,
|
||||||
|
CMAKE_COMMAND_KEY,
|
||||||
|
CMAKE_C_COMPILER_KEY,
|
||||||
|
CMAKE_CXX_COMPILER_KEY};
|
||||||
|
|
||||||
|
QString errorMessage;
|
||||||
|
const CMakeConfig currentConfig = cmakeBuildConfiguration()->configurationFromCMake();
|
||||||
|
if (!errorMessage.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const CMakeTool *tool = m_parameters.cmakeTool();
|
||||||
|
QTC_ASSERT(tool,
|
||||||
|
return false); // No cmake... we should not have ended up here in the first place
|
||||||
|
const QString extraKitGenerator = m_parameters.extraGenerator;
|
||||||
|
const QString mainKitGenerator = m_parameters.generator;
|
||||||
|
CMakeConfig targetConfig = m_parameters.configuration;
|
||||||
|
targetConfig.append(CMakeConfigItem(GENERATOR_KEY,
|
||||||
|
CMakeConfigItem::INTERNAL,
|
||||||
|
QByteArray(),
|
||||||
|
mainKitGenerator.toUtf8()));
|
||||||
|
if (!extraKitGenerator.isEmpty())
|
||||||
|
targetConfig.append(CMakeConfigItem(EXTRA_GENERATOR_KEY,
|
||||||
|
CMakeConfigItem::INTERNAL,
|
||||||
|
QByteArray(),
|
||||||
|
extraKitGenerator.toUtf8()));
|
||||||
|
targetConfig.append(CMakeConfigItem(CMAKE_COMMAND_KEY,
|
||||||
|
CMakeConfigItem::INTERNAL,
|
||||||
|
QByteArray(),
|
||||||
|
tool->cmakeExecutable().toUserOutput().toUtf8()));
|
||||||
|
Utils::sort(targetConfig, CMakeConfigItem::sortOperator());
|
||||||
|
|
||||||
|
bool mustReparse = false;
|
||||||
|
auto ccit = currentConfig.constBegin();
|
||||||
|
auto kcit = targetConfig.constBegin();
|
||||||
|
|
||||||
|
while (ccit != currentConfig.constEnd() && kcit != targetConfig.constEnd()) {
|
||||||
|
if (ccit->key == kcit->key) {
|
||||||
|
if (ccit->value != kcit->value) {
|
||||||
|
if (criticalKeys.contains(kcit->key)) {
|
||||||
|
clearCMakeCache();
|
||||||
|
return false; // no need to trigger a new reader, clearCache will do that
|
||||||
|
}
|
||||||
|
mustReparse = true;
|
||||||
|
}
|
||||||
|
++ccit;
|
||||||
|
++kcit;
|
||||||
|
} else {
|
||||||
|
if (ccit->key < kcit->key) {
|
||||||
|
++ccit;
|
||||||
|
} else {
|
||||||
|
++kcit;
|
||||||
|
mustReparse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have keys that do not exist yet, then reparse.
|
||||||
|
//
|
||||||
|
// The critical keys *must* be set in cmake configuration, so those were already
|
||||||
|
// handled above.
|
||||||
|
return mustReparse || kcit != targetConfig.constEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMakeBuildSystem::checkConfiguration()
|
||||||
|
{
|
||||||
|
if (m_parameters.workDirectory
|
||||||
|
!= m_parameters.buildDirectory) // always throw away changes in the tmpdir!
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const CMakeConfig cache = cmakeBuildConfiguration()->configurationFromCMake();
|
||||||
|
if (cache.isEmpty())
|
||||||
|
return false; // No cache file yet.
|
||||||
|
|
||||||
|
CMakeConfig newConfig;
|
||||||
|
QHash<QString, QPair<QString, QString>> changedKeys;
|
||||||
|
foreach (const CMakeConfigItem &projectItem, m_parameters.configuration) {
|
||||||
|
const QString projectKey = QString::fromUtf8(projectItem.key);
|
||||||
|
const QString projectValue = projectItem.expandedValue(m_parameters.expander);
|
||||||
|
const CMakeConfigItem &cmakeItem = Utils::findOrDefault(cache,
|
||||||
|
[&projectItem](
|
||||||
|
const CMakeConfigItem &i) {
|
||||||
|
return i.key == projectItem.key;
|
||||||
|
});
|
||||||
|
const QString iCacheValue = QString::fromUtf8(cmakeItem.value);
|
||||||
|
if (cmakeItem.isNull()) {
|
||||||
|
changedKeys.insert(projectKey, qMakePair(tr("<removed>"), projectValue));
|
||||||
|
} else if (iCacheValue != projectValue) {
|
||||||
|
changedKeys.insert(projectKey, qMakePair(iCacheValue, projectValue));
|
||||||
|
newConfig.append(cmakeItem);
|
||||||
|
} else {
|
||||||
|
newConfig.append(projectItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changedKeys.isEmpty()) {
|
||||||
|
QStringList keyList = changedKeys.keys();
|
||||||
|
Utils::sort(keyList);
|
||||||
|
QString table = QString::fromLatin1("<table><tr><th>%1</th><th>%2</th><th>%3</th></tr>")
|
||||||
|
.arg(tr("Key"))
|
||||||
|
.arg(tr("%1 Project").arg(Core::Constants::IDE_DISPLAY_NAME))
|
||||||
|
.arg(tr("Changed value"));
|
||||||
|
foreach (const QString &k, keyList) {
|
||||||
|
const QPair<QString, QString> data = changedKeys.value(k);
|
||||||
|
table += QString::fromLatin1("\n<tr><td>%1</td><td>%2</td><td>%3</td></tr>")
|
||||||
|
.arg(k)
|
||||||
|
.arg(data.second.toHtmlEscaped())
|
||||||
|
.arg(data.first.toHtmlEscaped());
|
||||||
|
}
|
||||||
|
table += QLatin1String("\n</table>");
|
||||||
|
|
||||||
|
QPointer<QMessageBox> box = new QMessageBox(Core::ICore::mainWindow());
|
||||||
|
box->setText(tr("The project has been changed outside of %1.")
|
||||||
|
.arg(Core::Constants::IDE_DISPLAY_NAME));
|
||||||
|
box->setInformativeText(table);
|
||||||
|
auto *defaultButton = box->addButton(tr("Discard External Changes"),
|
||||||
|
QMessageBox::RejectRole);
|
||||||
|
auto *applyButton = box->addButton(tr("Adapt %1 Project to Changes")
|
||||||
|
.arg(Core::Constants::IDE_DISPLAY_NAME),
|
||||||
|
QMessageBox::ApplyRole);
|
||||||
|
box->setDefaultButton(defaultButton);
|
||||||
|
|
||||||
|
box->exec();
|
||||||
|
if (box->clickedButton() == applyButton) {
|
||||||
|
m_parameters.configuration = newConfig;
|
||||||
|
QSignalBlocker blocker(buildConfiguration());
|
||||||
|
cmakeBuildConfiguration()->setConfigurationForCMake(newConfig);
|
||||||
|
return false;
|
||||||
|
} else if (box->clickedButton() == defaultButton)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const
|
CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const
|
||||||
@@ -709,6 +1030,20 @@ const QList<CMakeBuildTarget> &CMakeBuildSystem::buildTargets() const
|
|||||||
return m_buildTargets;
|
return m_buildTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMakeConfig CMakeBuildSystem::parseCMakeCacheDotTxt(const Utils::FilePath &cacheFile,
|
||||||
|
QString *errorMessage)
|
||||||
|
{
|
||||||
|
if (!cacheFile.exists()) {
|
||||||
|
if (errorMessage)
|
||||||
|
*errorMessage = tr("CMakeCache.txt file not found.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
CMakeConfig result = CMakeConfigItem::itemsFromFile(cacheFile, errorMessage);
|
||||||
|
if (!errorMessage->isEmpty())
|
||||||
|
return {};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DeploymentData CMakeBuildSystem::deploymentData() const
|
DeploymentData CMakeBuildSystem::deploymentData() const
|
||||||
{
|
{
|
||||||
DeploymentData result;
|
DeploymentData result;
|
||||||
|
@@ -25,10 +25,17 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "builddirmanager.h"
|
#include "builddirparameters.h"
|
||||||
|
#include "cmakebuildtarget.h"
|
||||||
|
#include "cmakeprojectnodes.h"
|
||||||
|
#include "fileapireader.h"
|
||||||
|
#include "utils/macroexpander.h"
|
||||||
|
|
||||||
#include <projectexplorer/buildsystem.h>
|
#include <projectexplorer/buildsystem.h>
|
||||||
|
|
||||||
|
#include <utils/fileutils.h>
|
||||||
|
#include <utils/temporarydirectory.h>
|
||||||
|
|
||||||
namespace ProjectExplorer { class ExtraCompiler; }
|
namespace ProjectExplorer { class ExtraCompiler; }
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
@@ -81,7 +88,28 @@ public:
|
|||||||
|
|
||||||
CMakeBuildConfiguration *cmakeBuildConfiguration() const;
|
CMakeBuildConfiguration *cmakeBuildConfiguration() const;
|
||||||
|
|
||||||
|
// Generic CMake helper functions:
|
||||||
|
static CMakeConfig parseCMakeCacheDotTxt(const Utils::FilePath &cacheFile,
|
||||||
|
QString *errorMessage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Actually ask for parsing:
|
||||||
|
enum ReparseParameters {
|
||||||
|
REPARSE_DEFAULT = 0, // Nothing special:-)
|
||||||
|
REPARSE_FORCE_CMAKE_RUN = (1 << 0), // Force cmake to run
|
||||||
|
REPARSE_FORCE_CONFIGURATION = (1 << 1), // Force configuration arguments to cmake
|
||||||
|
REPARSE_CHECK_CONFIGURATION
|
||||||
|
= (1 << 2), // Check for on-disk config and QtC config diff // FIXME: Remove this!
|
||||||
|
REPARSE_SCAN = (1 << 3), // Run filesystem scan
|
||||||
|
REPARSE_URGENT = (1 << 4), // Do not delay the parser run by 1s
|
||||||
|
};
|
||||||
|
QString reparseParametersString(int reparseFlags);
|
||||||
|
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
||||||
|
const int reparseParameters);
|
||||||
|
|
||||||
|
void writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander);
|
||||||
|
|
||||||
|
// State handling:
|
||||||
// Parser states:
|
// Parser states:
|
||||||
void handleParsingSuccess();
|
void handleParsingSuccess();
|
||||||
void handleParsingError();
|
void handleParsingError();
|
||||||
@@ -106,7 +134,12 @@ private:
|
|||||||
|
|
||||||
void wireUpConnections(const ProjectExplorer::Project *p);
|
void wireUpConnections(const ProjectExplorer::Project *p);
|
||||||
|
|
||||||
BuildDirManager m_buildDirManager;
|
Utils::FilePath workDirectory(const BuildDirParameters ¶meters);
|
||||||
|
void stopParsingAndClearState();
|
||||||
|
void becameDirty();
|
||||||
|
|
||||||
|
void updateReparseParameters(const int parameters);
|
||||||
|
int takeReparseParameters();
|
||||||
|
|
||||||
ProjectExplorer::TreeScanner m_treeScanner;
|
ProjectExplorer::TreeScanner m_treeScanner;
|
||||||
QHash<QString, bool> m_mimeBinaryCache;
|
QHash<QString, bool> m_mimeBinaryCache;
|
||||||
@@ -121,6 +154,17 @@ private:
|
|||||||
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
|
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
|
||||||
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
|
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
|
||||||
QList<CMakeBuildTarget> m_buildTargets;
|
QList<CMakeBuildTarget> m_buildTargets;
|
||||||
|
|
||||||
|
bool checkConfiguration();
|
||||||
|
bool hasConfigChanged();
|
||||||
|
|
||||||
|
// Parsing state:
|
||||||
|
BuildDirParameters m_parameters;
|
||||||
|
int m_reparseParameters;
|
||||||
|
mutable std::unordered_map<Utils::FilePath, std::unique_ptr<Utils::TemporaryDirectory>>
|
||||||
|
m_buildDirToTempDir;
|
||||||
|
FileApiReader m_reader;
|
||||||
|
mutable bool m_isHandlingError = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -60,7 +60,6 @@ sequenceDiagram
|
|||||||
participant User
|
participant User
|
||||||
participant ParseGuard
|
participant ParseGuard
|
||||||
participant CMakeBuildSystem
|
participant CMakeBuildSystem
|
||||||
participant BuildDirManager
|
|
||||||
participant FileApiReader
|
participant FileApiReader
|
||||||
|
|
||||||
alt Trigger Parsing
|
alt Trigger Parsing
|
||||||
@@ -69,14 +68,12 @@ sequenceDiagram
|
|||||||
User ->> CMakeBuildSystem: Signal from outside the CMakeBuildSystem
|
User ->> CMakeBuildSystem: Signal from outside the CMakeBuildSystem
|
||||||
end
|
end
|
||||||
activate CMakeBuildSystem
|
activate CMakeBuildSystem
|
||||||
CMakeBuildSystem ->> BuildDirManager: call setParametersAndRequestReparse()
|
CMakeBuildSystem ->> CMakeBuildSystem: call setParametersAndRequestReparse()
|
||||||
activate BuildDirManager
|
CMakeBuildSystem ->> CMakeBuildSystem: Validate parameters
|
||||||
BuildDirManager ->> BuildDirManager: Validate parameters
|
CMakeBuildSystem ->> FileApiReader: Construct
|
||||||
BuildDirManager ->> FileApiReader: Construct
|
|
||||||
activate FileApiReader
|
activate FileApiReader
|
||||||
BuildDirManager ->> FileApiReader: call setParameters
|
CMakeBuildSystem ->> FileApiReader: call setParameters
|
||||||
BuildDirManager ->> CMakeBuildSystem: call request*Reparse()
|
CMakeBuildSystem ->> CMakeBuildSystem: call request*Reparse()
|
||||||
deactivate BuildDirManager
|
|
||||||
deactivate CMakeBuildSystem
|
deactivate CMakeBuildSystem
|
||||||
|
|
||||||
CMakeBuildSystem ->> CMakeBuildSystem: m_delayedParsingTimer sends timeout() triggering triggerParsing()
|
CMakeBuildSystem ->> CMakeBuildSystem: m_delayedParsingTimer sends timeout() triggering triggerParsing()
|
||||||
@@ -92,10 +89,8 @@ sequenceDiagram
|
|||||||
|
|
||||||
CMakeBuildSystem ->>+ TreeScanner: call asyncScanForFiles()
|
CMakeBuildSystem ->>+ TreeScanner: call asyncScanForFiles()
|
||||||
|
|
||||||
CMakeBuildSystem ->>+ BuildDirManager: call parse(...)
|
CMakeBuildSystem ->>+ FileApiReader: call parse(...)
|
||||||
BuildDirManager ->>+ FileApiReader: call parse(...)
|
|
||||||
FileApiReader ->> FileApiReader: startState()
|
FileApiReader ->> FileApiReader: startState()
|
||||||
deactivate BuildDirManager
|
|
||||||
deactivate CMakeBuildSystem
|
deactivate CMakeBuildSystem
|
||||||
|
|
||||||
opt Parse
|
opt Parse
|
||||||
@@ -106,17 +101,12 @@ sequenceDiagram
|
|||||||
FileApiReader ->> FileApiReader: call endState(...)
|
FileApiReader ->> FileApiReader: call endState(...)
|
||||||
|
|
||||||
alt Return Result from FileApiReader
|
alt Return Result from FileApiReader
|
||||||
FileApiReader ->> BuildDirManager: signal dataAvailable()
|
FileApiReader ->> CMakeBuildSystem: signal dataAvailable() and trigger handleParsingSucceeded()
|
||||||
BuildDirManager ->> CMakeBuildSystem: signal dataAvailable() and trigger handleParsingSucceeded()
|
CMakeBuildSystem ->> FileApiReader: call takeBuildTargets()
|
||||||
CMakeBuildSystem ->> BuildDirManager: call takeBuildTargets()
|
CMakeBuildSystem ->> FileApiReader: call takeParsedConfiguration(....)
|
||||||
BuildDirManager ->> FileApiReader: call takeBuildTargets()
|
|
||||||
CMakeBuildSystem ->> BuildDirManager: call takeCMakeConfiguration(...)
|
|
||||||
BuildDirManager ->> FileApiReader: call takeCMakeConfiguration(....)
|
|
||||||
else
|
else
|
||||||
FileApiReader ->> BuildDirManager: signal errorOccurred(...)
|
FileApiReader ->> CMakeBuildSystem: signal errorOccurred(...) and trigger handelParsingFailed(...)
|
||||||
BuildDirManager ->> CMakeBuildSystem: signal errorOccurred(...) and trigger handelParsingFailed(...)
|
CMakeBuildSystem ->> FileApiReader: call takeParsedConfiguration(....)
|
||||||
CMakeBuildSystem ->> BuildDirManager: call takeCMakeConfiguration(...)
|
|
||||||
BuildDirManager ->> FileApiReader: call takeCMakeConfiguration(....)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
deactivate FileApiReader
|
deactivate FileApiReader
|
||||||
@@ -132,20 +122,17 @@ sequenceDiagram
|
|||||||
activate CMakeBuildSystem
|
activate CMakeBuildSystem
|
||||||
opt: Parsing was a success
|
opt: Parsing was a success
|
||||||
CMakeBuildSystem ->> CMakeBuildSystem: call updateProjectData()
|
CMakeBuildSystem ->> CMakeBuildSystem: call updateProjectData()
|
||||||
CMakeBuildSystem ->> BuildDirManager: call projectFilesToWatch()
|
CMakeBuildSystem ->> FileApiReader: call projectFilesToWatch()
|
||||||
BuildDirManager ->> FileApiReader: call projectFilesToWatch()
|
CMakeBuildSystem ->> FileApiReader: call createRawProjectParts(...)
|
||||||
CMakeBuildSystem ->> BuildDirManager: call createRawProjectParts(...)
|
CMakeBuildSystem ->> FileApiReader: call resetData()
|
||||||
BuildDirManager ->> FileApiReader: call createRawProjectParts(...)
|
|
||||||
CMakeBuildSystem ->> BuildDirManager: call resetData()
|
|
||||||
BuildDirManager ->> FileApiReader: Destruct
|
|
||||||
CMakeBuildSystem ->> ParseGuard: call markAsSuccess()
|
CMakeBuildSystem ->> ParseGuard: call markAsSuccess()
|
||||||
end
|
end
|
||||||
deactivate FileApiReader
|
|
||||||
|
|
||||||
CMakeBuildSystem ->> ParseGuard: Destruct
|
CMakeBuildSystem ->> ParseGuard: Destruct
|
||||||
deactivate ParseGuard
|
deactivate ParseGuard
|
||||||
|
|
||||||
CMakeBuildSystem ->> CMakeBuildSystem: call emitBuildSystemUpdated()
|
CMakeBuildSystem ->> CMakeBuildSystem: call emitBuildSystemUpdated()
|
||||||
|
deactivate FileApiReader
|
||||||
deactivate CMakeBuildSystem
|
deactivate CMakeBuildSystem
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
#include "cmakeprojectimporter.h"
|
#include "cmakeprojectimporter.h"
|
||||||
|
|
||||||
#include "builddirmanager.h"
|
|
||||||
#include "cmakebuildconfiguration.h"
|
#include "cmakebuildconfiguration.h"
|
||||||
|
#include "cmakebuildsystem.h"
|
||||||
#include "cmakekitinformation.h"
|
#include "cmakekitinformation.h"
|
||||||
#include "cmaketoolmanager.h"
|
#include "cmaketoolmanager.h"
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ QList<void *> CMakeProjectImporter::examineDirectory(const Utils::FilePath &impo
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
const CMakeConfig config = BuildDirManager::parseCMakeConfiguration(cacheFile, &errorMessage);
|
const CMakeConfig config = CMakeBuildSystem::parseCMakeCacheDotTxt(cacheFile, &errorMessage);
|
||||||
if (config.isEmpty() || !errorMessage.isEmpty()) {
|
if (config.isEmpty() || !errorMessage.isEmpty()) {
|
||||||
qCDebug(cmInputLog()) << "Failed to read configuration from" << cacheFile << errorMessage;
|
qCDebug(cmInputLog()) << "Failed to read configuration from" << cacheFile << errorMessage;
|
||||||
return { };
|
return { };
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
DEFINES += CMAKEPROJECTMANAGER_LIBRARY
|
DEFINES += CMAKEPROJECTMANAGER_LIBRARY
|
||||||
include(../../qtcreatorplugin.pri)
|
include(../../qtcreatorplugin.pri)
|
||||||
|
|
||||||
HEADERS = builddirmanager.h \
|
HEADERS = builddirparameters.h \
|
||||||
builddirparameters.h \
|
|
||||||
cmakebuildstep.h \
|
cmakebuildstep.h \
|
||||||
cmakebuildsystem.h \
|
cmakebuildsystem.h \
|
||||||
cmakebuildtarget.h \
|
cmakebuildtarget.h \
|
||||||
@@ -37,8 +36,7 @@ HEADERS = builddirmanager.h \
|
|||||||
fileapireader.h \
|
fileapireader.h \
|
||||||
projecttreehelper.h
|
projecttreehelper.h
|
||||||
|
|
||||||
SOURCES = builddirmanager.cpp \
|
SOURCES = builddirparameters.cpp \
|
||||||
builddirparameters.cpp \
|
|
||||||
cmakebuildstep.cpp \
|
cmakebuildstep.cpp \
|
||||||
cmakebuildsystem.cpp \
|
cmakebuildsystem.cpp \
|
||||||
cmakeconfigitem.cpp \
|
cmakeconfigitem.cpp \
|
||||||
|
@@ -21,8 +21,6 @@ QtcPlugin {
|
|||||||
files: [
|
files: [
|
||||||
"builddirparameters.cpp",
|
"builddirparameters.cpp",
|
||||||
"builddirparameters.h",
|
"builddirparameters.h",
|
||||||
"builddirmanager.cpp",
|
|
||||||
"builddirmanager.h",
|
|
||||||
"cmake_global.h",
|
"cmake_global.h",
|
||||||
"cmakebuildconfiguration.cpp",
|
"cmakebuildconfiguration.cpp",
|
||||||
"cmakebuildconfiguration.h",
|
"cmakebuildconfiguration.h",
|
||||||
|
@@ -136,6 +136,8 @@ void FileApiReader::parse(bool forceCMakeRun, bool forceConfiguration)
|
|||||||
|
|
||||||
void FileApiReader::stop()
|
void FileApiReader::stop()
|
||||||
{
|
{
|
||||||
|
if (m_cmakeProcess)
|
||||||
|
disconnect(m_cmakeProcess.get(), nullptr, this, nullptr);
|
||||||
m_cmakeProcess.reset();
|
m_cmakeProcess.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user