Commit 9a980adf authored by Tobias Hunger's avatar Tobias Hunger

CMake: Implement different backends to run cmake

Only the original one is implemented so far, but at least
in theory backends for retrieving data from cmake can now
be switched at runtime.

Change-Id: Id73a81c7d40f078be95defd30a38511dca3a3720
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
Reviewed-by: Eike Ziller's avatarEike Ziller <eike.ziller@qt.io>
parent b75c6444
......@@ -25,26 +25,17 @@
#pragma once
#include "cmakecbpparser.h"
#include "builddirreader.h"
#include "cmakeconfigitem.h"
#include "cmakefile.h"
#include <projectexplorer/task.h>
#include <utils/environment.h>
#include <utils/qtcprocess.h>
#include <utils/fileutils.h>
#include <QByteArray>
#include <QFutureInterface>
#include <QObject>
#include <QSet>
#include <QTemporaryDir>
#include <QTimer>
QT_FORWARD_DECLARE_CLASS(QTemporaryDir);
QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher);
#include <memory>
namespace Core { class IDocument; }
namespace CppTools { class ProjectPartBuilder; }
namespace ProjectExplorer {
......@@ -68,7 +59,6 @@ class BuildDirManager : public QObject
public:
BuildDirManager(CMakeBuildConfiguration *bc);
~BuildDirManager() override;
bool isParsing() const;
......@@ -87,9 +77,6 @@ public:
void checkConfiguration();
void handleDocumentSaves(Core::IDocument *document);
void handleCmakeFileChange();
signals:
void configurationStarted() const;
void dataAvailable() const;
......@@ -99,50 +86,22 @@ protected:
static CMakeConfig parseConfiguration(const Utils::FileName &cacheFile,
QString *errorMessage);
const ProjectExplorer::Kit *kit() const;
const Utils::FileName buildDirectory() const;
const Utils::FileName workDirectory() const;
const Utils::FileName sourceDirectory() const;
const CMakeConfig intendedConfiguration() const;
private:
void parse();
void cmakeFilesChanged();
void stopProcess();
void cleanUpProcess();
void extractData();
void updateReader();
void startCMake(CMakeTool *tool, const QStringList &generatorArgs, const CMakeConfig &config);
void cmakeFinished(int code, QProcess::ExitStatus status);
void processCMakeOutput();
void processCMakeError();
QStringList getCXXFlagsFor(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
bool extractCXXFlagsFromMake(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
bool extractCXXFlagsFromNinja(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
void parse();
bool m_hasData = false;
void becameDirty();
CMakeBuildConfiguration *m_buildConfiguration = nullptr;
Utils::QtcProcess *m_cmakeProcess = nullptr;
QTemporaryDir *m_tempDir = nullptr;
mutable std::unique_ptr<QTemporaryDir> m_tempDir = nullptr;
mutable CMakeConfig m_cmakeCache;
QSet<Utils::FileName> m_cmakeFiles;
QString m_projectName;
QList<CMakeBuildTarget> m_buildTargets;
QList<ProjectExplorer::FileNode *> m_files;
// For error reporting:
ProjectExplorer::IOutputParser *m_parser = nullptr;
QFutureInterface<void> *m_future = nullptr;
QTimer m_reparseTimer;
QSet<Internal::CMakeFile *> m_watchedFiles;
std::unique_ptr<BuildDirReader> m_reader;
};
} // namespace Internal
......
......@@ -23,42 +23,72 @@
**
****************************************************************************/
#include "cmakefile.h"
#include "builddirreader.h"
#include "builddirmanager.h"
#include "cmakeprojectconstants.h"
#include "cmakebuildconfiguration.h"
#include "cmakekitinformation.h"
#include "tealeafreader.h"
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
#include <utils/fileutils.h>
using namespace Utils;
using namespace ProjectExplorer;
namespace CMakeProjectManager {
namespace Internal {
CMakeFile::CMakeFile(BuildDirManager *bdm, const FileName &fileName) : m_buildDirManager(bdm)
// --------------------------------------------------------------------
// BuildDirReader:
// --------------------------------------------------------------------
BuildDirReader::Parameters::Parameters() = default;
BuildDirReader::Parameters::Parameters(const CMakeBuildConfiguration *bc)
{
setId("Cmake.ProjectFile");
setMimeType(QLatin1String(Constants::CMAKEPROJECTMIMETYPE));
setFilePath(fileName);
const ProjectExplorer::Kit *k = bc->target()->kit();
projectName = bc->target()->project()->displayName();
sourceDirectory = bc->target()->project()->projectDirectory();
buildDirectory = bc->buildDirectory();
environment = bc->environment();
CMakeTool *cmake = CMakeKitInformation::cmakeTool(k);
cmakeVersion = cmake->version();
cmakeHasServerMode = cmake->hasServerMode();
cmakeExecutable = cmake->cmakeExecutable();
pathMapper = cmake->pathMapper();
auto tc = ProjectExplorer::ToolChainKitInformation::toolChain(k, ProjectExplorer::ToolChain::Language::Cxx);
if (tc)
toolChainId = tc->id();
sysRoot = ProjectExplorer::SysRootKitInformation::sysRoot(k);
expander = k->macroExpander();
configuration = bc->cmakeConfiguration();
generator = CMakeGeneratorKitInformation::generator(k);
extraGenerator = CMakeGeneratorKitInformation::extraGenerator(k);
platform = CMakeGeneratorKitInformation::platform(k);
toolset = CMakeGeneratorKitInformation::toolset(k);
generatorArguments = CMakeGeneratorKitInformation::generatorArguments(k);
}
Core::IDocument::ReloadBehavior CMakeFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
BuildDirReader::Parameters::Parameters(const BuildDirReader::Parameters &other) = default;
BuildDirReader *BuildDirReader::createReader(const BuildDirReader::Parameters &p)
{
Q_UNUSED(state)
Q_UNUSED(type)
return BehaviorSilent;
Q_UNUSED(p); // FIXME
return new TeaLeafReader;
}
bool CMakeFile::reload(QString *errorString, Core::IDocument::ReloadFlag flag, Core::IDocument::ChangeType type)
void BuildDirReader::setParameters(const BuildDirReader::Parameters &p)
{
Q_UNUSED(errorString);
Q_UNUSED(flag);
if (type != TypePermissions)
m_buildDirManager->handleCmakeFileChange();
return true;
m_parameters = p;
}
} // namespace Internal
......
/****************************************************************************
**
** 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 "cmakeconfigitem.h"
#include "cmakeproject.h"
#include "cmaketool.h"
#include <utils/environment.h>
#include <utils/fileutils.h>
#include <utils/macroexpander.h>
#include <QFutureInterface>
#include <QObject>
namespace CppTools { class ProjectPartBuilder; }
namespace ProjectExplorer {
class IOutputParser;
class Kit;
} // ProjectExplorer
namespace Utils { class QtcProcess; }
namespace CMakeProjectManager {
namespace Internal {
class CMakeBuildConfiguration;
class BuildDirReader : public QObject
{
Q_OBJECT
public:
struct Parameters {
Parameters();
Parameters(const CMakeBuildConfiguration *bc);
Parameters(const Parameters &other);
QString projectName;
Utils::FileName sourceDirectory;
Utils::FileName buildDirectory;
Utils::Environment environment;
Utils::FileName cmakeExecutable;
CMakeTool::Version cmakeVersion;
bool cmakeHasServerMode;
CMakeTool::PathMapper pathMapper;
QByteArray toolChainId;
Utils::FileName sysRoot;
Utils::MacroExpander *expander = nullptr;
CMakeConfig configuration;
QString generator;
QString extraGenerator;
QString platform;
QString toolset;
QStringList generatorArguments;
};
static BuildDirReader *createReader(const BuildDirReader::Parameters &p);
void setParameters(const Parameters &p);
virtual bool isCompatible(const Parameters &p) = 0;
virtual void resetData() = 0;
virtual void parse(bool force) = 0;
virtual void stop() = 0;
virtual bool isParsing() const = 0;
virtual bool hasData() const = 0;
virtual CMakeConfig parsedConfiguration() const = 0;
virtual QList<CMakeBuildTarget> buildTargets() const = 0;
virtual void generateProjectTree(CMakeProjectNode *root) = 0;
virtual QSet<Core::Id> updateCodeModel(CppTools::ProjectPartBuilder &ppBuilder) = 0;
signals:
void configurationStarted() const;
void dataAvailable() const;
void dirty() const;
void errorOccured(const QString &message) const;
protected:
Parameters m_parameters;
};
} // namespace Internal
} // namespace CMakeProjectManager
......@@ -139,17 +139,17 @@ void CMakeBuildConfiguration::ctor()
target()->kit(),
displayName(), BuildConfiguration::Unknown));
connect(m_buildDirManager, &BuildDirManager::dataAvailable,
connect(m_buildDirManager.get(), &BuildDirManager::dataAvailable,
this, &CMakeBuildConfiguration::dataAvailable);
connect(m_buildDirManager, &BuildDirManager::errorOccured,
connect(m_buildDirManager.get(), &BuildDirManager::errorOccured,
this, &CMakeBuildConfiguration::setError);
connect(m_buildDirManager, &BuildDirManager::configurationStarted,
connect(m_buildDirManager.get(), &BuildDirManager::configurationStarted,
this, [this]() { m_completeConfigurationCache.clear(); emit parsingStarted(); });
connect(this, &CMakeBuildConfiguration::environmentChanged,
m_buildDirManager, &BuildDirManager::forceReparse);
m_buildDirManager.get(), &BuildDirManager::forceReparse);
connect(this, &CMakeBuildConfiguration::buildDirectoryChanged,
m_buildDirManager, &BuildDirManager::forceReparse);
m_buildDirManager.get(), &BuildDirManager::forceReparse);
connect(this, &CMakeBuildConfiguration::parsingStarted, project, &CMakeProject::handleParsingStarted);
connect(this, &CMakeBuildConfiguration::dataAvailable, project, &CMakeProject::updateProjectData);
......
......@@ -32,6 +32,8 @@
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/abi.h>
#include <memory>
namespace CppTools { class ProjectPartBuilder; }
namespace ProjectExplorer { class ToolChain; }
......@@ -114,7 +116,7 @@ private:
mutable QList<CMakeConfigItem> m_completeConfigurationCache;
BuildDirManager *const m_buildDirManager = nullptr;
std::unique_ptr<BuildDirManager> m_buildDirManager;
friend class CMakeBuildSettingsWidget;
friend class CMakeProjectManager::CMakeProject;
......
......@@ -2,6 +2,7 @@ DEFINES += CMAKEPROJECTMANAGER_LIBRARY
include(../../qtcreatorplugin.pri)
HEADERS = builddirmanager.h \
builddirreader.h \
cmakebuildinfo.h \
cmakebuildstep.h \
cmakeconfigitem.h \
......@@ -24,14 +25,15 @@ HEADERS = builddirmanager.h \
cmakekitinformation.h \
cmakekitconfigwidget.h \
cmakecbpparser.h \
cmakefile.h \
cmakebuildsettingswidget.h \
cmakeindenter.h \
cmakeautocompleter.h \
configmodel.h \
configmodelitemdelegate.h
configmodelitemdelegate.h \
tealeafreader.h
SOURCES = builddirmanager.cpp \
builddirreader.cpp \
cmakebuildstep.cpp \
cmakeconfigitem.cpp \
cmakeproject.cpp \
......@@ -51,11 +53,11 @@ SOURCES = builddirmanager.cpp \
cmakekitinformation.cpp \
cmakekitconfigwidget.cpp \
cmakecbpparser.cpp \
cmakefile.cpp \
cmakebuildsettingswidget.cpp \
cmakeindenter.cpp \
cmakeautocompleter.cpp \
configmodel.cpp \
configmodelitemdelegate.cpp
configmodelitemdelegate.cpp \
tealeafreader.cpp
RESOURCES += cmakeproject.qrc
......@@ -20,6 +20,8 @@ QtcPlugin {
files: [
"builddirmanager.cpp",
"builddirmanager.h",
"builddirreader.cpp",
"builddirreader.h",
"cmake_global.h",
"cmakebuildconfiguration.cpp",
"cmakebuildconfiguration.h",
......@@ -34,8 +36,6 @@ QtcPlugin {
"cmakeconfigitem.h",
"cmakeeditor.cpp",
"cmakeeditor.h",
"cmakefile.cpp",
"cmakefile.h",
"cmakefilecompletionassist.cpp",
"cmakefilecompletionassist.h",
"cmakekitconfigwidget.h",
......@@ -73,6 +73,8 @@ QtcPlugin {
"configmodel.cpp",
"configmodel.h",
"configmodelitemdelegate.cpp",
"configmodelitemdelegate.h"
"configmodelitemdelegate.h",
"tealeafreader.cpp",
"tealeafreader.h"
]
}
This diff is collapsed.
......@@ -25,23 +25,68 @@
#pragma once
#include <coreplugin/idocument.h>
#include "builddirreader.h"
namespace Utils { class QtcProcess; }
namespace CMakeProjectManager {
namespace Internal {
class BuildDirManager;
class CMakeFile;
class CMakeFile : public Core::IDocument
class TeaLeafReader : public BuildDirReader
{
Q_OBJECT
public:
CMakeFile(BuildDirManager *bdm, const Utils::FileName &fileName);
TeaLeafReader();
~TeaLeafReader() final;
bool isCompatible(const Parameters &p) final;
void resetData() final;
void parse(bool force) final;
void stop() final;
bool isParsing() const final;
bool hasData() const final;
ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override;
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
QList<CMakeBuildTarget> buildTargets() const final;
CMakeConfig parsedConfiguration() const final;
void generateProjectTree(CMakeProjectNode *root) final;
QSet<Core::Id> updateCodeModel(CppTools::ProjectPartBuilder &ppBuilder) final;
private:
BuildDirManager *m_buildDirManager;
void cleanUpProcess();
void extractData();
void startCMake(const QStringList &configurationArguments);
void cmakeFinished(int code, QProcess::ExitStatus status);
void processCMakeOutput();
void processCMakeError();
QStringList getCXXFlagsFor(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
bool extractCXXFlagsFromMake(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
bool extractCXXFlagsFromNinja(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
CMakeConfig parseConfiguration(const Utils::FileName &cacheFile, QString *errorMessage) const;
Utils::QtcProcess *m_cmakeProcess = nullptr;
// For error reporting:
ProjectExplorer::IOutputParser *m_parser = nullptr;
QFutureInterface<void> *m_future = nullptr;
bool m_hasData = false;
mutable CMakeConfig m_cmakeCache;
QSet<Utils::FileName> m_cmakeFiles;
QString m_projectName;
QList<CMakeBuildTarget> m_buildTargets;
QList<ProjectExplorer::FileNode *> m_files;
QSet<Internal::CMakeFile *> m_watchedFiles;
friend class CMakeFile;
};
} // namespace Internal
......
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