diff options
author | Patricia Santana Cruz <patriciasc@openismus.com> | 2011-11-29 14:19:28 +0100 |
---|---|---|
committer | hjk <qthjk@ovi.com> | 2011-11-30 14:16:12 +0100 |
commit | 6445c99ad2020182b5d105b29e373de6273cb5f5 (patch) | |
tree | 66540891455785e38b7a6e9ac3ded71686f708fc /src | |
parent | 442f2d6972d3abf76fcece0a996a810000ba1f3a (diff) | |
download | qt-creator-6445c99ad2020182b5d105b29e373de6273cb5f5.tar.gz |
Add AutotoolsProjectManager plugin
Change-Id: Icbc8d105a3ffea2bf705d18e3413f6b3487ccfd3
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Reviewed-by: hjk <qthjk@ovi.com>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@nokia.com>
Diffstat (limited to 'src')
38 files changed, 5484 insertions, 1 deletions
diff --git a/src/plugins/autotoolsprojectmanager/AutotoolsProject.mimetypes.xml b/src/plugins/autotoolsprojectmanager/AutotoolsProject.mimetypes.xml new file mode 100644 index 0000000000..6e32748d2c --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/AutotoolsProject.mimetypes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'> + <mime-type type="text/x-makefile"> + <sub-class-of type="text/plain"/> + <comment>Automake based Makefile</comment> + <glob weight="10" pattern="Makefile.am"/> + </mime-type> +</mime-info> diff --git a/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in b/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in new file mode 100644 index 0000000000..31bd06076a --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in @@ -0,0 +1,23 @@ +<plugin name=\"AutotoolsProjectManager\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_VERSION\"> + <vendor>Openismus GmbH</vendor> + <copyright>(C) 2010 Openismus GmbH</copyright> + <license>GNU Lesser General Public License Usage + This file may be used under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation and + appearing in the file LICENSE.LGPL included in the packaging of this file. + Please review the following information to ensure the GNU Lesser General + Public License version 2.1 requirements will be met: + http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + + In addition, as a special exception, Nokia gives you certain additional + rights. These rights are described in the Nokia Qt LGPL Exception + version 1.1, included in the file LGPL_EXCEPTION.txt in this package.</license> + <category>Build Systems</category> + <description>Autotools project integration.</description> + <url>http://qt.nokia.com</url> + <dependencyList> + <dependency name=\"Core\" version=\"$$QTCREATOR_VERSION\"/> + <dependency name=\"ProjectExplorer\" version=\"$$QTCREATOR_VERSION\"/> + <dependency name=\"CppTools\" version=\"$$QTCREATOR_VERSION\"/> + </dependencyList> +</plugin> diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.cpp b/src/plugins/autotoolsprojectmanager/autogenstep.cpp new file mode 100644 index 0000000000..f5144e8d9c --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autogenstep.cpp @@ -0,0 +1,305 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autogenstep.h" +#include "autotoolsproject.h" +#include "autotoolstarget.h" +#include "autotoolsbuildconfiguration.h" +#include "autotoolsprojectconstants.h" + +#include <projectexplorer/buildsteplist.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/gnumakeparser.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <utils/qtcprocess.h> + +#include <QtCore/QVariantMap> +#include <QtCore/QDateTime> +#include <QtGui/QLineEdit> +#include <QtGui/QFormLayout> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; +using namespace ProjectExplorer; + +namespace { +const char AUTOGEN_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.AutogenStep.AdditionalArguments"; +const char AUTOGEN_STEP_ID[] = "AutotoolsProjectManager.AutogenStep"; +} + +///////////////////////////// +// AutogenStepFactory class +///////////////////////////// +AutogenStepFactory::AutogenStepFactory(QObject *parent) : + ProjectExplorer::IBuildStepFactory(parent) +{ +} + +AutogenStepFactory::~AutogenStepFactory() +{ +} + +QStringList AutogenStepFactory::availableCreationIds(BuildStepList *parent) const +{ + if (parent->target()->project()->id() == QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return QStringList() << QLatin1String(AUTOGEN_STEP_ID); + return QStringList(); +} + +QString AutogenStepFactory::displayNameForId(const QString &id) const +{ + if (id == QLatin1String(AUTOGEN_STEP_ID)) + return tr("Autogen", "Display name for AutotoolsProjectManager::AutogenStep id."); + return QString(); +} + +bool AutogenStepFactory::canCreate(BuildStepList *parent, const QString &id) const +{ + if (parent->target()->project()->id() != QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return false; + + if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD) + return false; + + return QLatin1String(AUTOGEN_STEP_ID) == id; +} + +BuildStep *AutogenStepFactory::create(BuildStepList *parent, const QString &id) +{ + if (!canCreate(parent, id)) + return 0; + return new AutogenStep(parent); +} + +bool AutogenStepFactory::canClone(BuildStepList *parent, BuildStep *source) const +{ + return canCreate(parent, source->id()); +} + +BuildStep *AutogenStepFactory::clone(BuildStepList *parent, BuildStep *source) +{ + if (!canClone(parent, source)) + return 0; + return new AutogenStep(parent, static_cast<AutogenStep *>(source)); +} + +bool AutogenStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const +{ + QString id(ProjectExplorer::idFromMap(map)); + return canCreate(parent, id); +} + +BuildStep *AutogenStepFactory::restore(BuildStepList *parent, const QVariantMap &map) +{ + if (!canRestore(parent, map)) + return 0; + AutogenStep *bs = new AutogenStep(parent); + if (bs->fromMap(map)) + return bs; + delete bs; + return 0; +} + +//////////////////////// +// AutogenStep class +//////////////////////// +AutogenStep::AutogenStep(ProjectExplorer::BuildStepList *bsl) : + AbstractProcessStep(bsl, QLatin1String(AUTOGEN_STEP_ID)), + m_runAutogen(false) +{ + ctor(); +} + +AutogenStep::AutogenStep(ProjectExplorer::BuildStepList *bsl, const QString &id) : + AbstractProcessStep(bsl, id) +{ + ctor(); +} + +AutogenStep::AutogenStep(ProjectExplorer::BuildStepList *bsl, AutogenStep *bs) : + AbstractProcessStep(bsl, bs), + m_additionalArguments(bs->additionalArguments()) +{ + ctor(); +} + +void AutogenStep::ctor() +{ + setDefaultDisplayName(tr("Autogen")); +} + +AutogenStep::~AutogenStep() +{ +} + +AutotoolsBuildConfiguration *AutogenStep::autotoolsBuildConfiguration() const +{ + return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); +} + +bool AutogenStep::init() +{ + AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + + setEnabled(true); + + ProcessParameters *pp = processParameters(); + pp->setMacroExpander(bc->macroExpander()); + pp->setEnvironment(bc->environment()); + pp->setWorkingDirectory(bc->buildDirectory()); + pp->setCommand(QLatin1String("autogen.sh")); + pp->setArguments(additionalArguments()); + + return AbstractProcessStep::init(); +} + +void AutogenStep::run(QFutureInterface<bool> &interface) +{ + AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + + // Check wether we need to run autogen.sh + const QFileInfo configureInfo(bc->buildDirectory() + QLatin1String("/configure")); + const QFileInfo configureAcInfo(bc->buildDirectory() + QLatin1String("/configure.ac")); + const QFileInfo makefileAmInfo(bc->buildDirectory() + QLatin1String("/Makefile.am")); + + if (!configureInfo.exists() + || configureInfo.lastModified() < configureAcInfo.lastModified() + || configureInfo.lastModified() < makefileAmInfo.lastModified()) { + m_runAutogen = true; + } + + if (!m_runAutogen) { + emit addOutput(tr("Configuration unchanged, skipping autogen step."), BuildStep::MessageOutput); + interface.reportResult(true); + return; + } + + m_runAutogen = false; + AbstractProcessStep::run(interface); +} + +ProjectExplorer::BuildStepConfigWidget* AutogenStep::createConfigWidget() +{ + return new AutogenStepConfigWidget(this); +} + +bool AutogenStep::immutable() const +{ + return false; +} + +void AutogenStep::setAdditionalArguments(const QString &list) +{ + if (list == m_additionalArguments) + return; + + m_additionalArguments = list; + m_runAutogen = true; + + emit additionalArgumentsChanged(list); +} + +QString AutogenStep::additionalArguments() const +{ + return m_additionalArguments; +} + +QVariantMap AutogenStep::toMap() const +{ + QVariantMap map(AbstractProcessStep::toMap()); + + map.insert(QLatin1String(AUTOGEN_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments); + return map; +} + +bool AutogenStep::fromMap(const QVariantMap &map) +{ + m_additionalArguments = map.value(QLatin1String(AUTOGEN_ADDITIONAL_ARGUMENTS_KEY)).toString(); + + return BuildStep::fromMap(map); +} + +////////////////////////////////// +// AutogenStepConfigWidget class +////////////////////////////////// +AutogenStepConfigWidget::AutogenStepConfigWidget(AutogenStep *autogenStep) : + m_autogenStep(autogenStep), + m_summaryText(), + m_additionalArguments(0) +{ + QFormLayout *fl = new QFormLayout(this); + fl->setMargin(0); + fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); + setLayout(fl); + + m_additionalArguments = new QLineEdit(this); + fl->addRow(tr("Arguments:"), m_additionalArguments); + m_additionalArguments->setText(m_autogenStep->additionalArguments()); + + updateDetails(); + + connect(m_additionalArguments, SIGNAL(textChanged(QString)), + autogenStep, SLOT(setAdditionalArguments(QString))); + connect(autogenStep, SIGNAL(additionalArgumentsChanged(QString)), + this, SLOT(updateDetails())); +} + +AutogenStepConfigWidget::~AutogenStepConfigWidget() +{ +} + +QString AutogenStepConfigWidget::displayName() const +{ + return tr("Autogen", "AutotoolsProjectManager::AutogenStepConfigWidget display name."); +} + +QString AutogenStepConfigWidget::summaryText() const +{ + return m_summaryText; +} + +void AutogenStepConfigWidget::updateDetails() +{ + AutotoolsBuildConfiguration *bc = m_autogenStep->autotoolsBuildConfiguration(); + + ProcessParameters param; + param.setMacroExpander(bc->macroExpander()); + param.setEnvironment(bc->environment()); + param.setWorkingDirectory(bc->buildDirectory()); + param.setCommand("autogen.sh"); + param.setArguments(m_autogenStep->additionalArguments()); + m_summaryText = param.summary(displayName()); + emit updateSummary(); +} diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.h b/src/plugins/autotoolsprojectmanager/autogenstep.h new file mode 100644 index 0000000000..4fa0590211 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autogenstep.h @@ -0,0 +1,162 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOGENSTEP_H +#define AUTOGENSTEP_H + +#include <projectexplorer/abstractprocessstep.h> + +QT_BEGIN_NAMESPACE +class QLineEdit; +QT_END_NAMESPACE + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsProject; +class AutotoolsBuildConfiguration; +class AutogenStep; +class AutogenStepConfigWidget; + +///////////////////////////// +// AutogenStepFactory class +///////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::IBuildStepFactory interface. + * + * This factory is used to create instances of AutogenStep. + */ +class AutogenStepFactory : public ProjectExplorer::IBuildStepFactory +{ + Q_OBJECT + +public: + AutogenStepFactory(QObject *parent = 0); + ~AutogenStepFactory(); + + QStringList availableCreationIds(ProjectExplorer::BuildStepList *bc) const; + QString displayNameForId(const QString &id) const; + bool canCreate(ProjectExplorer::BuildStepList *parent, const QString &id) const; + ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const QString &id); + bool canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source) const; + ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source); + bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const; + ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map); +}; + +/////////////////////// +// AutogenStep class +/////////////////////// +/** + * @brief Implementation of the ProjectExplorer::AbstractProcessStep interface. + * + * A autogen step can be configured by selecting the "Projects" button of Qt Creator + * (in the left hand side menu) and under "Build Settings". + * + * It is possible for the user to specify custom arguments. The corresponding + * configuration widget is created by AutogenStep::createConfigWidget and is + * represented by an instance of the class AutogenStepConfigWidget. + */ + +class AutogenStep : public ProjectExplorer::AbstractProcessStep +{ + Q_OBJECT + friend class AutogenStepFactory; + friend class AutogenStepConfigWidget; + +public: + AutogenStep(ProjectExplorer::BuildStepList *bsl); + ~AutogenStep(); + + AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; + bool init(); + void run(QFutureInterface<bool> &interface); + ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + bool immutable() const; + QString additionalArguments() const; + QVariantMap toMap() const; + +public slots: + void setAdditionalArguments(const QString &list); + +signals: + void additionalArgumentsChanged(const QString &); + +protected: + AutogenStep(ProjectExplorer::BuildStepList *bsl, AutogenStep *bs); + AutogenStep(ProjectExplorer::BuildStepList *bsl, const QString &id); + + bool fromMap(const QVariantMap &map); + +private: + void ctor(); + + QString m_additionalArguments; + bool m_runAutogen; +}; + +////////////////////////////////// +// AutogenStepConfigWidget class +////////////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::BuildStepConfigWidget interface. + * + * Allows to configure a autogen step in the GUI. + */ +class AutogenStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT + +public: + AutogenStepConfigWidget(AutogenStep *autogenStep); + ~AutogenStepConfigWidget(); + + QString displayName() const; + QString summaryText() const; + + +private slots: + void updateDetails(); + +private: + AutogenStep *m_autogenStep; + QString m_summaryText; + QLineEdit *m_additionalArguments; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOGENSTEP_H + diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp new file mode 100644 index 0000000000..2769ec50e5 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp @@ -0,0 +1,299 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autoreconfstep.h" +#include "autotoolsproject.h" +#include "autotoolstarget.h" +#include "autotoolsbuildconfiguration.h" +#include "autotoolsprojectconstants.h" + +#include <projectexplorer/buildsteplist.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/gnumakeparser.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <utils/qtcprocess.h> + +#include <QtCore/QVariantMap> +#include <QtGui/QLineEdit> +#include <QtGui/QFormLayout> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; +using namespace ProjectExplorer; + +namespace { +const char AUTORECONF_STEP_ID[] = "AutotoolsProjectManager.AutoreconfStep"; +const char AUTORECONF_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.AutoreconfStep.AdditionalArguments"; +} + +//////////////////////////////// +// AutoreconfStepFactory class +//////////////////////////////// +AutoreconfStepFactory::AutoreconfStepFactory(QObject *parent) : + ProjectExplorer::IBuildStepFactory(parent) +{ +} + +AutoreconfStepFactory::~AutoreconfStepFactory() +{ +} + +QStringList AutoreconfStepFactory::availableCreationIds(BuildStepList *parent) const +{ + if (parent->target()->project()->id() == QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return QStringList() << QLatin1String(AUTORECONF_STEP_ID); + return QStringList(); +} + +QString AutoreconfStepFactory::displayNameForId(const QString &id) const +{ + if (id == QLatin1String(AUTORECONF_STEP_ID)) + return tr("Autoreconf", "Display name for AutotoolsProjectManager::AutoreconfStep id."); + return QString(); +} + +bool AutoreconfStepFactory::canCreate(BuildStepList *parent, const QString &id) const +{ + if (parent->target()->project()->id() != QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return false; + + if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD) + return false; + + return QLatin1String(AUTORECONF_STEP_ID) == id; +} + +BuildStep *AutoreconfStepFactory::create(BuildStepList *parent, const QString &id) +{ + if (!canCreate(parent, id)) + return 0; + return new AutoreconfStep(parent); +} + +bool AutoreconfStepFactory::canClone(BuildStepList *parent, BuildStep *source) const +{ + return canCreate(parent, source->id()); +} + +BuildStep *AutoreconfStepFactory::clone(BuildStepList *parent, BuildStep *source) +{ + if (!canClone(parent, source)) + return 0; + return new AutoreconfStep(parent, static_cast<AutoreconfStep *>(source)); +} + +bool AutoreconfStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const +{ + QString id(ProjectExplorer::idFromMap(map)); + return canCreate(parent, id); +} + +BuildStep *AutoreconfStepFactory::restore(BuildStepList *parent, const QVariantMap &map) +{ + if (!canRestore(parent, map)) + return 0; + AutoreconfStep *bs = new AutoreconfStep(parent); + if (bs->fromMap(map)) + return bs; + delete bs; + return 0; +} + +///////////////////////// +// AutoreconfStep class +///////////////////////// +AutoreconfStep::AutoreconfStep(ProjectExplorer::BuildStepList *bsl) : + AbstractProcessStep(bsl, QLatin1String(AUTORECONF_STEP_ID)), + m_runAutoreconf(false) +{ + ctor(); +} + +AutoreconfStep::AutoreconfStep(ProjectExplorer::BuildStepList *bsl, const QString &id) : + AbstractProcessStep(bsl, id) +{ + ctor(); +} + +AutoreconfStep::AutoreconfStep(ProjectExplorer::BuildStepList *bsl, AutoreconfStep *bs) : + AbstractProcessStep(bsl, bs), + m_additionalArguments(bs->additionalArguments()) +{ + ctor(); +} + +void AutoreconfStep::ctor() +{ + setDefaultDisplayName(tr("Autoreconf")); +} + +AutoreconfStep::~AutoreconfStep() +{ +} + +AutotoolsBuildConfiguration *AutoreconfStep::autotoolsBuildConfiguration() const +{ + return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); +} + +bool AutoreconfStep::init() +{ + AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + + setEnabled(true); + + ProcessParameters *pp = processParameters(); + pp->setMacroExpander(bc->macroExpander()); + pp->setEnvironment(bc->environment()); + pp->setWorkingDirectory(bc->buildDirectory()); + pp->setCommand("autoreconf"); + pp->setArguments(additionalArguments()); + + return AbstractProcessStep::init(); +} + +void AutoreconfStep::run(QFutureInterface<bool> &interface) +{ + AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + + // Check wether we need to run autoreconf + const QFileInfo configureInfo(bc->buildDirectory() + QLatin1String("/configure")); + + if (!configureInfo.exists()) + m_runAutoreconf = true; + + if (!m_runAutoreconf) { + emit addOutput(tr("Configuration unchanged, skipping autoreconf step."), BuildStep::MessageOutput); + interface.reportResult(true); + return; + } + + m_runAutoreconf = false; + AbstractProcessStep::run(interface); +} + +ProjectExplorer::BuildStepConfigWidget* AutoreconfStep::createConfigWidget() +{ + return new AutoreconfStepConfigWidget(this); +} + +bool AutoreconfStep::immutable() const +{ + return false; +} + +void AutoreconfStep::setAdditionalArguments(const QString &list) +{ + if (list == m_additionalArguments) + return; + + m_additionalArguments = list; + m_runAutoreconf = true; + + emit additionalArgumentsChanged(list); +} + +QString AutoreconfStep::additionalArguments() const +{ + return m_additionalArguments; +} + +QVariantMap AutoreconfStep::toMap() const +{ + QVariantMap map(AbstractProcessStep::toMap()); + + map.insert(QLatin1String(AUTORECONF_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments); + return map; +} + +bool AutoreconfStep::fromMap(const QVariantMap &map) +{ + m_additionalArguments = map.value(QLatin1String(AUTORECONF_ADDITIONAL_ARGUMENTS_KEY)).toString(); + + return BuildStep::fromMap(map); +} + +////////////////////////////////////// +// AutoreconfStepConfigWidget class +////////////////////////////////////// +AutoreconfStepConfigWidget::AutoreconfStepConfigWidget(AutoreconfStep *autoreconfStep) : + m_autoreconfStep(autoreconfStep), + m_summaryText(), + m_additionalArguments(0) +{ + QFormLayout *fl = new QFormLayout(this); + fl->setMargin(0); + fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); + setLayout(fl); + + m_additionalArguments = new QLineEdit(this); + fl->addRow(tr("Arguments:"), m_additionalArguments); + m_additionalArguments->setText(m_autoreconfStep->additionalArguments()); + + updateDetails(); + + connect(m_additionalArguments, SIGNAL(textChanged(QString)), + autoreconfStep, SLOT(setAdditionalArguments(QString))); + connect(autoreconfStep, SIGNAL(additionalArgumentsChanged(QString)), + this, SLOT(updateDetails())); +} + +AutoreconfStepConfigWidget::~AutoreconfStepConfigWidget() +{ +} + +QString AutoreconfStepConfigWidget::displayName() const +{ + return tr("Autoreconf", "AutotoolsProjectManager::AutoreconfStepConfigWidget display name."); +} + +QString AutoreconfStepConfigWidget::summaryText() const +{ + return m_summaryText; +} + +void AutoreconfStepConfigWidget::updateDetails() +{ + AutotoolsBuildConfiguration *bc = m_autoreconfStep->autotoolsBuildConfiguration(); + + ProcessParameters param; + param.setMacroExpander(bc->macroExpander()); + param.setEnvironment(bc->environment()); + param.setWorkingDirectory(bc->buildDirectory()); + param.setCommand("autoreconf"); + param.setArguments(m_autoreconfStep->additionalArguments()); + m_summaryText = param.summary(displayName()); + emit updateSummary(); +} diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.h b/src/plugins/autotoolsprojectmanager/autoreconfstep.h new file mode 100644 index 0000000000..bafe0df6a0 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.h @@ -0,0 +1,163 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTORECONFSTEP_H +#define AUTORECONFSTEP_H + +#include <projectexplorer/abstractprocessstep.h> +#include <QtGui/QLineEdit> + +QT_BEGIN_NAMESPACE +class QLineEdit; +QT_END_NAMESPACE + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsProject; +class AutotoolsBuildConfiguration; +class AutoreconfStep; + +//////////////////////////////// +// AutoreconfStepFactory class +//////////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::IBuildStepFactory interface. + * + * The factory is used to create instances of AutoreconfStep. + */ +class AutoreconfStepFactory : public ProjectExplorer::IBuildStepFactory +{ + Q_OBJECT + +public: + AutoreconfStepFactory(QObject *parent = 0); + ~AutoreconfStepFactory(); + + QStringList availableCreationIds(ProjectExplorer::BuildStepList *bc) const; + QString displayNameForId(const QString &id) const; + + bool canCreate(ProjectExplorer::BuildStepList *parent, const QString &id) const; + ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const QString &id); + bool canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source) const; + ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source); + bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const; + ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map); +}; + +///////////////////////// +// AutoreconfStep class +///////////////////////// +/** + * @brief Implementation of the ProjectExplorer::AbstractProcessStep interface. + * + * A autoreconf step can be configured by selecting the "Projects" button + * of Qt Creator (in the left hand side menu) and under "Build Settings". + * + * It is possible for the user to specify custom arguments. The corresponding + * configuration widget is created by AutoreconfStep::createConfigWidget and is + * represented by an instance of the class AutoreconfStepConfigWidget. + */ + +class AutoreconfStep : public ProjectExplorer::AbstractProcessStep +{ + Q_OBJECT + friend class AutoreconfStepFactory; + friend class AutoreconfStepConfigWidget; + +public: + + AutoreconfStep(ProjectExplorer::BuildStepList *bsl); + ~AutoreconfStep(); + + AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; + bool init(); + void run(QFutureInterface<bool> &interface); + ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + bool immutable() const; + QString additionalArguments() const; + QVariantMap toMap() const; + +public slots: + void setAdditionalArguments(const QString &list); + +signals: + void additionalArgumentsChanged(const QString &); + +protected: + AutoreconfStep(ProjectExplorer::BuildStepList *bsl, AutoreconfStep *bs); + AutoreconfStep(ProjectExplorer::BuildStepList *bsl, const QString &id); + + bool fromMap(const QVariantMap &map); + +private: + void ctor(); + + QString m_additionalArguments; + bool m_runAutoreconf; +}; + +////////////////////////////////////// +// AutoreconfStepConfigWidget class +////////////////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::BuildStepConfigWidget interface. + * + * Allows to configure a autoreconf step in the GUI.. + */ +class AutoreconfStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT + +public: + AutoreconfStepConfigWidget(AutoreconfStep *autoreconfStep); + ~AutoreconfStepConfigWidget(); + + QString displayName() const; + QString summaryText() const; + +private slots: + void updateDetails(); + +private: + AutoreconfStep *m_autoreconfStep; + QString m_summaryText; + QLineEdit *m_additionalArguments; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTORECONFSTEP_H + diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp new file mode 100644 index 0000000000..80f7ba3ab0 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp @@ -0,0 +1,260 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsbuildconfiguration.h" +#include "makestep.h" +#include "autotoolsproject.h" +#include "autotoolstarget.h" +#include "autotoolsprojectconstants.h" +#include "makestep.h" +#include "autogenstep.h" +#include "autoreconfstep.h" +#include "configurestep.h" + +#include <projectexplorer/buildsteplist.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/customexecutablerunconfiguration.h> +#include <utils/qtcassert.h> + +#include <QtGui/QInputDialog> + +using namespace AutotoolsProjectManager; +using namespace Internal; + +////////////////////////////////////// +// AutotoolsBuildConfiguration class +////////////////////////////////////// +AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(AutotoolsTarget *parent) + : BuildConfiguration(parent, QLatin1String(Constants::AUTOTOOLS_BC_ID)) +{ + m_buildDirectory = autotoolsTarget()->defaultBuildDirectory(); +} + +AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(AutotoolsTarget *parent, const QString &id) + : BuildConfiguration(parent, id) +{ +} + +AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(AutotoolsTarget *parent, AutotoolsBuildConfiguration *source) + : BuildConfiguration(parent, source), + m_buildDirectory(source->m_buildDirectory) +{ + cloneSteps(source); +} + +AutotoolsBuildConfiguration::~AutotoolsBuildConfiguration() +{ +} + +QVariantMap AutotoolsBuildConfiguration::toMap() const +{ + QVariantMap map(ProjectExplorer::BuildConfiguration::toMap()); + map.insert(QLatin1String(Constants::BUILD_DIRECTORY_KEY), m_buildDirectory); + return map; +} + +bool AutotoolsBuildConfiguration::fromMap(const QVariantMap &map) +{ + if (!BuildConfiguration::fromMap(map)) + return false; + + m_buildDirectory = map.value(QLatin1String(Constants::BUILD_DIRECTORY_KEY), autotoolsTarget()->defaultBuildDirectory()).toString(); + return true; +} + +QString AutotoolsBuildConfiguration::buildDirectory() const +{ + return m_buildDirectory; +} + +void AutotoolsBuildConfiguration::setBuildDirectory(const QString &buildDirectory) +{ + if (m_buildDirectory == buildDirectory) + return; + m_buildDirectory = buildDirectory; + emit buildDirectoryChanged(); +} + +AutotoolsTarget *AutotoolsBuildConfiguration::autotoolsTarget() const +{ + return static_cast<AutotoolsTarget *>(target()); +} + +ProjectExplorer::IOutputParser *AutotoolsBuildConfiguration::createOutputParser() const +{ + ProjectExplorer::ToolChain *tc = autotoolsTarget()->autotoolsProject()->toolChain(); + if (tc) + return tc->outputParser(); + return 0; +} + +////////////////////////////////////// +// AutotoolsBuildConfiguration class +////////////////////////////////////// +AutotoolsBuildConfigurationFactory::AutotoolsBuildConfigurationFactory(QObject *parent) : + ProjectExplorer::IBuildConfigurationFactory(parent) +{ +} + +AutotoolsBuildConfigurationFactory::~AutotoolsBuildConfigurationFactory() +{ +} + +QStringList AutotoolsBuildConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const +{ + if (!qobject_cast<AutotoolsTarget *>(parent)) + return QStringList(); + return QStringList() << QLatin1String(Constants::AUTOTOOLS_BC_ID); +} + +QString AutotoolsBuildConfigurationFactory::displayNameForId(const QString &id) const +{ + if (id == QLatin1String(Constants::AUTOTOOLS_BC_ID)) + return tr("Build"); + return QString(); +} + +bool AutotoolsBuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const +{ + if (!qobject_cast<AutotoolsTarget *>(parent)) + return false; + if (id == QLatin1String(Constants::AUTOTOOLS_BC_ID)) + return true; + return false; +} + +AutotoolsBuildConfiguration *AutotoolsBuildConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id) +{ + if (!canCreate(parent, id)) + return 0; + + AutotoolsTarget *t(static_cast<AutotoolsTarget *>(parent)); + AutotoolsBuildConfiguration *bc =createDefaultConfiguration(t); + + bool ok; + QString buildConfigurationName = QInputDialog::getText(0, + tr("New Configuration"), + tr("New configuration name:"), + QLineEdit::Normal, + QString(), + &ok); + + if (!ok || buildConfigurationName.isEmpty()) + return 0; + bc->setDisplayName(buildConfigurationName); + + t->addBuildConfiguration(bc); + t->addDeployConfiguration(t->createDeployConfiguration(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID)); + // User needs to choose where the executable file is. + // TODO: Parse the file in *Anjuta style* to be able to add custom RunConfigurations. + t->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(t)); + + return bc; +} + +AutotoolsBuildConfiguration *AutotoolsBuildConfigurationFactory::createDefaultConfiguration(AutotoolsTarget *target) const +{ + AutotoolsBuildConfiguration *bc = new AutotoolsBuildConfiguration(target); + ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); + + // ### Build Steps Build ### + // autogen.sh or autoreconf + QFile autogenFile(target->autotoolsProject()->sourceDirectory() + QLatin1String("/autogen.sh")); + if (autogenFile.exists()) { + AutogenStep *autogenStep = new AutogenStep(buildSteps); + buildSteps->insertStep(0, autogenStep); + } else { + AutoreconfStep *autoreconfStep = new AutoreconfStep(buildSteps); + autoreconfStep->setAdditionalArguments(QLatin1String("--force --install")); + buildSteps->insertStep(0, autoreconfStep); + } + + // ./configure. + ConfigureStep *configureStep = new ConfigureStep(buildSteps); + buildSteps->insertStep(1, configureStep); + + // make + MakeStep *makeStep = new MakeStep(buildSteps); + buildSteps->insertStep(2, makeStep); + makeStep->setBuildTarget(QLatin1String("all"), /*on =*/ true); + + // ### Build Steps Clean ### + ProjectExplorer::BuildStepList *cleanSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN); + MakeStep *cleanMakeStep = new MakeStep(cleanSteps); + cleanMakeStep->setAdditionalArguments(QLatin1String("clean")); + cleanMakeStep->setClean(true); + cleanSteps->insertStep(0, cleanMakeStep); + + return bc; +} + +bool AutotoolsBuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const +{ + return canCreate(parent, source->id()); +} + +AutotoolsBuildConfiguration *AutotoolsBuildConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) +{ + if (!canClone(parent, source)) + return 0; + + AutotoolsBuildConfiguration *origin = static_cast<AutotoolsBuildConfiguration *>(source); + AutotoolsTarget *target(static_cast<AutotoolsTarget *>(parent)); + return new AutotoolsBuildConfiguration(target, origin); +} + +bool AutotoolsBuildConfigurationFactory::canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const +{ + QString id(ProjectExplorer::idFromMap(map)); + return canCreate(parent, id); +} + +AutotoolsBuildConfiguration *AutotoolsBuildConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map) +{ + if (!canRestore(parent, map)) + return 0; + AutotoolsTarget *target(static_cast<AutotoolsTarget *>(parent)); + AutotoolsBuildConfiguration *bc = new AutotoolsBuildConfiguration(target); + if (bc->fromMap(map)) + return bc; + delete bc; + return 0; +} + +ProjectExplorer::BuildConfiguration::BuildType AutotoolsBuildConfiguration::buildType() const +{ + // TODO: Should I return something different from Unknown? + return Unknown; +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h new file mode 100644 index 0000000000..9889a1c677 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h @@ -0,0 +1,94 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSBUILDCONFIGURATION_H +#define AUTOTOOLSBUILDCONFIGURATION_H + +#include <projectexplorer/buildconfiguration.h> + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsTarget; +class AutotoolsBuildConfigurationFactory; + +class AutotoolsBuildConfiguration : public ProjectExplorer::BuildConfiguration +{ + Q_OBJECT + friend class AutotoolsBuildConfigurationFactory; + +public: + explicit AutotoolsBuildConfiguration(AutotoolsTarget *parent); + ~AutotoolsBuildConfiguration(); + + AutotoolsTarget *autotoolsTarget() const; + QString buildDirectory() const; + void setBuildDirectory(const QString &buildDirectory); + QVariantMap toMap() const; + ProjectExplorer::IOutputParser *createOutputParser() const; + BuildType buildType() const; + +protected: + AutotoolsBuildConfiguration(AutotoolsTarget *parent, const QString &id); + AutotoolsBuildConfiguration(AutotoolsTarget *parent, AutotoolsBuildConfiguration *source); + + bool fromMap(const QVariantMap &map); + +private: + QString m_buildDirectory; +}; + +class AutotoolsBuildConfigurationFactory : public ProjectExplorer::IBuildConfigurationFactory +{ + Q_OBJECT + +public: + explicit AutotoolsBuildConfigurationFactory(QObject *parent = 0); + ~AutotoolsBuildConfigurationFactory(); + + QStringList availableCreationIds(ProjectExplorer::Target *parent) const; + QString displayNameForId(const QString &id) const; + + bool canCreate(ProjectExplorer::Target *parent, const QString &id) const; + AutotoolsBuildConfiguration *create(ProjectExplorer::Target *parent, const QString &id); + AutotoolsBuildConfiguration *createDefaultConfiguration(AutotoolsTarget *target) const; + bool canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const; + AutotoolsBuildConfiguration *clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source); + bool canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const; + AutotoolsBuildConfiguration *restore(ProjectExplorer::Target *parent, const QVariantMap &map); +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager +#endif // AUTOTOOLSBUILDCONFIGURATION_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp new file mode 100644 index 0000000000..7d05b051e6 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp @@ -0,0 +1,139 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsbuildsettingswidget.h" +#include "autotoolsproject.h" +#include "autotoolsbuildconfiguration.h" + +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/toolchainmanager.h> + +#include <QtGui/QGridLayout> +#include <QtGui/QLabel> +#include <QtGui/QLineEdit> +#include <QtGui/QFormLayout> +#include <QtGui/QComboBox> +#include <QtCore/QPointer> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; +using namespace ProjectExplorer; + +AutotoolsBuildSettingsWidget::AutotoolsBuildSettingsWidget(AutotoolsTarget *target) : + m_target(target), + m_pathChooser(0), + m_toolChainChooser(0), + m_buildConfiguration(0) +{ + QFormLayout *fl = new QFormLayout(this); + fl->setContentsMargins(0, 0, 0, 0); + fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); + + m_pathChooser = new Utils::PathChooser(this); + m_pathChooser->setEnabled(true); + m_pathChooser->setExpectedKind(Utils::PathChooser::Directory); + m_pathChooser->setBaseDirectory(m_target->autotoolsProject()->projectDirectory()); + fl->addRow(tr("Build directory:"), m_pathChooser); + connect(m_pathChooser, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged())); + + // tool chain + m_toolChainChooser = new QComboBox; + m_toolChainChooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + updateToolChainList(); + + fl->addRow(tr("Tool chain:"), m_toolChainChooser); + connect(m_toolChainChooser, SIGNAL(activated(int)), this, SLOT(toolChainSelected(int))); + connect(m_target->autotoolsProject(), SIGNAL(toolChainChanged(ProjectExplorer::ToolChain*)), + this, SLOT(toolChainChanged(ProjectExplorer::ToolChain*))); + connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)), + this, SLOT(updateToolChainList())); + connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)), + this, SLOT(updateToolChainList())); +} + +AutotoolsBuildSettingsWidget::~AutotoolsBuildSettingsWidget() +{ +} + +QString AutotoolsBuildSettingsWidget::displayName() const +{ + return QLatin1String("Autotools Manager"); +} + +void AutotoolsBuildSettingsWidget::init(BuildConfiguration *bc) +{ + m_buildConfiguration = static_cast<AutotoolsBuildConfiguration *>(bc); + m_pathChooser->setPath(m_buildConfiguration->buildDirectory()); +} + +void AutotoolsBuildSettingsWidget::buildDirectoryChanged() +{ + m_buildConfiguration->setBuildDirectory(m_pathChooser->rawPath()); +} + +void AutotoolsBuildSettingsWidget::toolChainSelected(int index) +{ + using namespace ProjectExplorer; + + ToolChain *tc = static_cast<ToolChain *>(m_toolChainChooser->itemData(index).value<void *>()); + m_target->autotoolsProject()->setToolChain(tc); +} + +void AutotoolsBuildSettingsWidget::toolChainChanged(ProjectExplorer::ToolChain *tc) +{ + for (int i = 0; i < m_toolChainChooser->count(); ++i) { + ToolChain * currentTc = static_cast<ToolChain *>(m_toolChainChooser->itemData(i).value<void *>()); + if (currentTc != tc) + continue; + m_toolChainChooser->setCurrentIndex(i); + return; + } +} + +void AutotoolsBuildSettingsWidget::updateToolChainList() +{ + m_toolChainChooser->clear(); + + QList<ToolChain *> tcs = ToolChainManager::instance()->toolChains(); + if (!m_target->autotoolsProject()->toolChain()) { + m_toolChainChooser->addItem(tr("<Invalid tool chain>"), qVariantFromValue(static_cast<void *>(0))); + m_toolChainChooser->setCurrentIndex(0); + } + foreach (ToolChain *tc, tcs) { + m_toolChainChooser->addItem(tc->displayName(), qVariantFromValue(static_cast<void *>(tc))); + if (m_target->autotoolsProject()->toolChain() + && m_target->autotoolsProject()->toolChain()->id() == tc->id()) + m_toolChainChooser->setCurrentIndex(m_toolChainChooser->count() - 1); + } +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h new file mode 100644 index 0000000000..6fc3be08ad --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h @@ -0,0 +1,88 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSBUILDSETTINGSWIDGET_H +#define AUTOTOOLSBUILDSETTINGSWIDGET_H + +#include "autotoolstarget.h" +#include "autotoolsbuildconfiguration.h" + +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/project.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/buildstep.h> +#include <utils/pathchooser.h> + +QT_BEGIN_NAMESPACE +class QComboBox; +QT_END_NAMESPACE + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsProject; + +/** + * @brief Implementation of ProjectExplorer::BuildConfigWidget interface. + * + * Provides an editor to configure the build directory and build steps. + */ +class AutotoolsBuildSettingsWidget : public ProjectExplorer::BuildConfigWidget +{ + Q_OBJECT + +public: + AutotoolsBuildSettingsWidget(AutotoolsTarget* target); + ~AutotoolsBuildSettingsWidget(); + + QString displayName() const; + void init(ProjectExplorer::BuildConfiguration* bc); + +private slots: + void buildDirectoryChanged(); + void toolChainSelected(int index); + void toolChainChanged(ProjectExplorer::ToolChain *); + void updateToolChainList(); + +private: + AutotoolsTarget *m_target; + Utils::PathChooser *m_pathChooser; + QComboBox *m_toolChainChooser; + AutotoolsBuildConfiguration *m_buildConfiguration; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSBUILDSETTINGSWIDGET_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsmanager.cpp b/src/plugins/autotoolsprojectmanager/autotoolsmanager.cpp new file mode 100644 index 0000000000..474fb6997e --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsmanager.cpp @@ -0,0 +1,83 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsmanager.h" +#include "autotoolsproject.h" +#include "autotoolsprojectconstants.h" + +#include <coreplugin/icore.h> +#include <coreplugin/ifile.h> +#include <coreplugin/messagemanager.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/session.h> + +using namespace AutotoolsProjectManager::Internal; + +AutotoolsManager::AutotoolsManager() +{ +} + +AutotoolsManager::~AutotoolsManager() +{ +} + +ProjectExplorer::Project *AutotoolsManager::openProject(const QString& fileName, QString *errorString) +{ + QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); + + if (canonicalFilePath.isEmpty()) { + if (errorString) + *errorString = tr("Failed opening project '%1': Project file does not exist") + .arg(QDir::toNativeSeparators(fileName)); + return 0; + } + + // Check whether the project is already open or not. + ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance(); + foreach (ProjectExplorer::Project *pi, projectExplorer->session()->projects()) { + if (canonicalFilePath == pi->file()->fileName()) { + *errorString = tr("Failed opening project '%1': Project already open") + .arg(QDir::toNativeSeparators(canonicalFilePath)); + return 0; + } + } + + return new AutotoolsProject(this, canonicalFilePath); +} + +QString AutotoolsManager::mimeType() const +{ + return QLatin1String(Constants::MAKEFILE_MIMETYPE); +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsmanager.h b/src/plugins/autotoolsprojectmanager/autotoolsmanager.h new file mode 100644 index 0000000000..2f9aaa6d1e --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsmanager.h @@ -0,0 +1,65 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSMANAGER_H +#define AUTOTOOLSMANAGER_H + +#include <projectexplorer/iprojectmanager.h> + +namespace AutotoolsProjectManager { +namespace Internal { + +/** + * @brief Implementation of ProjectExplorer::IProjectManager interface. + * + * An autotools project is identified by the MIME type text/x-makefile. + * The project is represented by an instance of ProjectExplorer::Project, + * which gets created by AutotoolsManager::openProject(). + */ +class AutotoolsManager : public ProjectExplorer::IProjectManager +{ + Q_OBJECT + +public: + AutotoolsManager(); + ~AutotoolsManager(); + + ProjectExplorer::Project *openProject(const QString& fileName, QString *errorString); + QString mimeType() const; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSMANAGER_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp new file mode 100644 index 0000000000..d53a42acc9 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp @@ -0,0 +1,121 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsopenprojectwizard.h" + +#include <QtGui/QVBoxLayout> +#include <QtGui/QFormLayout> +#include <QtGui/QLabel> +#include <QtCore/QDir> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; + +////////////////////////////////////// +// AutotoolsOpenProjectWizard class +////////////////////////////////////// +AutotoolsOpenProjectWizard::AutotoolsOpenProjectWizard(AutotoolsManager *manager, + const QString &sourceDirectory, + QWidget *parent) + : Utils::Wizard(parent), + m_manager(manager), + m_sourceDirectory(sourceDirectory) +{ + QDir dir(m_sourceDirectory); + m_buildDirectory = dir.absolutePath(); + + setPage(BuildPathPageId, new BuildPathPage(this)); + + setStartId(BuildPathPageId); + init(); +} + +AutotoolsOpenProjectWizard::~AutotoolsOpenProjectWizard() +{ +} + +void AutotoolsOpenProjectWizard::init() +{ + setOption(QWizard::NoBackButtonOnStartPage); + setWindowTitle(tr("Autotools Wizard")); +} + +AutotoolsManager *AutotoolsOpenProjectWizard::autotoolsManager() const +{ + return m_manager; +} + +QString AutotoolsOpenProjectWizard::buildDirectory() const +{ + return m_buildDirectory; +} + +QString AutotoolsOpenProjectWizard::sourceDirectory() const +{ + return m_sourceDirectory; +} + +void AutotoolsOpenProjectWizard::setBuildDirectory(const QString &directory) +{ + m_buildDirectory = directory; +} + +///////////////////////// +// BuildPathPage class +///////////////////////// +BuildPathPage::BuildPathPage(AutotoolsOpenProjectWizard *wizard) + : QWizardPage(wizard), m_wizard(wizard) +{ + QFormLayout *fl = new QFormLayout; + this->setLayout(fl); + + QLabel *label = new QLabel(this); + label->setWordWrap(true); + label->setText(tr("Please enter the directory in which you want to build your project. " + "Qt Creator recommends to not use the source directory for building. " + "This ensures that the source directory remains clean and enables multiple builds " + "with different settings.")); + fl->addWidget(label); + m_pc = new Utils::PathChooser(this); + m_pc->setBaseDirectory(m_wizard->sourceDirectory()); + m_pc->setPath(m_wizard->buildDirectory()); + connect(m_pc, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged())); + fl->addRow(tr("Build directory:"), m_pc); + setTitle(tr("Build Location")); +} + +void BuildPathPage::buildDirectoryChanged() +{ + m_wizard->setBuildDirectory(m_pc->path()); +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.h b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.h new file mode 100644 index 0000000000..5a1056a723 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.h @@ -0,0 +1,87 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSOPENPROJECTWIZARD_H +#define AUTOTOOLSOPENPROJECTWIZARD_H + +#include <utils/wizard.h> +#include <utils/pathchooser.h> + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsManager; + +class AutotoolsOpenProjectWizard : public Utils::Wizard +{ + Q_OBJECT +public: + enum PageId + { + BuildPathPageId + }; + + AutotoolsOpenProjectWizard(AutotoolsManager *manager, + const QString &sourceDirectory, + QWidget *parent = 0); + + ~AutotoolsOpenProjectWizard(); + + QString buildDirectory() const; + QString sourceDirectory() const; + void setBuildDirectory(const QString &directory); + AutotoolsManager *autotoolsManager() const; + +private: + void init(); + AutotoolsManager *m_manager; + QString m_buildDirectory; + QString m_sourceDirectory; +}; + +class BuildPathPage : public QWizardPage +{ + Q_OBJECT +public: + explicit BuildPathPage(AutotoolsOpenProjectWizard *wizard); +private slots: + void buildDirectoryChanged(); +private: + AutotoolsOpenProjectWizard *m_wizard; + Utils::PathChooser *m_pc; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager +#endif //AUTOTOOLSOPENPROJECTWIZARD_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp new file mode 100644 index 0000000000..7a1a514d8e --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -0,0 +1,542 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsproject.h" +#include "autotoolsprojectconstants.h" +#include "autotoolsmanager.h" +#include "autotoolsprojectnode.h" +#include "autotoolsprojectfile.h" +#include "autotoolsopenprojectwizard.h" +#include "makestep.h" +#include "makefileparserthread.h" + +#include <projectexplorer/abi.h> +#include <projectexplorer/buildenvironmentwidget.h> +#include <projectexplorer/toolchainmanager.h> +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/buildsteplist.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <extensionsystem/pluginmanager.h> +#include <cplusplus/ModelManagerInterface.h> +#include <coreplugin/icore.h> +#include <utils/qtcassert.h> + +#include <QtCore/QFileInfo> +#include <QtCore/QTimer> +#include <QtCore/QPointer> +#include <QtGui/QApplication> +#include <QtGui/QCursor> +#include <QtGui/QLabel> +#include <QtGui/QPushButton> +#include <QtGui/QVBoxLayout> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; +using namespace ProjectExplorer; + +namespace { +const char TOOLCHAIN_KEY[] = "AutotoolsProjectManager.AutotoolsProject.Toolchain"; +} + +AutotoolsProject::AutotoolsProject(AutotoolsManager *manager, const QString &fileName) : + m_manager(manager), + m_fileName(fileName), + m_files(), + m_file(new AutotoolsProjectFile(this, m_fileName)), + m_rootNode(new AutotoolsProjectNode(this, m_file)), + m_fileWatcher(new Utils::FileSystemWatcher(this)), + m_watchedFiles(), + m_makefileParserThread(0), + m_toolChain(0) +{ + setProjectContext(Core::Context(Constants::PROJECT_CONTEXT)); + setProjectLanguage(Core::Context(ProjectExplorer::Constants::LANG_CXX)); + + const QFileInfo fileInfo(m_fileName); + m_projectName = fileInfo.absoluteDir().dirName(); + m_rootNode->setDisplayName(fileInfo.absoluteDir().dirName()); +} + +AutotoolsProject::~AutotoolsProject() +{ + // Although ProjectExplorer::ProjectNode is a QObject, the ctor + // does not allow to specify the parent. Manually setting the + // parent would be possible, but we use the same approach as in the + // other project managers and delete the node manually (TBD). + // + delete m_rootNode; + m_rootNode = 0; + + if (m_makefileParserThread != 0) { + m_makefileParserThread->wait(); + delete m_makefileParserThread; + m_makefileParserThread = 0; + } +} + +void AutotoolsProject::setToolChain(ToolChain *tc) +{ + if (m_toolChain == tc) + return; + + m_toolChain = tc; + + foreach (Target *t, targets()) { + foreach (BuildConfiguration *bc, t->buildConfigurations()) + bc->setToolChain(tc); + } + + emit toolChainChanged(m_toolChain); +} + +ToolChain *AutotoolsProject::toolChain() const +{ + return m_toolChain; +} + +QString AutotoolsProject::displayName() const +{ + return m_projectName; +} + +QString AutotoolsProject::id() const +{ + return QLatin1String(Constants::AUTOTOOLS_PROJECT_ID); +} + +Core::IFile* AutotoolsProject::file() const +{ + return m_file; +} + +ProjectExplorer::IProjectManager* AutotoolsProject::projectManager() const +{ + return m_manager; +} + +AutotoolsTarget *AutotoolsProject::activeTarget() const +{ + return static_cast<AutotoolsTarget *>(Project::activeTarget()); +} + +QList<ProjectExplorer::Project*> AutotoolsProject::dependsOn() +{ + return QList<Project *>(); +} + +QString AutotoolsProject::defaultBuildDirectory() const +{ + return sourceDirectory(); +} + +QList<ProjectExplorer::BuildConfigWidget*> AutotoolsProject::subConfigWidgets() +{ + QList<ProjectExplorer::BuildConfigWidget*> list; + list << new BuildEnvironmentWidget; + return list; +} + +ProjectExplorer::ProjectNode *AutotoolsProject::rootProjectNode() const +{ + return m_rootNode; +} + +QStringList AutotoolsProject::files(FilesMode fileMode) const +{ + Q_UNUSED(fileMode); + return m_files; +} + +QString AutotoolsProject::sourceDirectory() const +{ + return QFileInfo(m_fileName).absolutePath(); +} + +QVariantMap AutotoolsProject::toMap() const +{ + QVariantMap map(Project::toMap()); + map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChain ? m_toolChain->id() : QString()); + return map; +} + +// This function, is called at the very beginning, to +// restore the settings if there are some stored. +bool AutotoolsProject::fromMap(const QVariantMap &map) +{ + if (!Project::fromMap(map)) + return false; + + // Check if this project was already loaded by checking + // if there already exists a .user file. + bool hasUserFile = activeTarget(); + if (!hasUserFile) { + AutotoolsTargetFactory *factory = + ExtensionSystem::PluginManager::instance()->getObject<AutotoolsTargetFactory>(); + AutotoolsTarget *t = factory->create(this, QLatin1String(Constants::DEFAULT_AUTOTOOLS_TARGET_ID)); + + QTC_ASSERT(t, return false); + QTC_ASSERT(t->activeBuildConfiguration(), return false); + + // Ask the user for where he/she wants to build it. + QFileInfo fileInfo(m_fileName); + const QString defaultBuildDir = fileInfo.absolutePath(); + + QPointer<AutotoolsOpenProjectWizard> wizard = new AutotoolsOpenProjectWizard(m_manager, sourceDirectory()); + if (!wizard->exec() == QDialog::Accepted) + return false; + + AutotoolsBuildConfiguration *bc = + static_cast<AutotoolsBuildConfiguration *>(t->buildConfigurations().at(0)); + if (!wizard->buildDirectory().isEmpty()) + bc->setBuildDirectory(wizard->buildDirectory()); + + addTarget(t); + } + + // Toolchain + QString id = map.value(QLatin1String(TOOLCHAIN_KEY)).toString(); + const ToolChainManager *toolChainManager = ToolChainManager::instance(); + + if (!id.isNull()) { + setToolChain(toolChainManager->findToolChain(id)); + } else { + ProjectExplorer::Abi abi = ProjectExplorer::Abi::hostAbi(); + abi = ProjectExplorer::Abi(abi.architecture(), + abi.os(), + ProjectExplorer::Abi::UnknownFlavor, + abi.binaryFormat(), abi.wordWidth() == 32 ? 32 : 0); + QList<ToolChain *> tcs = toolChainManager->findToolChains(abi); + if (tcs.isEmpty()) + tcs = toolChainManager->toolChains(); + if (!tcs.isEmpty()) + setToolChain(tcs.at(0)); + } + + connect(m_fileWatcher, SIGNAL(fileChanged(QString)), + this, SLOT(onFileChanged(QString))); + + // Load the project tree structure. + loadProjectTree(); + + return true; +} + +void AutotoolsProject::loadProjectTree() +{ + if (m_makefileParserThread != 0) { + // The thread is still busy parsing a previus configuration. + // Wait until the thread has been finished and delete it. + // TODO: Discuss whether blocking is acceptable. + disconnect(m_makefileParserThread, SIGNAL(finished()), + this, SLOT(makefileParsingFinished())); + m_makefileParserThread->wait(); + delete m_makefileParserThread; + m_makefileParserThread = 0; + } + + // Parse the makefile asynchronously in a thread + m_makefileParserThread = new MakefileParserThread(m_fileName); + + connect(m_makefileParserThread, SIGNAL(started()), + this, SLOT(makefileParsingStarted())); + + connect(m_makefileParserThread, SIGNAL(finished()), + this, SLOT(makefileParsingFinished())); + m_makefileParserThread->start(); +} + +void AutotoolsProject::makefileParsingStarted() +{ + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); +} + +void AutotoolsProject::makefileParsingFinished() +{ + // The finished() signal is from a previous makefile-parser-thread + // and can be skipped. This can happen, if the thread has emitted the + // finished() signal during the execution of AutotoolsProject::loadProjectTree(). + // In this case the signal is in the message queue already and deleting + // the thread of course does not remove the signal again. + if (sender() != m_makefileParserThread) + return; + + QApplication::restoreOverrideCursor(); + + if (m_makefileParserThread->isCanceled()) { + // The parsing has been cancelled by the user. Don't show any + // project data at all. + m_makefileParserThread->deleteLater(); + m_makefileParserThread = 0; + return; + } + + if (m_makefileParserThread->hasError()) + qWarning("Parsing of makefile contained errors."); + + // Remove file watches for the current project state. + // The file watches will be added again after the parsing. + foreach (const QString& watchedFile, m_watchedFiles) + m_fileWatcher->removeFile(watchedFile); + + m_watchedFiles.clear(); + + // Apply sources to m_files, which are returned at AutotoolsProject::files() + const QFileInfo fileInfo(m_fileName); + const QDir dir = fileInfo.absoluteDir(); + QStringList files = m_makefileParserThread->sources(); + foreach (const QString& file, files) + m_files.append(dir.absoluteFilePath(file)); + + // Watch for changes of Makefile.am files. If a Makefile.am file + // has been changed, the project tree must be reparsed. + const QStringList makefiles = m_makefileParserThread->makefiles(); + foreach (const QString& makefile, makefiles) { + files.append(makefile); + + const QString watchedFile = dir.absoluteFilePath(makefile); + m_fileWatcher->addFile(watchedFile, Utils::FileSystemWatcher::WatchAllChanges); + m_watchedFiles.append(watchedFile); + } + + // Add configure.ac file to project and watch for changes + const QLatin1String configureAc(QLatin1String("configure.ac")); + const QFile configureAcFile(fileInfo.absolutePath() + QChar('/') + configureAc); + if (configureAcFile.exists()) { + files.append(configureAc); + const QString configureAcFilePath = dir.absoluteFilePath(configureAc); + m_fileWatcher->addFile(configureAcFilePath, Utils::FileSystemWatcher::WatchAllChanges); + m_watchedFiles.append(configureAcFilePath); + } + + buildFileNodeTree(dir, files); + updateCppCodeModel(); + + m_makefileParserThread->deleteLater(); + m_makefileParserThread = 0; +} + +void AutotoolsProject::onFileChanged(const QString &file) +{ + Q_UNUSED(file); + loadProjectTree(); +} + +QStringList AutotoolsProject::buildTargets() const +{ + QStringList targets; + targets.append(QLatin1String("all")); + targets.append(QLatin1String("clean")); + return targets; +} + +void AutotoolsProject::buildFileNodeTree(const QDir &directory, + const QStringList &files) +{ + // Get all existing nodes and remember them in a hash table. + // This allows to reuse existing nodes and to remove obsolete + // nodes later. + QHash<QString, ProjectExplorer::Node*> nodeHash; + foreach (ProjectExplorer::Node* node, nodes(m_rootNode)) + nodeHash.insert(node->path(), node); + + // Add the sources to the filenode project tree. Sources + // inside the same directory are grouped into a folder-node. + const QString baseDir = directory.absolutePath(); + + QList<ProjectExplorer::FileNode*> fileNodes; + ProjectExplorer::FolderNode* parentFolder = 0; + ProjectExplorer::FolderNode* oldParentFolder = 0; + + foreach (const QString& file, files) { + if (file.contains(QLatin1String(".moc"))) + continue; + + QString subDir = baseDir + QChar('/') + file; + for (int i = subDir.length() - 1; i >= 0; --i) { + if (subDir.at(i) == QChar('/')) { + subDir = subDir.left(i); + break; + } + } + + // Add folder nodes, that are not already available + oldParentFolder = parentFolder; + parentFolder = 0; + if (nodeHash.contains(subDir)) { + QTC_ASSERT(nodeHash[subDir]->nodeType() == ProjectExplorer::FolderNodeType, return); + parentFolder = static_cast<ProjectExplorer::FolderNode*>(nodeHash[subDir]); + } else { + parentFolder = insertFolderNode(QDir(subDir), nodeHash); + if (parentFolder == 0) { + // No node gets created for the root folder + parentFolder = m_rootNode; + } + } + QTC_ASSERT(parentFolder != 0, return); + if ((oldParentFolder != parentFolder) && !fileNodes.isEmpty()) { + // AutotoolsProjectNode::addFileNodes() is a very expensive operation. It is + // important to collect as much file nodes of the same parent folder as + // possible before invoking it. + m_rootNode->addFileNodes(fileNodes, oldParentFolder); + fileNodes.clear(); + } + + // Add file node + const QString filePath = directory.absoluteFilePath(file); + if (nodeHash.contains(filePath)) { + nodeHash.remove(filePath); + } else { + ProjectExplorer::FileNode* node = + new ProjectExplorer::FileNode(filePath, + ProjectExplorer::ResourceType, + false); + fileNodes.append(node); + } + } + + if (!fileNodes.isEmpty()) + m_rootNode->addFileNodes(fileNodes, parentFolder); + + // Remove unused file nodes and empty folder nodes + QHash<QString, ProjectExplorer::Node*>::const_iterator it = nodeHash.constBegin(); + while (it != nodeHash.constEnd()) { + if ((*it)->nodeType() == ProjectExplorer::FileNodeType) { + ProjectExplorer::FileNode* fileNode = static_cast<ProjectExplorer::FileNode*>(*it); + ProjectExplorer::FolderNode* parent = fileNode->parentFolderNode(); + m_rootNode->removeFileNodes(QList<ProjectExplorer::FileNode*>() << fileNode, parent); + + // Remove all empty parent folders + while (parent->subFolderNodes().isEmpty() && parent->fileNodes().isEmpty()) { + ProjectExplorer::FolderNode* grandParent = parent->parentFolderNode(); + m_rootNode->removeFolderNodes(QList<ProjectExplorer::FolderNode *>() << parent, grandParent); + parent = grandParent; + if (parent == m_rootNode) + break; + } + } + ++it; + } +} + +ProjectExplorer::FolderNode* AutotoolsProject::insertFolderNode(const QDir &nodeDir, + QHash<QString, ProjectExplorer::Node*> &nodes) +{ + const QString nodePath = nodeDir.absolutePath(); + QFileInfo rootInfo(m_rootNode->path()); + const QString rootPath = rootInfo.absolutePath(); + + // Do not create a folder for the root node + if (rootPath == nodePath) + return 0; + + ProjectExplorer::FolderNode* folder = new ProjectExplorer::FolderNode(nodePath); + QDir dir(nodeDir); + folder->setDisplayName(dir.dirName()); + + // Get parent-folder. If it does not exist, create it recursively. + // Take care that the m_rootNode is considered as top folder. + ProjectExplorer::FolderNode* parentFolder = m_rootNode; + if ((rootPath != folder->path()) && dir.cdUp()) { + const QString parentDir = dir.absolutePath(); + if (!nodes.contains(parentDir)) { + ProjectExplorer::FolderNode* insertedFolder = insertFolderNode(parentDir, nodes); + if (insertedFolder != 0) + parentFolder = insertedFolder; + } else { + QTC_ASSERT(nodes[parentDir]->nodeType() == ProjectExplorer::FolderNodeType, return 0); + parentFolder = static_cast<ProjectExplorer::FolderNode*>(nodes[parentDir]); + } + } + + m_rootNode->addFolderNodes(QList<ProjectExplorer::FolderNode*>() << folder, parentFolder); + nodes.insert(nodePath, folder); + + return folder; +} + +QList<ProjectExplorer::Node*> AutotoolsProject::nodes(ProjectExplorer::FolderNode *parent) const +{ + QList<ProjectExplorer::Node*> list; + QTC_ASSERT(parent != 0, return list); + + foreach (ProjectExplorer::FolderNode* folder, parent->subFolderNodes()) { + list.append(nodes(folder)); + list.append(folder); + } + foreach (ProjectExplorer::FileNode* file, parent->fileNodes()) + list.append(file); + + return list; +} + +void AutotoolsProject::updateCppCodeModel() +{ + CPlusPlus::CppModelManagerInterface *modelManager = + CPlusPlus::CppModelManagerInterface::instance(); + + if (!modelManager) + return; + + QStringList allIncludePaths = m_makefileParserThread->includePaths(); + QStringList allFrameworkPaths; + + if (m_toolChain) { + const QList<ProjectExplorer::HeaderPath> allHeaderPaths = m_toolChain->systemHeaderPaths(); + foreach (const ProjectExplorer::HeaderPath &headerPath, allHeaderPaths) { + if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath) { + allFrameworkPaths.append(headerPath.path()); + } else { + allIncludePaths.append(headerPath.path()); + } + } + } + + CPlusPlus::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this); + + const bool update = (pinfo.includePaths != allIncludePaths) + || (pinfo.sourceFiles != m_files) + || (pinfo.defines != m_toolChain->predefinedMacros()) + || (pinfo.frameworkPaths != allFrameworkPaths); + if (update) { + pinfo.includePaths = allIncludePaths; + pinfo.sourceFiles = m_files; + if (m_toolChain) + pinfo.defines = m_toolChain->predefinedMacros(); + pinfo.frameworkPaths = allFrameworkPaths; + modelManager->updateProjectInfo(pinfo); + modelManager->updateSourceFiles(pinfo.sourceFiles); + } + + modelManager->updateProjectInfo(pinfo); +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.h b/src/plugins/autotoolsprojectmanager/autotoolsproject.h new file mode 100644 index 0000000000..e84c56c992 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.h @@ -0,0 +1,183 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSPROJECT_H +#define AUTOTOOLSPROJECT_H + +#include "autotoolstarget.h" + +#include <coreplugin/editormanager/ieditor.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/project.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectnodes.h> +#include <utils/filesystemwatcher.h> + +#include <QtCore/QPointer> +#include <QtCore/QDir> + +namespace ProjectExplorer { +class ToolChain; +} + +namespace AutotoolsProjectManager { +namespace Internal { +class AutotoolsConfigurationFactory; +class AutotoolsProjectFile; +class AutotoolsProjectNode; +class AutotoolsManager; +class MakefileParserThread; +class AutotoolsTarget; + +/** + * @brief Implementation of the ProjectExplorer::Project interface. + * + * Loads the autotools project and embeds it into the QtCreator project tree. + * The class AutotoolsProject is the core of the autotools project plugin. + * It is responsible to parse the Makefile.am files and do trigger project + * updates if a Makefile.am file or a configure.ac file has been changed. + */ +class AutotoolsProject : public ProjectExplorer::Project +{ + Q_OBJECT + +public: + AutotoolsProject(AutotoolsManager *manager, const QString &fileName); + ~AutotoolsProject(); + + QString displayName() const; + QString id() const; + Core::IFile *file() const; + ProjectExplorer::IProjectManager *projectManager() const; + AutotoolsTarget *activeTarget() const; + QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets(); + ProjectExplorer::ProjectNode *rootProjectNode() const; + QStringList files(FilesMode fileMode) const; + QList<ProjectExplorer::Project*> dependsOn(); + QString defaultBuildDirectory() const; + QString sourceDirectory() const; + QStringList buildTargets() const; + ProjectExplorer::ToolChain *toolChain() const; + void setToolChain(ProjectExplorer::ToolChain *tc); + QVariantMap toMap() const; + +signals: + void toolChainChanged(ProjectExplorer::ToolChain *); + +protected: + bool fromMap(const QVariantMap &map); + +private slots: + /** + * Loads the project tree by parsing the makefiles. + */ + void loadProjectTree(); + + /** + * Is invoked when the makefile parsing by m_makefileParserThread has + * been started. Turns the mouse cursor into a busy cursor. + */ + void makefileParsingStarted(); + + /** + * Is invoked when the makefile parsing by m_makefileParserThread has + * been finished. Adds all sources and files into the project tree and + * takes care listen to file changes for Makefile.am and configure.ac + * files. + */ + void makefileParsingFinished(); + + /** + * Is invoked, if a file of the project tree has been changed by the user. + * If a Makefile.am or a configure.ac file has been changed, the project + * configuration must be updated. + */ + void onFileChanged(const QString &file); + +private: + /** + * Creates folder-nodes and file-nodes for the project tree. + */ + void buildFileNodeTree(const QDir &directory, + const QStringList &files); + + /** + * Helper method for buildFileNodeTree(): Inserts a new folder-node for + * the directory \p nodeDir and inserts it into \p nodes. If no parent + * folder exists, it will be created recursively. + */ + ProjectExplorer::FolderNode* insertFolderNode(const QDir &nodeDir, + QHash<QString, ProjectExplorer::Node*> &nodes); + + /** + * @return All nodes (including sub-folder- and file-nodes) for the given parent folder. + */ + QList<ProjectExplorer::Node*> nodes(ProjectExplorer::FolderNode *parent) const; + + /** + * This function is in charge of the code completion. + */ + void updateCppCodeModel(); + +private: + /// Project manager that has been passed in the constructor + AutotoolsManager *m_manager; + + /// File name of the makefile that has been passed in the constructor + QString m_fileName; + QString m_projectName; + + /// Return value for AutotoolsProject::files() + QStringList m_files; + + /// Return value for AutotoolsProject::file() + AutotoolsProjectFile *m_file; + + /// Return value for AutotoolsProject::rootProjectNode() + AutotoolsProjectNode *m_rootNode; + + /// Watches project files for changes. + Utils::FileSystemWatcher *m_fileWatcher; + QStringList m_watchedFiles; + + /// Responsible for parsing the makefiles asynchronously in a thread + MakefileParserThread *m_makefileParserThread; + + ProjectExplorer::ToolChain *m_toolChain; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSPROJECT_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.qrc b/src/plugins/autotoolsprojectmanager/autotoolsproject.qrc new file mode 100644 index 0000000000..514790e9be --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/autotoolsproject" > + <file>AutotoolsProject.mimetypes.xml</file> + </qresource> +</RCC> diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h new file mode 100644 index 0000000000..cbc442ec60 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSPROJECTCONSTANTS_H +#define AUTOTOOLSPROJECTCONSTANTS_H + +namespace AutotoolsProjectManager { +/** + * Collects project constants, that are shared between several classes. + */ +namespace Constants { + const char MAKEFILE_MIMETYPE[] = "text/x-makefile"; + +//BuildConfiguration + const char AUTOTOOLS_BC_ID[] = "AutotoolsProjectManager.AutotoolsBuildConfiguration"; + const char BUILD_DIRECTORY_KEY[] = "AutotoolsProjectManager.AutotoolsBuildConfiguration.BuildDirectory"; + +//Target + const char DEFAULT_AUTOTOOLS_TARGET_ID[] = "AutotoolsProjectManager.DefaultAutotoolsTarget"; + +//Project + const char AUTOTOOLS_PROJECT_ID[] = "AutotoolsProjectManager.AutotoolsProject"; + const char PROJECT_CONTEXT[] = "AutotoolsProject.ProjectContext"; +} // namespace Constants +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSPROJECTCONSTANTS_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp new file mode 100644 index 0000000000..cdbb2b13ff --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp @@ -0,0 +1,109 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsprojectfile.h" +#include "autotoolsproject.h" +#include "autotoolsprojectconstants.h" + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; + +AutotoolsProjectFile::AutotoolsProjectFile(AutotoolsProject *project, const QString &fileName) : + Core::IFile(project), + m_project(project), + m_fileName(fileName) +{ +} + +AutotoolsProjectFile::~AutotoolsProjectFile() +{ +} + +bool AutotoolsProjectFile::save(QString *errorString, const QString &fileName, bool autoSave) +{ + Q_UNUSED(errorString); + Q_UNUSED(fileName); + Q_UNUSED(autoSave); + + return false; +} + +QString AutotoolsProjectFile::fileName() const +{ + return m_fileName; +} + +QString AutotoolsProjectFile::defaultPath() const +{ + return QString(); +} + +QString AutotoolsProjectFile::suggestedFileName() const +{ + return QString(); +} + +QString AutotoolsProjectFile::mimeType() const +{ + return QLatin1String(Constants::MAKEFILE_MIMETYPE); +} + +bool AutotoolsProjectFile::isModified() const +{ + return false; +} + +bool AutotoolsProjectFile::isReadOnly() const +{ + return true; +} + +bool AutotoolsProjectFile::isSaveAsAllowed() const +{ + return false; +} + +bool AutotoolsProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) +{ + Q_UNUSED(errorString); + Q_UNUSED(flag); + Q_UNUSED(type); + + return false; +} + +void AutotoolsProjectFile::rename(const QString &newName) +{ + Q_UNUSED(newName); +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h new file mode 100644 index 0000000000..9bf70aa1ad --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h @@ -0,0 +1,82 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSPROJECTFILE_H +#define AUTOTOOLSPROJECTFILE_H + +#include <coreplugin/ifile.h> + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsProject; + +/** + * @brief Implementation of the Core::IFile interface. + * + * Is used in AutotoolsProject and describes the root + * of a project. In the context of autotools the implementation + * is mostly empty, as the modification of a project is + * done by several Makefile.am files and the configure.ac file. + * + * @see AutotoolsProject + */ +class AutotoolsProjectFile : public Core::IFile +{ + Q_OBJECT + +public: + AutotoolsProjectFile(AutotoolsProject *project, const QString &fileName); + ~AutotoolsProjectFile(); + + bool save(QString *errorString, const QString &fileName, bool autoSave); + QString fileName() const; + QString defaultPath() const; + QString suggestedFileName() const; + QString mimeType() const; + bool isModified() const; + bool isReadOnly() const; + bool isSaveAsAllowed() const; + bool reload(QString *errorString, ReloadFlag flag, ChangeType type); + void rename(const QString &newName); + +private: + AutotoolsProject *m_project; + QString m_fileName; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSPROJECTFILE_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro new file mode 100644 index 0000000000..b642847aa7 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro @@ -0,0 +1,39 @@ +TEMPLATE = lib +TARGET = AutotoolsProjectManager +#PROVIDER = Openismus + +include(../../qtcreatorplugin.pri) +include(autotoolsprojectmanager_dependencies.pri) + +HEADERS = autotoolsprojectplugin.h\ + autotoolsopenprojectwizard.h\ + autotoolsmanager.h\ + autotoolsprojectfile.h\ + autotoolsprojectnode.h\ + autotoolsproject.h\ + autotoolstarget.h\ + autotoolsbuildsettingswidget.h\ + autotoolsbuildconfiguration.h\ + autotoolsprojectconstants.h\ + makestep.h\ + autogenstep.h\ + autoreconfstep.h\ + configurestep.h\ + makefileparserthread.h\ + makefileparser.h +SOURCES = autotoolsprojectplugin.cpp\ + autotoolsopenprojectwizard.cpp\ + autotoolsmanager.cpp\ + autotoolsprojectfile.cpp\ + autotoolsprojectnode.cpp\ + autotoolsproject.cpp\ + autotoolstarget.cpp\ + autotoolsbuildsettingswidget.cpp\ + autotoolsbuildconfiguration.cpp\ + makestep.cpp\ + autogenstep.cpp\ + autoreconfstep.cpp\ + configurestep.cpp\ + makefileparserthread.cpp\ + makefileparser.cpp +RESOURCES += autotoolsproject.qrc diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager_dependencies.pri b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager_dependencies.pri new file mode 100644 index 0000000000..614357cd4d --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager_dependencies.pri @@ -0,0 +1,3 @@ +include(../../plugins/projectexplorer/projectexplorer.pri) +include(../../plugins/coreplugin/coreplugin.pri) +include(../../plugins/cpptools/cpptools.pri) diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.cpp new file mode 100644 index 0000000000..52feb0368d --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.cpp @@ -0,0 +1,123 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsprojectnode.h" +#include "autotoolsproject.h" + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; + +AutotoolsProjectNode::AutotoolsProjectNode(AutotoolsProject *project, Core::IFile *projectFile) : + ProjectExplorer::ProjectNode(projectFile->fileName()), + m_project(project), + m_projectFile(projectFile) +{ +} + +AutotoolsProjectNode::~AutotoolsProjectNode() +{ +} + +bool AutotoolsProjectNode::hasBuildTargets() const +{ + return true; +} + +QList<ProjectExplorer::ProjectNode::ProjectAction> AutotoolsProjectNode::supportedActions(Node *node) const +{ + Q_UNUSED(node); + return QList<ProjectExplorer::ProjectNode::ProjectAction>(); +} + +bool AutotoolsProjectNode::canAddSubProject(const QString &proFilePath) const +{ + Q_UNUSED(proFilePath) + return false; +} + +bool AutotoolsProjectNode::addSubProjects(const QStringList &proFilePaths) +{ + Q_UNUSED(proFilePaths); + return false; +} + +bool AutotoolsProjectNode::removeSubProjects(const QStringList &proFilePaths) +{ + Q_UNUSED(proFilePaths); + return false; +} + +bool AutotoolsProjectNode::addFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, + QStringList *notAdded) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePaths); + Q_UNUSED(notAdded); + return false; +} + +bool AutotoolsProjectNode::removeFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, + QStringList *notRemoved) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePaths); + Q_UNUSED(notRemoved); + return false; +} + +bool AutotoolsProjectNode::deleteFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePaths); + return false; +} + +bool AutotoolsProjectNode::renameFile(const ProjectExplorer::FileType fileType, + const QString &filePath, + const QString &newFilePath) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePath); + Q_UNUSED(newFilePath); + return false; +} + +QList<ProjectExplorer::RunConfiguration *> AutotoolsProjectNode::runConfigurationsFor(Node *node) +{ + Q_UNUSED(node); + return QList<ProjectExplorer::RunConfiguration *>(); +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.h new file mode 100644 index 0000000000..a615ce86bd --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.h @@ -0,0 +1,93 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSPROJECTNODE_H +#define AUTOTOOLSPROJECTNODE_H + +#include <projectexplorer/projectnodes.h> +#include <coreplugin/ifile.h> + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsProject; + +/** + * @brief Implementation of the ProjectExplorer::ProjectNode interface. + * + * A project node represents a file or a folder of the project tree. + * No special operations (addFiles(), removeFiles(), renameFile(), ..) + * are offered. + * + * @see AutotoolsProject + */ +class AutotoolsProjectNode : public ProjectExplorer::ProjectNode +{ + Q_OBJECT + +public: + AutotoolsProjectNode(AutotoolsProject *project, Core::IFile *projectFile); + ~AutotoolsProjectNode(); + + bool hasBuildTargets() const; + QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions(Node *node) const; + bool canAddSubProject(const QString &proFilePath) const; + bool addSubProjects(const QStringList &proFilePaths); + bool removeSubProjects(const QStringList &proFilePaths); + bool addFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, + QStringList *notAdded = 0); + bool removeFiles(const ProjectExplorer::FileType fileType, + const QStringList& filePaths, + QStringList *notRemoved = 0); + bool deleteFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths); + bool renameFile(const ProjectExplorer::FileType fileType, + const QString &filePath, + const QString &newFilePath); + QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node); + +private: + AutotoolsProject *m_project; + Core::IFile *m_projectFile; + + // TODO: AutotoolsProject calls the protected method addFileNodes() from AutotoolsProjectNode. + // Instead of this friend declaration, a public interface might be preferable. + friend class AutotoolsProject; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSPROJECTNODE_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp new file mode 100644 index 0000000000..2e53addffc --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp @@ -0,0 +1,85 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolsprojectplugin.h" +#include "autotoolsmanager.h" +#include "autotoolstarget.h" +#include "autotoolsbuildconfiguration.h" +#include "makestep.h" +#include "autogenstep.h" +#include "autoreconfstep.h" +#include "configurestep.h" +#include "autotoolsprojectconstants.h" + +#include <coreplugin/icore.h> +#include <coreplugin/mimedatabase.h> + +#include <QtCore/QStringList> +#include <QtCore/QtPlugin> + +using namespace AutotoolsProjectManager::Internal; + +AutotoolsProjectPlugin::AutotoolsProjectPlugin() +{ +} + +AutotoolsProjectPlugin::~AutotoolsProjectPlugin() +{ +} + +void AutotoolsProjectPlugin::extensionsInitialized() +{ +} + +bool AutotoolsProjectPlugin::initialize(const QStringList &arguments, + QString *errorString) +{ + Q_UNUSED(arguments); + + Core::ICore *core = Core::ICore::instance(); + if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":autotoolsproject/AutotoolsProject.mimetypes.xml"), errorString)) + return false; + + addAutoReleasedObject(new AutotoolsTargetFactory); + addAutoReleasedObject(new AutotoolsBuildConfigurationFactory); + addAutoReleasedObject(new MakeStepFactory()); + addAutoReleasedObject(new AutogenStepFactory()); + addAutoReleasedObject(new ConfigureStepFactory()); + addAutoReleasedObject(new AutoreconfStepFactory()); + addAutoReleasedObject(new AutotoolsManager()); + + return true; +} + +Q_EXPORT_PLUGIN(AutotoolsProjectPlugin) diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h new file mode 100644 index 0000000000..2b5e15c435 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSPROJECTMANAGER_H +#define AUTOTOOLSPROJECTMANAGER_H + +#include <extensionsystem/iplugin.h> + +namespace AutotoolsProjectManager { +namespace Internal { + +/** + * @brief Implementation of the ExtensionsSystem::IPlugin interface. + * + * The plugin creates the following components: + * + * - AutotoolsManager: Will manage the new autotools project and + * tell QtCreator for which MIME types the autotools project should + * be instantiated. + * + * - MakeStepFactory: This factory is used to create make steps. + * + * - AutogenStepFactory: This factory is used to create autogen steps. + * + * - AutoreconfStepFactory: This factory is used to create autoreconf + * steps. + * + * - ConfigureStepFactory: This factory is used to create configure steps. + * + * - MakefileEditorFactory: Provides a specialized editor with automatic + * syntax highlighting for Makefile.am files. + * + * - AutotoolsTargetFactory: Our current target is desktop. + * + * - AutotoolsBuildConfigurationFactory: Creates build configurations that + * contain the steps (make, autogen, autoreconf or configure) that will + * be executed in the build process) + */ + +class AutotoolsProjectPlugin : public ExtensionSystem::IPlugin +{ +public: + AutotoolsProjectPlugin(); + ~AutotoolsProjectPlugin(); + + void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString); +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSPROJECTMANAGER_H diff --git a/src/plugins/autotoolsprojectmanager/autotoolstarget.cpp b/src/plugins/autotoolsprojectmanager/autotoolstarget.cpp new file mode 100644 index 0000000000..1c32bec871 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolstarget.cpp @@ -0,0 +1,186 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "autotoolstarget.h" +#include "autotoolsproject.h" +#include "autotoolsprojectconstants.h" +#include "autotoolsbuildsettingswidget.h" +#include "autotoolsbuildconfiguration.h" +#include "makestep.h" +#include "autogenstep.h" +#include "autoreconfstep.h" +#include "configurestep.h" + +#include <projectexplorer/customexecutablerunconfiguration.h> +#include <projectexplorer/buildsteplist.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <extensionsystem/pluginmanager.h> + +#include <QtGui/QApplication> +#include <QtGui/QStyle> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; + +namespace { + +QString displayNameForId(const QString &id) { + if (id == QLatin1String(Constants::DEFAULT_AUTOTOOLS_TARGET_ID)) + return QApplication::translate("AutotoolsProjectManager::Internal::AutotoolsTarget", + "Desktop", "Autotools Default target display name"); + return QString(); +} +} + +////////////////////////// +// AutotoolsTarget class +////////////////////////// + +AutotoolsTarget::AutotoolsTarget(AutotoolsProject *parent) : + ProjectExplorer::Target(parent, QLatin1String(Constants::DEFAULT_AUTOTOOLS_TARGET_ID)), + m_buildConfigurationFactory(new AutotoolsBuildConfigurationFactory(this)) +{ + setDefaultDisplayName(displayNameForId(id())); + setIcon(qApp->style()->standardIcon(QStyle::SP_ComputerIcon)); +} + +AutotoolsTarget::~AutotoolsTarget() +{ +} + +ProjectExplorer::BuildConfigWidget *AutotoolsTarget::createConfigWidget() +{ + return new AutotoolsBuildSettingsWidget(this); +} + + +AutotoolsProject *AutotoolsTarget::autotoolsProject() const +{ + return static_cast<AutotoolsProject *>(project()); +} + +AutotoolsBuildConfiguration *AutotoolsTarget::activeBuildConfiguration() const +{ + return static_cast<AutotoolsBuildConfiguration *>(Target::activeBuildConfiguration()); +} + +AutotoolsBuildConfigurationFactory *AutotoolsTarget::buildConfigurationFactory() const +{ + return m_buildConfigurationFactory; +} + +QString AutotoolsTarget::defaultBuildDirectory() const +{ + return autotoolsProject()->defaultBuildDirectory(); +} + +bool AutotoolsTarget::fromMap(const QVariantMap &map) +{ + return Target::fromMap(map); +} + +///////////////////////////////// +// AutotoolsTargetFactory class +///////////////////////////////// +AutotoolsTargetFactory::AutotoolsTargetFactory(QObject *parent) : + ITargetFactory(parent) +{ +} + +AutotoolsTargetFactory::~AutotoolsTargetFactory() +{ +} + +bool AutotoolsTargetFactory::supportsTargetId(const QString &id) const +{ + return id == QLatin1String(Constants::DEFAULT_AUTOTOOLS_TARGET_ID); +} + +QStringList AutotoolsTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const +{ + if (!qobject_cast<AutotoolsProject *>(parent)) + return QStringList(); + return QStringList() << QLatin1String(Constants::DEFAULT_AUTOTOOLS_TARGET_ID); +} + +QString AutotoolsTargetFactory::displayNameForId(const QString &id) const +{ + return ::displayNameForId(id); +} + +bool AutotoolsTargetFactory::canCreate(ProjectExplorer::Project *parent, const QString &id) const +{ + if (!qobject_cast<AutotoolsProject *>(parent)) + return false; + return id == QLatin1String(Constants::DEFAULT_AUTOTOOLS_TARGET_ID); +} + +AutotoolsTarget *AutotoolsTargetFactory::create(ProjectExplorer::Project *parent, const QString &id) +{ + if (!canCreate(parent, id)) + return 0; + + AutotoolsProject *project(static_cast<AutotoolsProject *>(parent)); + AutotoolsTarget *t = new AutotoolsTarget(project); + + // Add default build configuration: + AutotoolsBuildConfigurationFactory *bcf = ExtensionSystem::PluginManager::instance()->getObject<AutotoolsBuildConfigurationFactory>(); + AutotoolsBuildConfiguration *bc = bcf->createDefaultConfiguration(t); + bc->setDisplayName("Default Build"); + + t->addBuildConfiguration(bc); + t->addDeployConfiguration(t->createDeployConfiguration(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID)); + // User needs to choose where the executable file is. + // TODO: Parse the file in *Anjuta style* to be able to add custom RunConfigurations. + t->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(t)); + + return t; +} + +bool AutotoolsTargetFactory::canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const +{ + return canCreate(parent, ProjectExplorer::idFromMap(map)); +} + +AutotoolsTarget *AutotoolsTargetFactory::restore(ProjectExplorer::Project *parent, const QVariantMap &map) +{ + if (!canRestore(parent, map)) + return 0; + AutotoolsProject *autotoolsproject(static_cast<AutotoolsProject *>(parent)); + AutotoolsTarget *target = new AutotoolsTarget(autotoolsproject); + if (target->fromMap(map)) + return target; + delete target; + return 0; +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolstarget.h b/src/plugins/autotoolsprojectmanager/autotoolstarget.h new file mode 100644 index 0000000000..6ac9481af8 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolstarget.h @@ -0,0 +1,101 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef AUTOTOOLSTARGET_H +#define AUTOTOOLSTARGET_H + +#include "autotoolsbuildconfiguration.h" + +#include <projectexplorer/target.h> + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsTargetFactory; +class AutotoolsBuildConfiguration; +class AutotoolsBuildConfigurationFactory; +class AutotoolsProject; + +/////////////////////////// +//// AutotoolsTarget class +/////////////////////////// +class AutotoolsTarget : public ProjectExplorer::Target +{ + Q_OBJECT + friend class AutotoolsTargetFactory; + +public: + explicit AutotoolsTarget(AutotoolsProject *parent); + ~AutotoolsTarget(); + + ProjectExplorer::BuildConfigWidget *createConfigWidget(); + AutotoolsProject *autotoolsProject() const; + AutotoolsBuildConfigurationFactory *buildConfigurationFactory() const; + AutotoolsBuildConfiguration *activeBuildConfiguration() const; + QString defaultBuildDirectory() const; + +protected: + bool fromMap(const QVariantMap &map); + +private: + AutotoolsBuildConfigurationFactory *m_buildConfigurationFactory; +}; + + +////////////////////////////////// +//// AutotoolsTargetFactory class +////////////////////////////////// +class AutotoolsTargetFactory : public ProjectExplorer::ITargetFactory +{ + Q_OBJECT + +public: + explicit AutotoolsTargetFactory(QObject *parent = 0); + ~AutotoolsTargetFactory(); + + bool supportsTargetId(const QString &id) const; + + QStringList supportedTargetIds(ProjectExplorer::Project *parent) const; + QString displayNameForId(const QString &id) const; + + bool canCreate(ProjectExplorer::Project *parent, const QString &id) const; + AutotoolsTarget *create(ProjectExplorer::Project *parent, const QString &id); + bool canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const; + AutotoolsTarget *restore(ProjectExplorer::Project *parent, const QVariantMap &map); +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // AUTOTOOLSTARGET_H diff --git a/src/plugins/autotoolsprojectmanager/configurestep.cpp b/src/plugins/autotoolsprojectmanager/configurestep.cpp new file mode 100644 index 0000000000..80037bb0a6 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/configurestep.cpp @@ -0,0 +1,303 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "configurestep.h" +#include "autotoolsproject.h" +#include "autotoolstarget.h" +#include "autotoolsbuildconfiguration.h" +#include "autotoolsprojectconstants.h" + +#include <projectexplorer/buildsteplist.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/gnumakeparser.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <utils/qtcprocess.h> + +#include <QtCore/QVariantMap> +#include <QtCore/QDateTime> +#include <QtGui/QLineEdit> +#include <QtGui/QFormLayout> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; +using namespace ProjectExplorer; + +namespace { +const char CONFIGURE_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.ConfigureStep.AdditionalArguments"; +const char CONFIGURE_STEP_ID[] = "AutotoolsProjectManager.ConfigureStep"; +} + +//////////////////////////////// +// ConfigureStepFactory Class +//////////////////////////////// +ConfigureStepFactory::ConfigureStepFactory(QObject *parent) : + ProjectExplorer::IBuildStepFactory(parent) +{ +} + +ConfigureStepFactory::~ConfigureStepFactory() +{ +} + +QStringList ConfigureStepFactory::availableCreationIds(BuildStepList *parent) const +{ + if (parent->target()->project()->id() == QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return QStringList() << QLatin1String(CONFIGURE_STEP_ID); + return QStringList(); +} + +QString ConfigureStepFactory::displayNameForId(const QString &id) const +{ + if (id == QLatin1String(CONFIGURE_STEP_ID)) + return tr("Configure", "Display name for AutotoolsProjectManager::ConfigureStep id."); + return QString(); +} + +bool ConfigureStepFactory::canCreate(BuildStepList *parent, const QString &id) const +{ + if (parent->target()->project()->id() != QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return false; + + if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD) + return false; + + return QLatin1String(CONFIGURE_STEP_ID) == id; +} + +BuildStep *ConfigureStepFactory::create(BuildStepList *parent, const QString &id) +{ + if (!canCreate(parent, id)) + return 0; + return new ConfigureStep(parent); +} + +bool ConfigureStepFactory::canClone(BuildStepList *parent, BuildStep *source) const +{ + return canCreate(parent, source->id()); +} + +BuildStep *ConfigureStepFactory::clone(BuildStepList *parent, BuildStep *source) +{ + if (!canClone(parent, source)) + return 0; + return new ConfigureStep(parent, static_cast<ConfigureStep *>(source)); +} + +bool ConfigureStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const +{ + QString id(ProjectExplorer::idFromMap(map)); + return canCreate(parent, id); +} + +BuildStep *ConfigureStepFactory::restore(BuildStepList *parent, const QVariantMap &map) +{ + if (!canRestore(parent, map)) + return 0; + ConfigureStep *bs = new ConfigureStep(parent); + if (bs->fromMap(map)) + return bs; + delete bs; + return 0; +} + +//////////////////////// +// ConfigureStep class +//////////////////////// +ConfigureStep::ConfigureStep(ProjectExplorer::BuildStepList* bsl) : + AbstractProcessStep(bsl, QLatin1String(CONFIGURE_STEP_ID)), + m_runConfigure(false) +{ + ctor(); +} + +ConfigureStep::ConfigureStep(ProjectExplorer::BuildStepList *bsl, const QString &id) : + AbstractProcessStep(bsl, id) +{ + ctor(); +} + +ConfigureStep::ConfigureStep(ProjectExplorer::BuildStepList *bsl, ConfigureStep *bs) : + AbstractProcessStep(bsl, bs), + m_additionalArguments(bs->additionalArguments()) +{ + ctor(); +} + +void ConfigureStep::ctor() +{ + setDefaultDisplayName(tr("Configure")); +} + +ConfigureStep::~ConfigureStep() +{ +} + +AutotoolsBuildConfiguration *ConfigureStep::autotoolsBuildConfiguration() const +{ + return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); +} + +bool ConfigureStep::init() +{ + AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + + setEnabled(true); + + ProcessParameters *pp = processParameters(); + pp->setMacroExpander(bc->macroExpander()); + pp->setEnvironment(bc->environment()); + pp->setWorkingDirectory(bc->buildDirectory()); + pp->setCommand("configure"); + pp->setArguments(additionalArguments()); + + return AbstractProcessStep::init(); +} + +void ConfigureStep::run(QFutureInterface<bool>& interface) +{ + AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + + //Check wether we need to run configure + const QFileInfo configureInfo(bc->buildDirectory() + QLatin1String("/configure")); + const QFileInfo configStatusInfo(bc->buildDirectory() + QLatin1String("/config.status")); + + if (!configStatusInfo.exists() + || configStatusInfo.lastModified() < configureInfo.lastModified()) { + m_runConfigure = true; + } + + if (!m_runConfigure) { + emit addOutput(tr("Configuration unchanged, skipping configure step."), BuildStep::MessageOutput); + interface.reportResult(true); + return; + } + + m_runConfigure = false; + AbstractProcessStep::run(interface); +} + +ProjectExplorer::BuildStepConfigWidget* ConfigureStep::createConfigWidget() +{ + return new ConfigureStepConfigWidget(this); +} + +bool ConfigureStep::immutable() const +{ + return false; +} + +void ConfigureStep::setAdditionalArguments(const QString &list) +{ + if (list == m_additionalArguments) + return; + + m_additionalArguments = list; + m_runConfigure = true; + + emit additionalArgumentsChanged(list); +} + +QString ConfigureStep::additionalArguments() const +{ + return m_additionalArguments; +} + +QVariantMap ConfigureStep::toMap() const +{ + QVariantMap map(AbstractProcessStep::toMap()); + + map.insert(QLatin1String(CONFIGURE_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments); + return map; +} + +bool ConfigureStep::fromMap(const QVariantMap &map) +{ + m_additionalArguments = map.value(QLatin1String(CONFIGURE_ADDITIONAL_ARGUMENTS_KEY)).toString(); + + return BuildStep::fromMap(map); +} + +///////////////////////////////////// +// ConfigureStepConfigWidget class +///////////////////////////////////// +ConfigureStepConfigWidget::ConfigureStepConfigWidget(ConfigureStep *configureStep) : + m_configureStep(configureStep), + m_summaryText(), + m_additionalArguments(0) +{ + QFormLayout *fl = new QFormLayout(this); + fl->setMargin(0); + fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); + setLayout(fl); + + m_additionalArguments = new QLineEdit(this); + fl->addRow(tr("Arguments:"), m_additionalArguments); + m_additionalArguments->setText(m_configureStep->additionalArguments()); + + updateDetails(); + + connect(m_additionalArguments, SIGNAL(textChanged(QString)), + configureStep, SLOT(setAdditionalArguments(QString))); + connect(configureStep, SIGNAL(additionalArgumentsChanged(QString)), + this, SLOT(updateDetails())); +} + +ConfigureStepConfigWidget::~ConfigureStepConfigWidget() +{ +} + +QString ConfigureStepConfigWidget::displayName() const +{ + return tr("Configure", "AutotoolsProjectManager::ConfigureStepConfigWidget display name."); +} + +QString ConfigureStepConfigWidget::summaryText() const +{ + return m_summaryText; +} + +void ConfigureStepConfigWidget::updateDetails() +{ + AutotoolsBuildConfiguration *bc = m_configureStep->autotoolsBuildConfiguration(); + + ProcessParameters param; + param.setMacroExpander(bc->macroExpander()); + param.setEnvironment(bc->environment()); + param.setWorkingDirectory(bc->buildDirectory()); + param.setCommand("configure"); + param.setArguments(m_configureStep->additionalArguments()); + m_summaryText = param.summary(displayName()); + emit updateSummary(); +} diff --git a/src/plugins/autotoolsprojectmanager/configurestep.h b/src/plugins/autotoolsprojectmanager/configurestep.h new file mode 100644 index 0000000000..ffc5aea17c --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/configurestep.h @@ -0,0 +1,162 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef CONFIGURESTEP_H +#define CONFIGURESTEP_H + +#include <projectexplorer/abstractprocessstep.h> + +QT_BEGIN_NAMESPACE +class QLineEdit; +QT_END_NAMESPACE + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsProject; +class AutotoolsBuildConfiguration; +class ConfigureStepConfigWidget; + +////////////////////////////////// +// ConfigureStepFactory Class +////////////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::IBuildStepFactory interface. + * + * The factory is used to create instances of ConfigureStep. + */ +class ConfigureStepFactory : public ProjectExplorer::IBuildStepFactory +{ + Q_OBJECT + +public: + ConfigureStepFactory(QObject *parent = 0); + ~ConfigureStepFactory(); + + QStringList availableCreationIds(ProjectExplorer::BuildStepList *bc) const; + QString displayNameForId(const QString &id) const; + + bool canCreate(ProjectExplorer::BuildStepList *parent, const QString &id) const; + ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const QString &id); + bool canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source) const; + ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source); + bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const; + ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map); +}; + +////////////////////////// +//// ConfigureStep class +////////////////////////// +///** +// * @brief Implementation of the ProjectExplorer::AbstractProcessStep interface. +// * +// * A configure step can be configured by selecting the "Projects" button of Qt +// * Creator (in the left hand side menu) and under "Build Settings". +// * +// * It is possible for the user to specify custom arguments. The corresponding +// * configuration widget is created by MakeStep::createConfigWidget and is +// * represented by an instance of the class MakeStepConfigWidget. +// */ +class ConfigureStep : public ProjectExplorer::AbstractProcessStep +{ + Q_OBJECT + friend class ConfigureStepFactory; + friend class ConfigureStepConfigWidget; + +public: + + ConfigureStep(ProjectExplorer::BuildStepList *bsl); + ~ConfigureStep(); + + AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; + bool init(); + void run(QFutureInterface<bool> &interface); + ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + bool immutable() const; + QString additionalArguments() const; + QVariantMap toMap() const; + +public slots: + void setAdditionalArguments(const QString &list); + +signals: + void additionalArgumentsChanged(const QString &); + +protected: + ConfigureStep(ProjectExplorer::BuildStepList *bsl, ConfigureStep *bs); + ConfigureStep(ProjectExplorer::BuildStepList *bsl, const QString &id); + + bool fromMap(const QVariantMap &map); + +private: + void ctor(); + + QString m_additionalArguments; + bool m_runConfigure; +}; + +///////////////////////////////////// +// ConfigureStepConfigWidget class +///////////////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::BuildStepConfigWidget interface. + * + * Allows to configure a configure step in the GUI. + */ +class ConfigureStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT + +public: + ConfigureStepConfigWidget(ConfigureStep *configureStep); + ~ConfigureStepConfigWidget(); + + QString displayName() const; + QString summaryText() const; + + +private slots: + void updateDetails(); + +private: + ConfigureStep *m_configureStep; + QString m_summaryText; + QLineEdit *m_additionalArguments; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // CONFIGURESTEP_H + diff --git a/src/plugins/autotoolsprojectmanager/makefileparser.cpp b/src/plugins/autotoolsprojectmanager/makefileparser.cpp new file mode 100644 index 0000000000..a9db927ee4 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/makefileparser.cpp @@ -0,0 +1,454 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "makefileparser.h" + +#include <utils/qtcassert.h> + +#include <QtCore/QFile> +#include <QtCore/QFileInfoList> +#include <QtCore/QMutexLocker> + +using namespace AutotoolsProjectManager::Internal; + +MakefileParser::MakefileParser(const QString &makefile) : + QObject(), + m_success(false), + m_cancel(false), + m_mutex(), + m_makefile(makefile), + m_executable(), + m_sources(), + m_makefiles(), + m_includePaths(), + m_line(), + m_textStream() +{ +} + +MakefileParser::~MakefileParser() +{ +} + +bool MakefileParser::parse() +{ + m_mutex.lock(); + m_cancel = false; + m_mutex.unlock(), + + m_success = true; + m_executable.clear(); + m_sources.clear(); + m_makefiles.clear(); + + QFile *file = new QFile(m_makefile); + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) + return false; + + QFileInfo info(m_makefile); + m_makefiles.append(info.fileName()); + + emit status(tr("Parsing %1 in directory %2").arg(info.fileName()).arg(info.absolutePath())); + + m_textStream.setDevice(file); + + do { + m_line = m_textStream.readLine(); + switch (topTarget()) { + case AmDefaultSourceExt: parseDefaultSourceExtensions(); break; + case BinPrograms: parseBinPrograms(); break; + case BuiltSources: break; // TODO: Add to m_sources? + case Sources: parseSources(); break; + case SubDirs: parseSubDirs(); break; + case Undefined: + default: break; + } + } while (!m_line.isNull()); + + parseIncludePaths(); + + return m_success; +} + +QStringList MakefileParser::sources() const +{ + return m_sources; +} + +QStringList MakefileParser::makefiles() const +{ + return m_makefiles; +} + +QString MakefileParser::executable() const +{ + return m_executable; +} + +QStringList MakefileParser::includePaths() const +{ + return m_includePaths; +} + +void MakefileParser::cancel() +{ + QMutexLocker locker(&m_mutex); + m_cancel = true; +} + +bool MakefileParser::isCanceled() const +{ + QMutexLocker locker(&m_mutex); + return m_cancel; +} + +MakefileParser::TopTarget MakefileParser::topTarget() const +{ + TopTarget topTarget = Undefined; + + const QString line = m_line.simplified(); + if (!line.isEmpty() && !line.startsWith(QChar('#'))) { + // TODO: Check how many fixed strings like AM_DEFAULT_SOURCE_EXT will + // be needed vs. variable strings like _SOURCES. Dependend on this a + // more clever way than this (expensive) if-cascading might be done. + if (line.startsWith(QLatin1String("AM_DEFAULT_SOURCE_EXT ="))) + topTarget = AmDefaultSourceExt; + else if (line.startsWith(QLatin1String("bin_PROGRAMS ="))) + topTarget = BinPrograms; + else if (line.startsWith(QLatin1String("BUILT_SOURCES ="))) + topTarget = BuiltSources; + else if (line.contains(QLatin1String("SUBDIRS ="))) + topTarget = SubDirs; + else if (line.contains(QLatin1String("_SOURCES ="))) + topTarget = Sources; + } + + return topTarget; +} + +void MakefileParser::parseBinPrograms() +{ + QTC_ASSERT(m_line.contains(QLatin1String("bin_PROGRAMS")), return); + const QStringList binPrograms = targetValues(); + + // TODO: are multiple values possible? + if (binPrograms.size() == 1) { + QFileInfo info(binPrograms.first()); + m_executable = info.fileName(); + } +} + +void MakefileParser::parseSources() +{ + QTC_ASSERT(m_line.contains(QLatin1String("_SOURCES")), return); + + bool hasVariables = false; + m_sources.append(targetValues(&hasVariables)); + + // Skip parsing of Makefile.am for getting the sub directories, + // as variables have been used. As fallback all sources will be added. + if (hasVariables) + addAllSources(); + + // Duplicates might be possible in combination with 'AM_DEFAULT_SOURCE_EXT =' + m_sources.removeDuplicates(); + + // TODO: Definitions like "SOURCES = ../src.cpp" are ignored currently. + // This case must be handled correctly in MakefileParser::parseSubDirs(), + // where the current sub directory must be shortened. + QStringList::iterator it = m_sources.begin(); + while (it != m_sources.end()) { + if ((*it).startsWith(QLatin1String(".."))) + it = m_sources.erase(it); + else + ++it; + } +} + +void MakefileParser::parseDefaultSourceExtensions() +{ + QTC_ASSERT(m_line.contains(QLatin1String("AM_DEFAULT_SOURCE_EXT")), return); + const QStringList extensions = targetValues(); + if (extensions.isEmpty()) { + m_success = false; + return; + } + + QFileInfo info(m_makefile); + const QString dirName = info.absolutePath(); + m_sources.append(directorySources(dirName, extensions)); + + // Duplicates might be possible in combination with '_SOURCES =' + m_sources.removeDuplicates(); +} + +void MakefileParser::parseSubDirs() +{ + QTC_ASSERT(m_line.contains(QLatin1String("SUBDIRS")), return); + if (isCanceled()) { + m_success = false; + return; + } + + QFileInfo info(m_makefile); + const QString path = info.absolutePath(); + const QString makefileName = info.fileName(); + + bool hasVariables = false; + QStringList subDirs = targetValues(&hasVariables); + if (hasVariables) { + // Skip parsing of Makefile.am for getting the sub directories, + // as variables have been used. As fallback all sources will be added. + addAllSources(); + return; + } + + // If the SUBDIRS values contain a '.' or a variable like $(test), + // all the sub directories of the current folder must get parsed. + bool hasDotSubDir = false; + QStringList::iterator it = subDirs.begin(); + while (it != subDirs.end()) { + // Erase all entries that represent a '.' + if ((*it) == QChar('.')) { + hasDotSubDir = true; + it = subDirs.erase(it); + } else { + ++it; + } + } + if (hasDotSubDir) { + // Add all sub directories of the current folder + QDir dir(path); + dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + foreach (const QFileInfo& info, dir.entryInfoList()) { + subDirs.append(info.fileName()); + } + } + subDirs.removeDuplicates(); + + // Delegate the parsing of all sub directories to a local + // makefile parser and merge the results + foreach (const QString& subDir, subDirs) { + const QChar slash('/'); + const QString subDirMakefile = path + slash + subDir + + slash + makefileName; + + // Parse sub directory + QFile *file = new QFile(subDirMakefile); + + // Don't try to parse a file, that might not exist (e. g. + // if SUBDIRS specifies a 'po' directory). + if (!file->exists()) + continue; + + MakefileParser parser(subDirMakefile); + connect(&parser, SIGNAL(status(QString)), this, SIGNAL(status(QString))); + const bool success = parser.parse(); + + // Don't return, try to parse as many sub directories + // as possible + if (!success) + m_success = false; + + m_makefiles.append(subDir + slash + makefileName); + + // Append the sources of the sub directory to the + // current sources + foreach (const QString& source, parser.sources()) + m_sources.append(subDir + slash + source); + + // Duplicates might be possible in combination with several + // "..._SUBDIRS" targets + m_makefiles.removeDuplicates(); + m_sources.removeDuplicates(); + } + + if (subDirs.isEmpty()) + m_success = false; +} + +QStringList MakefileParser::directorySources(const QString &directory, + const QStringList &extensions) +{ + if (isCanceled()) { + m_success = false; + return QStringList(); + } + + emit status(tr("Parsing directory %1").arg(directory)); + + QStringList list; // return value + + QDir dir(directory); + dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); + + const QFileInfoList infos = dir.entryInfoList(); + foreach (const QFileInfo& info, infos) { + if (info.isDir()) { + // Append recursively sources from the sub directory + const QStringList subDirSources = directorySources(info.absoluteFilePath(), + extensions); + const QString dirPath = info.fileName(); + foreach (const QString& subDirSource, subDirSources) + list.append(dirPath + QChar('/') + subDirSource); + } else { + // Check whether the file matches to an extension + foreach (const QString& extension, extensions) { + if (info.fileName().endsWith(extension)) { + list.append(info.fileName()); + appendHeader(list, dir, info.baseName()); + break; + } + } + } + } + + return list; +} + +QStringList MakefileParser::targetValues(bool *hasVariables) +{ + QStringList values; + if (hasVariables != 0) + *hasVariables = false; + + const int index = m_line.indexOf(QChar('=')); + if (index < 0) { + m_success = false; + return QStringList(); + } + + m_line.remove(0, index + 1); // remove the 'target = ' prefix + + bool endReached = false; + do { + m_line = m_line.simplified(); + + // Get all values of a line separated by spaces. + // Values representing a variable like $(value) get + // removed currently. + QStringList lineValues = m_line.split(QChar(' ')); + QStringList::iterator it = lineValues.begin(); + while (it != lineValues.end()) { + if ((*it).startsWith(QLatin1String("$("))) { + it = lineValues.erase(it); + if (hasVariables != 0) + *hasVariables = true; + } else { + ++it; + } + } + + endReached = lineValues.isEmpty(); + if (!endReached) { + const QChar backSlash('\\'); + QString last = lineValues.last(); + if (last.endsWith(backSlash)) { + // The last value contains a backslash. Remove the + // backslash and replace the last value. + lineValues.pop_back(); + last.remove(backSlash); + if (!last.isEmpty()) + lineValues.push_back(last); + + values.append(lineValues); + m_line = m_textStream.readLine(); + endReached = m_line.isNull(); + } else { + values.append(lineValues); + endReached = true; + } + } + } while (!endReached); + + return values; +} + +void MakefileParser::appendHeader(QStringList &list, const QDir &dir, const QString &fileName) +{ + const char *const headerExtensions[] = { ".h", ".hh", ".hg", ".hxx", ".hpp", 0 }; + int i = 0; + while (headerExtensions[i] != 0) { + const QString headerFile = fileName + QLatin1String(headerExtensions[i]); + QFileInfo fileInfo(dir, headerFile); + if (fileInfo.exists()) + list.append(headerFile); + ++i; + } +} + +void MakefileParser::addAllSources() +{ + QStringList extensions; + extensions << QLatin1String(".c") + << QLatin1String(".cpp") + << QLatin1String(".cc") + << QLatin1String(".cxx") + << QLatin1String(".ccg"); + QFileInfo info(m_makefile); + m_sources.append(directorySources(info.absolutePath(), extensions)); + m_sources.removeDuplicates(); +} + +void MakefileParser::parseIncludePaths() +{ + QFileInfo info(m_makefile); + const QString dirName = info.absolutePath(); + + QFile *file = new QFile(dirName + QLatin1String("/Makefile")); + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) + return; + + // TODO: The parsing is done very poor. Comments are ignored and targets + // are ignored too. Whether it is worth to improve this, depends on whether + // we want to parse the generated Makefile at all or whether we want to + // improve the Makefile.am parsing to be aware of variables. + QTextStream textStream(file); + QString line; + do { + line = textStream.readLine(); + QStringList terms = line.split(QLatin1Char(' '), QString::SkipEmptyParts); + foreach (const QString &term, terms) { + if (term.startsWith(QLatin1String("-I"))) { + QString includePath = term.right(term.length() - 2); // remove the "-I" + if (includePath == QLatin1String(".")) + includePath = dirName; + if (!includePath.isEmpty()) + m_includePaths += includePath; + } + } + } while (!line.isNull()); + + m_includePaths.removeDuplicates(); +} diff --git a/src/plugins/autotoolsprojectmanager/makefileparser.h b/src/plugins/autotoolsprojectmanager/makefileparser.h new file mode 100644 index 0000000000..ede6bfe45c --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/makefileparser.h @@ -0,0 +1,231 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef MAKEFILEPARSER_H +#define MAKEFILEPARSER_H + +#include <QtCore/QMutex> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QTextStream> +#include <QtCore/QObject> +#include <QtCore/QDir> +#include <QtCore/QFileInfo> + +namespace AutotoolsProjectManager { +namespace Internal { + +/** + * @brief Parses the autotools makefile Makefile.am. + * + * The parser returns the sources, makefiles and executable. + * Variables like $(test) are not evaluated. If such a variable + * is part of a SOURCES target, a fallback will be done and all + * sub directories get parsed for C- and C++ files. + */ +class MakefileParser : public QObject +{ + Q_OBJECT + +public: + /** + * @param makefile Filename including path of the autotools + * makefile that should be parsed. + */ + MakefileParser(const QString &makefile); + ~MakefileParser(); + + /** + * Parses the makefile. Must be invoked at least once, otherwise + * the getter methods of MakefileParser will return empty values. + * @return True, if the parsing was successful. If false is returned, + * the makefile could not be opened. + */ + bool parse(); + + /** + * @return List of sources that are set for the _SOURCES target. + * Sources in sub directorties contain the sub directory as + * prefix. + */ + QStringList sources() const; + + /** + * @return List of Makefile.am files from the current directory and + * all sub directories. The values for sub directories contain + * the sub directory as prefix. + */ + QStringList makefiles() const; + + /** + * @return File name of the executable. + */ + QString executable() const; + + /** + * @return List of include paths. Should be invoked, after the signal + * finished() has been emitted. + */ + QStringList includePaths() const; + + /** + * Cancels the parsing. Calling this method only makes sense, if the + * parser runs in a different thread than the caller of this method. + * The method is thread-safe. + */ + void cancel(); + + /** + * @return True, if the parser has been cancelled by MakefileParser::cancel(). + * The method is thread-safe. + */ + bool isCanceled() const; + +signals: + /** + * Is emitted periodically during parsing the Makefile.am files + * and the sub directories. \p status provides a translated + * string, that can be shown to indicate the current state + * of the parsing. + */ + void status(const QString &status); + +private: + enum TopTarget { + Undefined, + AmDefaultSourceExt, + BinPrograms, + BuiltSources, + Sources, + SubDirs + }; + + TopTarget topTarget() const; + + /** + * Parses the bin_PROGRAM target and stores it in m_executable. + */ + void parseBinPrograms(); + + /** + * Parses all values from a _SOURCE target and appends them to + * the m_sources list. + */ + void parseSources(); + + /** + * Parses all sub directories for files having the extension + * specified by 'AM_DEFAULT_SOURCE_EXT ='. The result will be + * append to the m_sources list. Corresponding header files + * will automatically be attached too. + */ + void parseDefaultSourceExtensions(); + + /** + * Parses all sub directories specified by the SUBDIRS target and + * adds the found sources to the m_sources list. The found makefiles + * get added to the m_makefiles list. + */ + void parseSubDirs(); + + /** + * Helper method for parseDefaultExtensions(). Returns recursively all sources + * inside the directory \p directory that match with the extension \p extension. + */ + QStringList directorySources(const QString &directory, + const QStringList &extensions); + + /** + * Helper method for all parse-methods. Returns each value of a target as string in + * the stringlist. The current line m_line is used as starting point and increased + * if the current line ends with a \. + * + * Example: For the text + * \code + * my_SOURCES = a.cpp\ + * b.cpp c.cpp\ + * d.cpp + * \endcode + * the string list contains all 4 *.cpp files. m_line is positioned to d.cpp afterwards. + * Variables like $(test) are skipped and not part of the return value. + * + * @param hasVariables Optional output parameter. Is set to true, if the target values + * contained a variable like $(test). Note that all variables are not + * part of the return value, as they cannot get interpreted currently. + */ + QStringList targetValues(bool *hasVariables = 0); + + /** + * Adds recursively all sources of the current folder to m_sources and removes + * all duplicates. The Makefile.am is not parsed, only the folders and files are + * handled. This method should only be called, if the sources parsing in the Makefile.am + * failed because variables (e.g. $(test)) have been used. + */ + void addAllSources(); + + /** + * Adds all include paths to m_includePaths. TODO: Currently this is done + * by parsing the generated Makefile. It might be more efficient and reliable + * to parse the Makefile.am instead. + */ + void parseIncludePaths(); + + /** + * Helper method for MakefileParser::directorySources(). Appends the name of the headerfile + * to \p list, if the header could be found in the directory specified by \p dir. + * The headerfile base name is defined by \p fileName. + */ + static void appendHeader(QStringList &list, const QDir &dir, const QString &fileName); + +private: + bool m_success; ///< Return value for MakefileParser::parse(). + + bool m_cancel; ///< True, if the parsing should be cancelled. + mutable QMutex m_mutex; ///< Mutex to protect m_cancel. + + QString m_makefile; ///< Filename of the makefile + QString m_executable; ///< Return value for MakefileParser::executable() + QStringList m_sources; ///< Return value for MakefileParser::sources() + QStringList m_makefiles; ///< Return value for MakefileParser::makefiles() + QStringList m_includePaths; ///< Return value for MakefileParser::includePaths() + + QString m_line; ///< Current line of the makefile + QTextStream m_textStream; ///< Textstream that represents the makefile +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // MAKEFILEPARSER_H + diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp new file mode 100644 index 0000000000..eee5c718dc --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp @@ -0,0 +1,112 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "makefileparserthread.h" + +#include <QtCore/QMutexLocker> + +using namespace AutotoolsProjectManager::Internal; + +MakefileParserThread::MakefileParserThread(const QString &makefile) : + QThread(), + m_parser(makefile), + m_mutex(), + m_hasError(false), + m_executable(), + m_sources(), + m_makefiles(), + m_includePaths() +{ + connect(&m_parser, SIGNAL(status(QString)), this, SIGNAL(status(QString))); +} + +MakefileParserThread::~MakefileParserThread() +{ +} + +QStringList MakefileParserThread::sources() const +{ + QMutexLocker locker(&m_mutex); + return m_sources; +} + +QStringList MakefileParserThread::makefiles() const +{ + QMutexLocker locker(&m_mutex); + return m_makefiles; +} + +QString MakefileParserThread::executable() const +{ + QMutexLocker locker(&m_mutex); + return m_executable; +} + +QStringList MakefileParserThread::includePaths() const +{ + QMutexLocker locker(&m_mutex); + return m_includePaths; +} + +bool MakefileParserThread::hasError() const +{ + QMutexLocker locker(&m_mutex); + return m_hasError; +} + +bool MakefileParserThread::isCanceled() const +{ + // MakefileParser::isCanceled() is thread-safe + return m_parser.isCanceled(); +} + +void MakefileParserThread::cancel() +{ + m_parser.cancel(); +} + +void MakefileParserThread::run() +{ + const bool success = m_parser.parse(); + + // Important: Start locking the mutex _after_ the parsing has been finished, as + // this prevents long locks if the caller reads a value before the signal + // finished() has been emitted. + QMutexLocker locker(&m_mutex); + m_hasError = !success; + m_executable = m_parser.executable(); + m_sources = m_parser.sources(); + m_makefiles = m_parser.makefiles(); + m_includePaths = m_parser.includePaths(); +} diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.h b/src/plugins/autotoolsprojectmanager/makefileparserthread.h new file mode 100644 index 0000000000..4815dc392b --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.h @@ -0,0 +1,136 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef MAKEFILEPARSERTHREAD_H +#define MAKEFILEPARSERTHREAD_H + +#include <makefileparser.h> + +#include <QtCore/QMutex> +#include <QtCore/QString> +#include <QtCore/QThread> + +namespace AutotoolsProjectManager { +namespace Internal { + +/** + * @brief Executes the makefile parser in the thread. + * + * After the finished() signal has been emitted, the makefile + * parser output can be read by sources(), makefiles() and executable(). + * A parsing error can be checked by hasError(). + */ +class MakefileParserThread : public QThread +{ + Q_OBJECT + +public: + MakefileParserThread(const QString &makefile); + ~MakefileParserThread(); + + /** @see QThread::run() */ + void run(); + + /** + * @return List of sources that are set for the _SOURCES target. + * Sources in sub directorties contain the sub directory as + * prefix. Should be invoked, after the signal finished() + * has been emitted. + */ + QStringList sources() const; + + /** + * @return List of Makefile.am files from the current directory and + * all sub directories. The values for sub directories contain + * the sub directory as prefix. Should be invoked, after the + * signal finished() has been emitted. + */ + QStringList makefiles() const; + + /** + * @return File name of the executable. Should be invoked, after the + * signal finished() has been emitted. + */ + QString executable() const; + + /** + * @return List of include paths. Should be invoked, after the signal + * finished() has been emitted. + */ + QStringList includePaths() const; + + /** + * @return True, if an error occured during the parsing. Should be invoked, + * after the signal finished() has been emitted. + */ + bool hasError() const; + + /** + * @return True, if the the has been cancelled by MakefileParserThread::cancel(). + */ + bool isCanceled() const; + +public slots: + /** + * Cancels the parsing of the makefile. MakefileParser::hasError() will + * return true in this case. + */ + void cancel(); + +signals: + /** + * Is emitted periodically during parsing the Makefile.am files + * and the sub directories. \p status provides a translated + * string, that can be shown to indicate the current state + * of the parsing. + */ + void status(const QString &status); + +private: + MakefileParser m_parser; ///< Is not accessible outside the thread + + mutable QMutex m_mutex; + bool m_hasError; ///< Return value for MakefileParserThread::hasError() + QString m_executable; ///< Return value for MakefileParserThread::executable() + QStringList m_sources; ///< Return value for MakefileParserThread::sources() + QStringList m_makefiles; ///< Return value for MakefileParserThread::makefiles() + QStringList m_includePaths; ///< Return value for MakefileParserThread::includePaths() +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // MAKEFILEPARSERTHREAD_H + + diff --git a/src/plugins/autotoolsprojectmanager/makestep.cpp b/src/plugins/autotoolsprojectmanager/makestep.cpp new file mode 100644 index 0000000000..2cafcc82d3 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/makestep.cpp @@ -0,0 +1,326 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "makestep.h" +#include "autotoolsproject.h" +#include "autotoolsprojectconstants.h" +#include "autotoolsbuildconfiguration.h" +#include "autotoolstarget.h" + +#include <projectexplorer/buildsteplist.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/gnumakeparser.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <utils/qtcprocess.h> + +#include <QtCore/QVariantMap> +#include <QtGui/QLineEdit> +#include <QtGui/QFormLayout> + +using namespace AutotoolsProjectManager; +using namespace AutotoolsProjectManager::Internal; +using namespace ProjectExplorer; + +namespace { +const char MAKE_STEP_ID[] = "AutotoolsProjectManager.MakeStep"; +const char CLEAN_KEY[] = "AutotoolsProjectManager.MakeStep.Clean"; +const char BUILD_TARGETS_KEY[] = "AutotoolsProjectManager.MakeStep.BuildTargets"; +const char MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.MakeStep.AdditionalArguments"; +} + +////////////////////////// +// MakeStepFactory class +////////////////////////// +MakeStepFactory::MakeStepFactory(QObject *parent) : + ProjectExplorer::IBuildStepFactory(parent) +{ +} + +MakeStepFactory::~MakeStepFactory() +{ +} + +QStringList MakeStepFactory::availableCreationIds(BuildStepList *parent) const +{ + if (parent->target()->project()->id() == QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return QStringList() << QLatin1String(MAKE_STEP_ID); + return QStringList(); +} + +QString MakeStepFactory::displayNameForId(const QString &id) const +{ + if (id == QLatin1String(MAKE_STEP_ID)) + return tr("Make", "Display name for AutotoolsProjectManager::MakeStep id."); + return QString(); +} + +bool MakeStepFactory::canCreate(BuildStepList *parent, const QString &id) const +{ + if (parent->target()->project()->id() != QLatin1String(Constants::AUTOTOOLS_PROJECT_ID)) + return false; + + if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD) + return false; + + return QLatin1String(MAKE_STEP_ID) == id; +} + +BuildStep *MakeStepFactory::create(BuildStepList *parent, const QString &id) +{ + if (!canCreate(parent, id)) + return 0; + return new MakeStep(parent); +} + +bool MakeStepFactory::canClone(BuildStepList *parent, BuildStep *source) const +{ + return canCreate(parent, source->id()); +} + +BuildStep *MakeStepFactory::clone(BuildStepList *parent, BuildStep *source) +{ + if (!canClone(parent, source)) + return 0; + return new MakeStep(parent, static_cast<MakeStep *>(source)); +} + +bool MakeStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const +{ + QString id(ProjectExplorer::idFromMap(map)); + return canCreate(parent, id); +} + +BuildStep *MakeStepFactory::restore(BuildStepList *parent, const QVariantMap &map) +{ + if (!canRestore(parent, map)) + return 0; + MakeStep *bs = new MakeStep(parent); + if (bs->fromMap(map)) + return bs; + delete bs; + return 0; +} + +///////////////////// +// MakeStep class +///////////////////// +MakeStep::MakeStep(ProjectExplorer::BuildStepList* bsl) : + AbstractProcessStep(bsl, QLatin1String(MAKE_STEP_ID)), + m_clean(false) +{ + ctor(); +} + +MakeStep::MakeStep(ProjectExplorer::BuildStepList *bsl, const QString &id) : + AbstractProcessStep(bsl, id), + m_clean(false) +{ + ctor(); +} + +MakeStep::MakeStep(ProjectExplorer::BuildStepList *bsl, MakeStep *bs) : + AbstractProcessStep(bsl, bs), + m_buildTargets(bs->m_buildTargets), + m_additionalArguments(bs->additionalArguments()), + m_clean(bs->m_clean) +{ + ctor(); +} + +void MakeStep::ctor() +{ + setDefaultDisplayName(tr("Make")); +} + +MakeStep::~MakeStep() +{ +} + +AutotoolsBuildConfiguration *MakeStep::autotoolsBuildConfiguration() const +{ + return static_cast<AutotoolsBuildConfiguration *>(buildConfiguration()); +} + +void MakeStep::setClean(bool clean) +{ + m_clean = clean; +} + +bool MakeStep::init() +{ + AutotoolsBuildConfiguration *bc = autotoolsBuildConfiguration(); + + QString arguments = Utils::QtcProcess::joinArgs(m_buildTargets); + Utils::QtcProcess::addArgs(&arguments, additionalArguments()); + + setEnabled(true); + setIgnoreReturnValue(m_clean); + + ProcessParameters *pp = processParameters(); + pp->setMacroExpander(bc->macroExpander()); + pp->setEnvironment(bc->environment()); + pp->setWorkingDirectory(bc->buildDirectory()); + pp->setCommand(bc->toolChain()->makeCommand()); + pp->setArguments(arguments); + + setOutputParser(new ProjectExplorer::GnuMakeParser()); + if (bc->autotoolsTarget()->autotoolsProject()->toolChain()) + appendOutputParser(bc->autotoolsTarget()->autotoolsProject()->toolChain()->outputParser()); + outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory()); + + return AbstractProcessStep::init(); +} + +void MakeStep::run(QFutureInterface<bool> &interface) +{ + AbstractProcessStep::run(interface); +} + +ProjectExplorer::BuildStepConfigWidget* MakeStep::createConfigWidget() +{ + return new MakeStepConfigWidget(this); +} + +bool MakeStep::immutable() const +{ + return false; +} + +void MakeStep::setBuildTarget(const QString &target, bool on) +{ + QStringList old = m_buildTargets; + if (on && !old.contains(target)) + old << target; + else if (!on && old.contains(target)) + old.removeOne(target); + + m_buildTargets = old; +} + +void MakeStep::setAdditionalArguments(const QString &list) +{ + if (list == m_additionalArguments) + return; + + m_additionalArguments = list; + + emit additionalArgumentsChanged(list); +} + +QString MakeStep::additionalArguments() const +{ + return m_additionalArguments; +} + +QVariantMap MakeStep::toMap() const +{ + QVariantMap map(AbstractProcessStep::toMap()); + + map.insert(QLatin1String(BUILD_TARGETS_KEY), m_buildTargets); + map.insert(QLatin1String(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments); + map.insert(QLatin1String(CLEAN_KEY), m_clean); + return map; +} + +bool MakeStep::fromMap(const QVariantMap &map) +{ + m_buildTargets = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList(); + m_additionalArguments = map.value(QLatin1String(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY)).toString(); + m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool(); + + return BuildStep::fromMap(map); +} + +/////////////////////////////// +// MakeStepConfigWidget class +/////////////////////////////// +MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) : + m_makeStep(makeStep), + m_summaryText(), + m_additionalArguments(0) +{ + QFormLayout *fl = new QFormLayout(this); + fl->setMargin(0); + fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); + setLayout(fl); + + m_additionalArguments = new QLineEdit(this); + fl->addRow(tr("Arguments:"), m_additionalArguments); + m_additionalArguments->setText(m_makeStep->additionalArguments()); + + updateDetails(); + + connect(m_additionalArguments, SIGNAL(textChanged(QString)), + makeStep, SLOT(setAdditionalArguments(QString))); + connect(makeStep, SIGNAL(additionalArgumentsChanged(QString)), + this, SLOT(updateDetails())); +} + +MakeStepConfigWidget::~MakeStepConfigWidget() +{ +} + +QString MakeStepConfigWidget::displayName() const +{ + return tr("Make", "AutotoolsProjectManager::MakeStepConfigWidget display name."); +} + +QString MakeStepConfigWidget::summaryText() const +{ + return m_summaryText; +} + +void MakeStepConfigWidget::updateDetails() +{ + AutotoolsBuildConfiguration *bc = m_makeStep->autotoolsBuildConfiguration(); + ProjectExplorer::ToolChain *tc = bc->toolChain(); + + if (tc) { + QString arguments = Utils::QtcProcess::joinArgs(m_makeStep->m_buildTargets); + Utils::QtcProcess::addArgs(&arguments, m_makeStep->additionalArguments()); + + ProcessParameters param; + param.setMacroExpander(bc->macroExpander()); + param.setEnvironment(bc->environment()); + param.setWorkingDirectory(bc->buildDirectory()); + param.setCommand(tc->makeCommand()); + param.setArguments(arguments); + m_summaryText = param.summary(displayName()); + } else { + m_summaryText = tr("<b>Unknown tool chain</b>"); + } + + emit updateSummary(); +} diff --git a/src/plugins/autotoolsprojectmanager/makestep.h b/src/plugins/autotoolsprojectmanager/makestep.h new file mode 100644 index 0000000000..af849ff870 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/makestep.h @@ -0,0 +1,163 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasantanacruz@gmail.com) +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef MAKESTEP_H +#define MAKESTEP_H + +#include <projectexplorer/abstractprocessstep.h> + +QT_BEGIN_NAMESPACE +class QLineEdit; +QT_END_NAMESPACE + +namespace AutotoolsProjectManager { +namespace Internal { + +class AutotoolsProject; +class AutotoolsBuildConfiguration; +class MakeStep; + +/////////////////////////// +// MakeStepFactory class +/////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::IBuildStepFactory interface. + * + * The factory is used to create instances of MakeStep. + */ +class MakeStepFactory : public ProjectExplorer::IBuildStepFactory +{ + Q_OBJECT + +public: + MakeStepFactory(QObject *parent = 0); + ~MakeStepFactory(); + + QStringList availableCreationIds(ProjectExplorer::BuildStepList *bc) const; + QString displayNameForId(const QString &id) const; + + bool canCreate(ProjectExplorer::BuildStepList *parent, const QString &id) const; + ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const QString &id); + bool canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source) const; + ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *source); + bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const; + ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map); +}; + +///////////////////// +// MakeStep class +///////////////////// +/** + * @brief Implementation of the ProjectExplorer::AbstractProcessStep interface. + * + * A make step can be configured by selecting the "Projects" button of Qt Creator + * (in the left hand side menu) and under "Build Settings". + * + * It is possible for the user to specify custom arguments. The corresponding + * configuration widget is created by MakeStep::createConfigWidget and is + * represented by an instance of the class MakeStepConfigWidget. + */ +class MakeStep : public ProjectExplorer::AbstractProcessStep +{ + Q_OBJECT + friend class MakeStepFactory; + friend class MakeStepConfigWidget; + +public: + + MakeStep(ProjectExplorer::BuildStepList *bsl); + ~MakeStep(); + + AutotoolsBuildConfiguration *autotoolsBuildConfiguration() const; + bool init(); + void run(QFutureInterface<bool> &interface); + ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + void setClean(bool clean); + bool immutable() const; + void setBuildTarget(const QString &target, bool on); + QString additionalArguments() const; + QVariantMap toMap() const; + +public slots: + void setAdditionalArguments(const QString &list); + +signals: + void additionalArgumentsChanged(const QString &); + +protected: + MakeStep(ProjectExplorer::BuildStepList *bsl, MakeStep *bs); + MakeStep(ProjectExplorer::BuildStepList *bsl, const QString &id); + + bool fromMap(const QVariantMap &map); + +private: + void ctor(); + + QStringList m_buildTargets; + QString m_additionalArguments; + bool m_clean; +}; + +/////////////////////////////// +// MakeStepConfigWidget class +/////////////////////////////// +/** + * @brief Implementation of the ProjectExplorer::BuildStepConfigWidget interface. + * + * Allows to configure a make step in the GUI. + */ +class MakeStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT + +public: + MakeStepConfigWidget(MakeStep *makeStep); + ~MakeStepConfigWidget(); + + QString displayName() const; + QString summaryText() const; + +private slots: + void updateDetails(); + +private: + MakeStep *m_makeStep; + QString m_summaryText; + QLineEdit *m_additionalArguments; +}; + +} // namespace Internal +} // namespace AutotoolsProjectManager + +#endif // MAKESTEP_H diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.cpp b/src/plugins/genericprojectmanager/genericprojectwizard.cpp index 00b961d8fe..dfabed3b36 100644 --- a/src/plugins/genericprojectmanager/genericprojectwizard.cpp +++ b/src/plugins/genericprojectmanager/genericprojectwizard.cpp @@ -129,7 +129,7 @@ Core::BaseFileWizardParameters GenericProjectWizard::parameters() } parameters.setDisplayName(tr("Import Existing Project")); parameters.setId(QLatin1String("Z.Makefile")); - parameters.setDescription(tr("Imports existing projects that do not use qmake or CMake. " + parameters.setDescription(tr("Imports existing projects that do not use qmake, CMake or Autotools. " "This allows you to use Qt Creator as a code editor.")); parameters.setCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY)); parameters.setDisplayCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY_DISPLAY)); diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index b1eff599b7..419f1f2f5d 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -25,6 +25,7 @@ SUBDIRS = plugin_coreplugin \ plugin_help \ plugin_cpaster \ plugin_cmakeprojectmanager \ + plugin_autotoolsprojectmanager \ plugin_fakevim \ plugin_designer \ plugin_resourceeditor \ @@ -216,6 +217,11 @@ plugin_cmakeprojectmanager.depends = plugin_texteditor plugin_cmakeprojectmanager.depends += plugin_projectexplorer plugin_cmakeprojectmanager.depends += plugin_cpptools +plugin_autotoolsprojectmanager.subdir = autotoolsprojectmanager +plugin_autotoolsprojectmanager.depends = plugin_projectexplorer +plugin_autotoolsprojectmanager.depends += plugin_coreplugin +plugin_autotoolsprojectmanager.depends += plugin_cpptools + plugin_genericprojectmanager.subdir = genericprojectmanager plugin_genericprojectmanager.depends = plugin_texteditor plugin_genericprojectmanager.depends += plugin_projectexplorer |