forked from qt-creator/qt-creator
Fixes: Some running support for cmake
Task: - RevBy: - AutoTest: - Details: Note: I need to refactor the code significantly, i'm more or less convinced that one build configuration per target is wrong. We probably want one build configuration per build directory and instead build all targets that we are interested then in the makestep. This means we won't have any cmake support for the beta.
This commit is contained in:
@@ -36,10 +36,13 @@
|
|||||||
#include "cmakeprojectnodes.h"
|
#include "cmakeprojectnodes.h"
|
||||||
#include "cmakestep.h"
|
#include "cmakestep.h"
|
||||||
#include "makestep.h"
|
#include "makestep.h"
|
||||||
|
#include "cmakerunconfiguration.h"
|
||||||
|
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <cpptools/cppmodelmanagerinterface.h>
|
#include <cpptools/cppmodelmanagerinterface.h>
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QDir>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
using namespace CMakeProjectManager;
|
using namespace CMakeProjectManager;
|
||||||
@@ -48,20 +51,31 @@ using namespace CMakeProjectManager::Internal;
|
|||||||
CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
|
CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
|
||||||
: m_manager(manager), m_fileName(fileName), m_rootNode(new CMakeProjectNode(m_fileName))
|
: m_manager(manager), m_fileName(fileName), m_rootNode(new CMakeProjectNode(m_fileName))
|
||||||
{
|
{
|
||||||
//TODO
|
|
||||||
m_file = new CMakeFile(this, fileName);
|
m_file = new CMakeFile(this, fileName);
|
||||||
QDir dir = QFileInfo(m_fileName).absoluteDir();
|
QDir dir = QFileInfo(m_fileName).absoluteDir();
|
||||||
QString cbpFile = findCbpFile(dir);
|
QString cbpFile = findCbpFile(dir);
|
||||||
if (cbpFile.isEmpty())
|
if (cbpFile.isEmpty())
|
||||||
cbpFile = createCbpFile(dir);
|
cbpFile = createCbpFile(dir);
|
||||||
|
|
||||||
|
//TODO move this parsing to a seperate method, which is also called if the CMakeList.txt is updated
|
||||||
CMakeCbpParser cbpparser;
|
CMakeCbpParser cbpparser;
|
||||||
if (cbpparser.parseCbpFile(cbpFile)) {
|
if (cbpparser.parseCbpFile(cbpFile)) {
|
||||||
|
// TODO do a intelligent updating of the tree
|
||||||
buildTree(m_rootNode, cbpparser.fileList());
|
buildTree(m_rootNode, cbpparser.fileList());
|
||||||
foreach(ProjectExplorer::FileNode *fn, cbpparser.fileList())
|
foreach(ProjectExplorer::FileNode *fn, cbpparser.fileList())
|
||||||
m_files.append(fn->path());
|
m_files.append(fn->path());
|
||||||
m_files.sort();
|
m_files.sort();
|
||||||
|
|
||||||
|
m_targets = cbpparser.targets();
|
||||||
|
qDebug()<<"Printing targets";
|
||||||
|
foreach(CMakeTarget ct, m_targets) {
|
||||||
|
qDebug()<<ct.title<<" with executable:"<<ct.executable;
|
||||||
|
qDebug()<<"WD:"<<ct.workingDirectory;
|
||||||
|
qDebug()<<ct.makeCommand<<ct.makeCleanCommand;
|
||||||
|
qDebug()<<"";
|
||||||
|
}
|
||||||
|
|
||||||
CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
|
CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
|
||||||
if (modelmanager) {
|
if (modelmanager) {
|
||||||
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
|
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
|
||||||
@@ -69,6 +83,7 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
|
|||||||
// TODO we only want C++ files, not all other stuff that might be in the project
|
// TODO we only want C++ files, not all other stuff that might be in the project
|
||||||
pinfo.sourceFiles = m_files;
|
pinfo.sourceFiles = m_files;
|
||||||
// TODO defines
|
// TODO defines
|
||||||
|
// TODO gcc preprocessor files
|
||||||
modelmanager->updateProjectInfo(pinfo);
|
modelmanager->updateProjectInfo(pinfo);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -96,16 +111,20 @@ QString CMakeProject::findCbpFile(const QDir &directory)
|
|||||||
return QString::null;
|
return QString::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CMakeProject::createCbpFile(const QDir &directory)
|
||||||
QString CMakeProject::createCbpFile(const QDir &)
|
|
||||||
{
|
{
|
||||||
// TODO create a cbp file.
|
// We create a cbp file, only if we didn't find a cbp file in the base directory
|
||||||
// Issue: Where to create it? We want to do that in the build directory
|
// Yet that can still override cbp files in subdirectories
|
||||||
// but at this stage we don't know the build directory yet
|
// And we are creating tons of files in the source directories
|
||||||
// So create it in a temp directory?
|
// All of that is not really nice.
|
||||||
// Issue: We want to reuse whatever CMakeCache.txt that is alread there, which
|
// The mid term plan is to move away from the CodeBlocks Generator and use our own
|
||||||
// would indicate, creating it in the build directory
|
// QtCreator generator, which actually can be very similar to the CodeBlock Generator
|
||||||
// Or we could use a temp directory and use -C builddirectory
|
|
||||||
|
// TODO we need to pass on the same paremeters as the cmakestep
|
||||||
|
QProcess cmake;
|
||||||
|
cmake.setWorkingDirectory(directory.absolutePath());
|
||||||
|
cmake.start("cmake", QStringList() << "-GCodeBlocks - Unix Makefiles");
|
||||||
|
|
||||||
return QString::null;
|
return QString::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,27 +246,35 @@ QStringList CMakeProject::files(FilesMode fileMode) const
|
|||||||
void CMakeProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
|
void CMakeProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
Q_UNUSED(writer);
|
Project::saveSettingsImpl(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader)
|
void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
Q_UNUSED(reader);
|
Project::restoreSettingsImpl(reader);
|
||||||
if (buildConfigurations().isEmpty()) {
|
if (buildConfigurations().isEmpty()) {
|
||||||
// No build configuration, adding those
|
// No build configuration, adding those
|
||||||
|
|
||||||
// TODO do we want to create one build configuration per target?
|
|
||||||
// or how do we want to handle that?
|
|
||||||
|
|
||||||
CMakeStep *cmakeStep = new CMakeStep(this);
|
CMakeStep *cmakeStep = new CMakeStep(this);
|
||||||
MakeStep *makeStep = new MakeStep(this);
|
MakeStep *makeStep = new MakeStep(this);
|
||||||
|
|
||||||
insertBuildStep(0, cmakeStep);
|
insertBuildStep(0, cmakeStep);
|
||||||
insertBuildStep(1, makeStep);
|
insertBuildStep(1, makeStep);
|
||||||
|
|
||||||
addBuildConfiguration("all");
|
// Create build configurations of m_targets
|
||||||
|
qDebug()<<"Create build configurations of m_targets";
|
||||||
|
foreach(const CMakeTarget &ct, m_targets) {
|
||||||
|
addBuildConfiguration(ct.title);
|
||||||
|
makeStep->setValue(ct.title, "makeCommand", ct.makeCommand);
|
||||||
|
makeStep->setValue(ct.title, "makeCleanCommand", ct.makeCleanCommand);
|
||||||
|
|
||||||
|
QSharedPointer<ProjectExplorer::RunConfiguration> rc(new CMakeRunConfiguration(this, ct.executable, ct.workingDirectory));
|
||||||
|
// TODO set build configuration to build before it can be run
|
||||||
|
addRunConfiguration(rc);
|
||||||
|
setActiveRunConfiguration(rc); // TODO what exactly shall be the active run configuration?
|
||||||
|
}
|
||||||
setActiveBuildConfiguration("all");
|
setActiveBuildConfiguration("all");
|
||||||
|
|
||||||
}
|
}
|
||||||
// Restoring is fine
|
// Restoring is fine
|
||||||
}
|
}
|
||||||
@@ -394,14 +421,16 @@ void CMakeCbpParser::parseBuild()
|
|||||||
|
|
||||||
void CMakeCbpParser::parseTarget()
|
void CMakeCbpParser::parseTarget()
|
||||||
{
|
{
|
||||||
m_targetOutput.clear();
|
|
||||||
m_targetType = false;
|
m_targetType = false;
|
||||||
|
m_target.clear();
|
||||||
|
|
||||||
|
if (attributes().hasAttribute("title"))
|
||||||
|
m_target.title = attributes().value("title").toString();
|
||||||
while(!atEnd()) {
|
while(!atEnd()) {
|
||||||
readNext();
|
readNext();
|
||||||
if (isEndElement()) {
|
if (isEndElement()) {
|
||||||
if (m_targetType && !m_targetOutput.isEmpty()) {
|
if (m_targetType || m_target.title == "all") {
|
||||||
qDebug()<<"found target "<<m_targetOutput;
|
m_targets.append(m_target);
|
||||||
m_targets.insert(m_targetOutput);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (name() == "Compiler") {
|
} else if (name() == "Compiler") {
|
||||||
@@ -417,9 +446,57 @@ void CMakeCbpParser::parseTarget()
|
|||||||
void CMakeCbpParser::parseTargetOption()
|
void CMakeCbpParser::parseTargetOption()
|
||||||
{
|
{
|
||||||
if (attributes().hasAttribute("output"))
|
if (attributes().hasAttribute("output"))
|
||||||
m_targetOutput = attributes().value("output").toString();
|
m_target.executable = attributes().value("output").toString();
|
||||||
else if (attributes().hasAttribute("type") && attributes().value("type") == "1")
|
else if (attributes().hasAttribute("type") && attributes().value("type") == "1")
|
||||||
m_targetType = true;
|
m_targetType = true;
|
||||||
|
else if (attributes().hasAttribute("working_dir"))
|
||||||
|
m_target.workingDirectory = attributes().value("working_dir").toString();
|
||||||
|
while(!atEnd()) {
|
||||||
|
readNext();
|
||||||
|
if (isEndElement()) {
|
||||||
|
return;
|
||||||
|
} else if (name() == "MakeCommand") {
|
||||||
|
parseMakeCommand();
|
||||||
|
} else if (isStartElement()) {
|
||||||
|
parseUnknownElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeCbpParser::parseMakeCommand()
|
||||||
|
{
|
||||||
|
while(!atEnd()) {
|
||||||
|
readNext();
|
||||||
|
if (isEndElement()) {
|
||||||
|
return;
|
||||||
|
} else if (name() == "Build") {
|
||||||
|
parseTargetBuild();
|
||||||
|
} else if (name() == "Clean") {
|
||||||
|
parseTargetClean();
|
||||||
|
} else if (isStartElement()) {
|
||||||
|
parseUnknownElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeCbpParser::parseTargetBuild()
|
||||||
|
{
|
||||||
|
if (attributes().hasAttribute("command"))
|
||||||
|
m_target.makeCommand = attributes().value("command").toString();
|
||||||
|
while(!atEnd()) {
|
||||||
|
readNext();
|
||||||
|
if (isEndElement()) {
|
||||||
|
return;
|
||||||
|
} else if (isStartElement()) {
|
||||||
|
parseUnknownElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeCbpParser::parseTargetClean()
|
||||||
|
{
|
||||||
|
if (attributes().hasAttribute("command"))
|
||||||
|
m_target.makeCleanCommand = attributes().value("command").toString();
|
||||||
while(!atEnd()) {
|
while(!atEnd()) {
|
||||||
readNext();
|
readNext();
|
||||||
if (isEndElement()) {
|
if (isEndElement()) {
|
||||||
@@ -497,3 +574,18 @@ QStringList CMakeCbpParser::includeFiles()
|
|||||||
{
|
{
|
||||||
return m_includeFiles;
|
return m_includeFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<CMakeTarget> CMakeCbpParser::targets()
|
||||||
|
{
|
||||||
|
return m_targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeTarget::clear()
|
||||||
|
{
|
||||||
|
executable = QString::null;
|
||||||
|
makeCommand = QString::null;
|
||||||
|
makeCleanCommand = QString::null;
|
||||||
|
workingDirectory = QString::null;
|
||||||
|
title = QString::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ namespace Internal{
|
|||||||
|
|
||||||
class CMakeFile;
|
class CMakeFile;
|
||||||
|
|
||||||
|
struct CMakeTarget
|
||||||
|
{
|
||||||
|
QString title;
|
||||||
|
QString executable;
|
||||||
|
QString workingDirectory;
|
||||||
|
QString makeCommand;
|
||||||
|
QString makeCleanCommand;
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
|
||||||
class CMakeProject : public ProjectExplorer::Project
|
class CMakeProject : public ProjectExplorer::Project
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -105,6 +115,7 @@ private:
|
|||||||
// TODO probably need a CMake specific node structure
|
// TODO probably need a CMake specific node structure
|
||||||
CMakeProjectNode* m_rootNode;
|
CMakeProjectNode* m_rootNode;
|
||||||
QStringList m_files;
|
QStringList m_files;
|
||||||
|
QList<CMakeTarget> m_targets;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer);
|
virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer);
|
||||||
@@ -118,23 +129,27 @@ public:
|
|||||||
bool parseCbpFile(const QString &fileName);
|
bool parseCbpFile(const QString &fileName);
|
||||||
QList<ProjectExplorer::FileNode *> fileList();
|
QList<ProjectExplorer::FileNode *> fileList();
|
||||||
QStringList includeFiles();
|
QStringList includeFiles();
|
||||||
|
QList<CMakeTarget> targets();
|
||||||
private:
|
private:
|
||||||
void parseCodeBlocks_project_file();
|
void parseCodeBlocks_project_file();
|
||||||
void parseProject();
|
void parseProject();
|
||||||
void parseBuild();
|
void parseBuild();
|
||||||
void parseTarget();
|
void parseTarget();
|
||||||
void parseTargetOption();
|
void parseTargetOption();
|
||||||
|
void parseMakeCommand();
|
||||||
|
void parseTargetBuild();
|
||||||
|
void parseTargetClean();
|
||||||
void parseCompiler();
|
void parseCompiler();
|
||||||
void parseAdd();
|
void parseAdd();
|
||||||
void parseUnit();
|
void parseUnit();
|
||||||
void parseUnknownElement();
|
void parseUnknownElement();
|
||||||
|
|
||||||
QSet<QString> m_targets;
|
|
||||||
QList<ProjectExplorer::FileNode *> m_fileList;
|
QList<ProjectExplorer::FileNode *> m_fileList;
|
||||||
QStringList m_includeFiles;
|
QStringList m_includeFiles;
|
||||||
|
|
||||||
QString m_targetOutput;
|
CMakeTarget m_target;
|
||||||
bool m_targetType;
|
bool m_targetType;
|
||||||
|
QList<CMakeTarget> m_targets;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMakeFile : public Core::IFile
|
class CMakeFile : public Core::IFile
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ const char * const PROJECTCONTEXT = "CMakeProject.ProjectContext";
|
|||||||
const char * const CMAKEMIMETYPE = "text/x-cmake"; // TOOD check that this is correct
|
const char * const CMAKEMIMETYPE = "text/x-cmake"; // TOOD check that this is correct
|
||||||
const char * const CMAKESTEP = "CMakeProjectManager.CMakeStep";
|
const char * const CMAKESTEP = "CMakeProjectManager.CMakeStep";
|
||||||
const char * const MAKESTEP = "CMakeProjectManager.MakeStep";
|
const char * const MAKESTEP = "CMakeProjectManager.MakeStep";
|
||||||
|
const char * const CMAKERUNCONFIGURATION = "CMakeProjectManager.CMakeRunConfiguration";
|
||||||
|
|
||||||
|
|
||||||
} // namespace Constants
|
} // namespace Constants
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ HEADERS = cmakeproject.h \
|
|||||||
cmakeprojectconstants.h \
|
cmakeprojectconstants.h \
|
||||||
cmakeprojectnodes.h \
|
cmakeprojectnodes.h \
|
||||||
cmakestep.h \
|
cmakestep.h \
|
||||||
makestep.h
|
makestep.h \
|
||||||
|
cmakerunconfiguration.h
|
||||||
SOURCES = cmakeproject.cpp \
|
SOURCES = cmakeproject.cpp \
|
||||||
cmakeprojectplugin.cpp \
|
cmakeprojectplugin.cpp \
|
||||||
cmakeprojectmanager.cpp \
|
cmakeprojectmanager.cpp \
|
||||||
cmakeprojectnodes.cpp \
|
cmakeprojectnodes.cpp \
|
||||||
cmakestep.cpp \
|
cmakestep.cpp \
|
||||||
makestep.cpp
|
makestep.cpp \
|
||||||
|
cmakerunconfiguration.cpp
|
||||||
RESOURCES += cmakeproject.qrc
|
RESOURCES += cmakeproject.qrc
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "cmakeprojectplugin.h"
|
#include "cmakeprojectplugin.h"
|
||||||
#include "cmakeprojectmanager.h"
|
#include "cmakeprojectmanager.h"
|
||||||
|
#include "cmakerunconfiguration.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/mimedatabase.h>
|
#include <coreplugin/mimedatabase.h>
|
||||||
@@ -57,6 +58,7 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *
|
|||||||
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":cmakeproject/CMakeProject.mimetypes.xml"), errorMessage))
|
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":cmakeproject/CMakeProject.mimetypes.xml"), errorMessage))
|
||||||
return false;
|
return false;
|
||||||
addAutoReleasedObject(new CMakeManager());
|
addAutoReleasedObject(new CMakeManager());
|
||||||
|
addAutoReleasedObject(new CMakeRunConfigurationFactory());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ bool CMakeStep::init(const QString &buildConfiguration)
|
|||||||
|
|
||||||
void CMakeStep::run(QFutureInterface<bool> &fi)
|
void CMakeStep::run(QFutureInterface<bool> &fi)
|
||||||
{
|
{
|
||||||
|
// TODO we want to only run cmake if the command line arguments or
|
||||||
|
// the CmakeLists.txt has actually changed
|
||||||
|
// And we want all of them to share the SAME command line arguments
|
||||||
|
// Shadow building ruins this, hmm, hmm
|
||||||
|
//
|
||||||
AbstractProcessStep::run(fi);
|
AbstractProcessStep::run(fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public:
|
|||||||
void setName(const QString &name);
|
void setName(const QString &name);
|
||||||
|
|
||||||
// Returns the widget used to configure this run configuration. Ownership is transferred to the caller
|
// Returns the widget used to configure this run configuration. Ownership is transferred to the caller
|
||||||
|
// rename to createConfigurationWidget
|
||||||
virtual QWidget *configurationWidget() = 0;
|
virtual QWidget *configurationWidget() = 0;
|
||||||
|
|
||||||
virtual void save(PersistentSettingsWriter &writer) const;
|
virtual void save(PersistentSettingsWriter &writer) const;
|
||||||
@@ -112,7 +113,6 @@ public:
|
|||||||
// used to translate the types to names to display to the user
|
// used to translate the types to names to display to the user
|
||||||
virtual QString nameForType(const QString &type) const = 0;
|
virtual QString nameForType(const QString &type) const = 0;
|
||||||
virtual QSharedPointer<RunConfiguration> create(Project *project, const QString &type) = 0;
|
virtual QSharedPointer<RunConfiguration> create(Project *project, const QString &type) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT IRunConfigurationRunner : public QObject
|
class PROJECTEXPLORER_EXPORT IRunConfigurationRunner : public QObject
|
||||||
|
|||||||
Reference in New Issue
Block a user