From 0b21f2898f5a2f04c888bc1972846fcc714fc076 Mon Sep 17 00:00:00 2001 From: dt <qtc-commiter@nokia.com> Date: Mon, 12 Jan 2009 15:10:33 +0100 Subject: [PATCH] Fixes: Various stuff in the cmake project. Details: Not yet usable, but at least you get a list of build targets now. --- .../cmakeprojectmanager/cmakeproject.cpp | 110 +++++++++++++----- .../cmakeprojectmanager/cmakeproject.h | 16 ++- src/plugins/cmakeprojectmanager/cmakestep.cpp | 7 +- src/plugins/cmakeprojectmanager/cmakestep.h | 1 + src/plugins/cmakeprojectmanager/makestep.cpp | 67 ++++++++++- src/plugins/cmakeprojectmanager/makestep.h | 16 +++ 6 files changed, 182 insertions(+), 35 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index b6e1f159b79..f8d68ccfaa7 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -46,6 +46,7 @@ #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QProcess> +#include <QtGui/QFormLayout> using namespace CMakeProjectManager; using namespace CMakeProjectManager::Internal; @@ -61,27 +62,39 @@ using namespace CMakeProjectManager::Internal; // Who sets up the environment for cl.exe ? INCLUDEPATH and so on + CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName) : m_manager(manager), m_fileName(fileName), m_rootNode(new CMakeProjectNode(m_fileName)) { - m_file = new CMakeFile(this, fileName); QDir dir = QFileInfo(m_fileName).absoluteDir(); - QString cbpFile = findCbpFile(dir); - if (cbpFile.isEmpty()) { - createCbpFile(dir); - cbpFile = findCbpFile(dir); - } + parseCMakeLists(dir); +} + +CMakeProject::~CMakeProject() +{ + delete m_rootNode; +} + +// TODO also call this method if the CMakeLists.txt file changed, which is also called if the CMakeList.txt is updated +// TODO make this function work even if it is reparsing +void CMakeProject::parseCMakeLists(const QDir &directory) +{ + createCbpFile(directory); + + QString cbpFile = findCbpFile(directory); - //TODO move this parsing to a seperate method, which is also called if the CMakeList.txt is updated CMakeCbpParser cbpparser; + qDebug()<<"Parsing file "<<cbpFile; if (cbpparser.parseCbpFile(cbpFile)) { + qDebug()<<"Building Tree"; // TODO do a intelligent updating of the tree buildTree(m_rootNode, cbpparser.fileList()); foreach (ProjectExplorer::FileNode *fn, cbpparser.fileList()) m_files.append(fn->path()); m_files.sort(); + qDebug()<<"Adding Targets"; m_targets = cbpparser.targets(); qDebug()<<"Printing targets"; foreach(CMakeTarget ct, m_targets) { @@ -91,6 +104,7 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName) qDebug()<<""; } + qDebug()<<"Updating CodeModel"; CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>(); if (modelmanager) { CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this); @@ -106,9 +120,12 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName) } } -CMakeProject::~CMakeProject() +QStringList CMakeProject::targets() const { - delete m_rootNode; + QStringList results; + foreach(const CMakeTarget &ct, m_targets) + results << ct.title; + return results; } QString CMakeProject::findCbpFile(const QDir &directory) @@ -134,10 +151,12 @@ void CMakeProject::createCbpFile(const QDir &directory) // QtCreator generator, which actually can be very similar to the CodeBlock Generator // TODO we need to pass on the same paremeters as the cmakestep + qDebug()<<"Creating cbp file"; QProcess cmake; cmake.setWorkingDirectory(directory.absolutePath()); cmake.start("cmake", QStringList() << "-GCodeBlocks - Unix Makefiles"); - cmake.waitForFinished(); + cmake.waitForFinished(-1); + qDebug()<<"cmake output: \n"<<cmake.readAll(); } void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list) @@ -219,14 +238,15 @@ ProjectExplorer::Environment CMakeProject::environment(const QString &buildConfi QString CMakeProject::buildDirectory(const QString &buildConfiguration) const { - Q_UNUSED(buildConfiguration) - //TODO - return QFileInfo(m_fileName).absolutePath(); + QString buildDirectory = value(buildConfiguration, "buildDirectory").toString(); + if (buildDirectory.isEmpty()) + buildDirectory = QFileInfo(m_fileName).absolutePath(); + return buildDirectory; } ProjectExplorer::BuildStepConfigWidget *CMakeProject::createConfigWidget() { - return new CMakeBuildSettingsWidget; + return new CMakeBuildSettingsWidget(this); } QList<ProjectExplorer::BuildStepConfigWidget*> CMakeProject::subConfigWidgets() @@ -238,8 +258,8 @@ QList<ProjectExplorer::BuildStepConfigWidget*> CMakeProject::subConfigWidgets() // You should probably set some default values in this method void CMakeProject::newBuildConfiguration(const QString &buildConfiguration) { - Q_UNUSED(buildConfiguration); - //TODO + // Default to all + makeStep()->setBuildTarget(buildConfiguration, "all", true); } ProjectExplorer::ProjectNode *CMakeProject::rootProjectNode() const @@ -261,6 +281,25 @@ void CMakeProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &w Project::saveSettingsImpl(writer); } +MakeStep *CMakeProject::makeStep() const +{ + foreach (ProjectExplorer::BuildStep *bs, buildSteps()) { + MakeStep *ms = qobject_cast<MakeStep *>(bs); + if (ms) + return ms; + } + return 0; +} + +CMakeStep *CMakeProject::cmakeStep() const +{ + foreach (ProjectExplorer::BuildStep *bs, buildSteps()) { + if (CMakeStep *cs = qobject_cast<CMakeStep *>(bs)) + return cs; + } + return 0; +} + void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader) { // TODO @@ -273,12 +312,12 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader insertBuildStep(0, cmakeStep); insertBuildStep(1, makeStep); - addBuildConfiguration("AllTargets"); - setActiveBuildConfiguration("AllTargets"); - makeStep->setValue("AllTargets", "buildTargets", QStringList() << "all"); + addBuildConfiguration("all"); + setActiveBuildConfiguration("all"); + makeStep->setBuildTarget("all", "all", true); - // Create build configurations of m_targets - qDebug()<<"Create build configurations of m_targets"; + // Create run configurations for m_targets + qDebug()<<"Create run configurations of m_targets"; bool setActive = false; foreach(const CMakeTarget &ct, m_targets) { QSharedPointer<ProjectExplorer::RunConfiguration> rc(new CMakeRunConfiguration(this, ct.executable, ct.workingDirectory)); @@ -289,7 +328,6 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader setActive = true; } } - setActiveBuildConfiguration("all"); } // Restoring is fine @@ -352,10 +390,19 @@ void CMakeFile::modified(ReloadBehavior *behavior) Q_UNUSED(behavior); } - -CMakeBuildSettingsWidget::CMakeBuildSettingsWidget() +CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeProject *project) + : m_project(project) { - + QFormLayout *fl = new QFormLayout(this); + setLayout(fl); + m_pathChooser = new Core::Utils::PathChooser(this); + m_pathChooser->setEnabled(false); + // TODO currently doesn't work + // since creating the cbp file also creates makefiles + // and then cmake builds in that directory instead of shadow building + // We need our own generator for that to work + connect(m_pathChooser, SIGNAL(changed()), this, SLOT(buildDirectoryChanged())); + fl->addRow("Build directory:", m_pathChooser); } QString CMakeBuildSettingsWidget::displayName() const @@ -365,10 +412,19 @@ QString CMakeBuildSettingsWidget::displayName() const void CMakeBuildSettingsWidget::init(const QString &buildConfiguration) { - Q_UNUSED(buildConfiguration); - // TODO + m_buildConfiguration = buildConfiguration; + m_pathChooser->setPath(m_project->buildDirectory(buildConfiguration)); } +void CMakeBuildSettingsWidget::buildDirectoryChanged() +{ + m_project->setValue(m_buildConfiguration, "buildDirectory", m_pathChooser->path()); +} + +///// +// CMakeCbpParser +//// + bool CMakeCbpParser::parseCbpFile(const QString &fileName) { QFile fi(fileName); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index c6a93f8693c..13bec80bb9c 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -36,11 +36,14 @@ #include "cmakeprojectmanager.h" #include "cmakeprojectnodes.h" +#include "makestep.h" +#include "cmakestep.h" #include <projectexplorer/project.h> #include <projectexplorer/projectnodes.h> #include <projectexplorer/buildstep.h> #include <coreplugin/ifile.h> +#include <utils/pathchooser.h> #include <QtCore/QXmlStreamReader> @@ -99,8 +102,12 @@ public: // virtual Node *nodeForFile(const QString &filePath) const = 0; virtual QStringList files(FilesMode fileMode) const; + MakeStep *makeStep() const; + CMakeStep *cmakeStep() const; + QStringList targets() const; private: + void parseCMakeLists(const QDir &directory); QString findCbpFile(const QDir &); void createCbpFile(const QDir &); @@ -177,13 +184,20 @@ private: class CMakeBuildSettingsWidget : public ProjectExplorer::BuildStepConfigWidget { + Q_OBJECT public: - CMakeBuildSettingsWidget(); + CMakeBuildSettingsWidget(CMakeProject *project); virtual QString displayName() const; // This is called to set up the config widget before showing it // buildConfiguration is QString::null for the non buildConfiguration specific page virtual void init(const QString &buildConfiguration); +private slots: + void buildDirectoryChanged(); +private: + CMakeProject *m_project; + Core::Utils::PathChooser *m_pathChooser; + QString m_buildConfiguration; }; } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmakestep.cpp b/src/plugins/cmakeprojectmanager/cmakestep.cpp index 13963273287..c286712c914 100644 --- a/src/plugins/cmakeprojectmanager/cmakestep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakestep.cpp @@ -55,7 +55,8 @@ bool CMakeStep::init(const QString &buildConfiguration) setEnabled(buildConfiguration, true); setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration)); setCommand(buildConfiguration, "cmake"); // TODO give full path here? - setArguments(buildConfiguration, QStringList() << "-GUnix Makefiles"); // TODO + QString sourceDir = QFileInfo(m_pro->file()->fileName()).absolutePath(); + setArguments(buildConfiguration, QStringList() << sourceDir << "-GUnix Makefiles"); // TODO setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration)); return AbstractProcessStep::init(buildConfiguration); } @@ -72,12 +73,12 @@ void CMakeStep::run(QFutureInterface<bool> &fi) QString CMakeStep::name() { - return "CMake"; + return Constants::CMAKESTEP; } QString CMakeStep::displayName() { - return Constants::CMAKESTEP; + return "CMake"; } ProjectExplorer::BuildStepConfigWidget *CMakeStep::createConfigWidget() diff --git a/src/plugins/cmakeprojectmanager/cmakestep.h b/src/plugins/cmakeprojectmanager/cmakestep.h index a0a20b0c50d..44f9bf7f601 100644 --- a/src/plugins/cmakeprojectmanager/cmakestep.h +++ b/src/plugins/cmakeprojectmanager/cmakestep.h @@ -46,6 +46,7 @@ class CMakeBuildStepConfigWidget; class CMakeStep : public ProjectExplorer::AbstractProcessStep { + Q_OBJECT public: CMakeStep(CMakeProject *pro); ~CMakeStep(); diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp index abd77cd10aa..ef956f38eea 100644 --- a/src/plugins/cmakeprojectmanager/makestep.cpp +++ b/src/plugins/cmakeprojectmanager/makestep.cpp @@ -36,6 +36,11 @@ #include "cmakeproject.h" #include <utils/qtcassert.h> +#include <QtGui/QFormLayout> +#include <QtGui/QGroupBox> +#include <QtGui/QCheckBox> +#include <QtGui/QLineEdit> +#include <QtGui/QListWidget> using namespace CMakeProjectManager; using namespace CMakeProjectManager::Internal; @@ -66,17 +71,17 @@ void MakeStep::run(QFutureInterface<bool> &fi) QString MakeStep::name() { - return "Make"; + return Constants::CMAKESTEP; } QString MakeStep::displayName() { - return Constants::CMAKESTEP; + return "Make"; } ProjectExplorer::BuildStepConfigWidget *MakeStep::createConfigWidget() { - return new MakeBuildStepConfigWidget(); + return new MakeBuildStepConfigWidget(this); } bool MakeStep::immutable() const @@ -84,18 +89,72 @@ bool MakeStep::immutable() const return true; } +CMakeProject *MakeStep::project() const +{ + return m_pro; +} + +bool MakeStep::buildsTarget(const QString &buildConfiguration, const QString &target) const +{ + return value(buildConfiguration, "buildTargets").toStringList().contains(target); +} + +void MakeStep::setBuildTarget(const QString &buildConfiguration, const QString &target, bool on) +{ + QStringList old = value(buildConfiguration, "buildTargets").toStringList(); + if (on && !old.contains(target)) + setValue(buildConfiguration, "buildTargets", old << target); + else if(!on && old.contains(target)) + setValue(buildConfiguration, "buildTargets", old.removeOne(target)); +} + // // CMakeBuildStepConfigWidget // +MakeBuildStepConfigWidget::MakeBuildStepConfigWidget(MakeStep *makeStep) + : m_makeStep(makeStep) +{ + QFormLayout *fl = new QFormLayout(this); + setLayout(fl); + + m_targetsList = new QListWidget; + fl->addRow("Targets:", m_targetsList); + + // TODO update this list also on rescans of the CMakeLists.txt + CMakeProject *pro = m_makeStep->project(); + foreach(const QString& target, pro->targets()) { + QListWidgetItem *item = new QListWidgetItem(target, m_targetsList); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(Qt::Unchecked); + } + connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); +} + +void MakeBuildStepConfigWidget::itemChanged(QListWidgetItem *item) +{ + m_makeStep->setBuildTarget(m_buildConfiguration, item->text(), item->checkState() & Qt::Checked); +} QString MakeBuildStepConfigWidget::displayName() const { return "Make"; } -void MakeBuildStepConfigWidget::init(const QString & /* buildConfiguration */) +void MakeBuildStepConfigWidget::init(const QString &buildConfiguration) { // TODO + + // disconnect to make the changes to the items + disconnect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); + m_buildConfiguration = buildConfiguration; + int count = m_targetsList->count(); + for(int i = 0; i < count; ++i) { + QListWidgetItem *item = m_targetsList->item(i); + item->setCheckState(m_makeStep->buildsTarget(buildConfiguration, item->text()) ? Qt::Checked : Qt::Unchecked); + } + // and connect again + connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); + } // diff --git a/src/plugins/cmakeprojectmanager/makestep.h b/src/plugins/cmakeprojectmanager/makestep.h index 33800265d6a..1b32ab6f2fc 100644 --- a/src/plugins/cmakeprojectmanager/makestep.h +++ b/src/plugins/cmakeprojectmanager/makestep.h @@ -36,6 +36,10 @@ #include <projectexplorer/abstractprocessstep.h> +class QLineEdit; +class QListWidget; +class QListWidgetItem; + namespace CMakeProjectManager { namespace Internal { @@ -43,6 +47,7 @@ class CMakeProject; class MakeStep : public ProjectExplorer::AbstractProcessStep { + Q_OBJECT public: MakeStep(CMakeProject *pro); ~MakeStep(); @@ -54,15 +59,26 @@ public: virtual QString displayName(); virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); virtual bool immutable() const; + CMakeProject *project() const; + bool buildsTarget(const QString &buildConfiguration, const QString &target) const; + void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on); private: CMakeProject *m_pro; }; class MakeBuildStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget { + Q_OBJECT public: + MakeBuildStepConfigWidget(MakeStep *makeStep); virtual QString displayName() const; virtual void init(const QString &buildConfiguration); +private slots: + void itemChanged(QListWidgetItem*); +private: + QString m_buildConfiguration; + MakeStep * m_makeStep; + QListWidget *m_targetsList; }; class MakeBuildStepFactory : public ProjectExplorer::IBuildStepFactory -- GitLab