From 6445c99ad2020182b5d105b29e373de6273cb5f5 Mon Sep 17 00:00:00 2001 From: Patricia Santana Cruz Date: Tue, 29 Nov 2011 14:19:28 +0100 Subject: [PATCH] Add AutotoolsProjectManager plugin Change-Id: Icbc8d105a3ffea2bf705d18e3413f6b3487ccfd3 Reviewed-by: Oswald Buddenhagen Reviewed-by: hjk Reviewed-by: Leena Miettinen --- doc/images/qtcreator-autotools-buildrun.png | Bin 0 -> 25725 bytes .../qtcreator-autotools-buildsettings.png | Bin 0 -> 16596 bytes .../projects/creator-projects-autotools.qdoc | 77 +++ doc/src/projects/creator-projects-cmake.qdoc | 2 +- .../projects/creator-projects-generic.qdoc | 2 +- doc/src/qtcreator.qdoc | 1 + .../generic-highlighter/autoconf.xml | 390 +++++++++++++ .../AutotoolsProject.mimetypes.xml | 8 + .../AutotoolsProjectManager.pluginspec.in | 23 + .../autotoolsprojectmanager/autogenstep.cpp | 305 ++++++++++ .../autotoolsprojectmanager/autogenstep.h | 162 ++++++ .../autoreconfstep.cpp | 299 ++++++++++ .../autotoolsprojectmanager/autoreconfstep.h | 163 ++++++ .../autotoolsbuildconfiguration.cpp | 260 +++++++++ .../autotoolsbuildconfiguration.h | 94 +++ .../autotoolsbuildsettingswidget.cpp | 139 +++++ .../autotoolsbuildsettingswidget.h | 88 +++ .../autotoolsmanager.cpp | 83 +++ .../autotoolsmanager.h | 65 +++ .../autotoolsopenprojectwizard.cpp | 121 ++++ .../autotoolsopenprojectwizard.h | 87 +++ .../autotoolsproject.cpp | 542 ++++++++++++++++++ .../autotoolsproject.h | 183 ++++++ .../autotoolsproject.qrc | 5 + .../autotoolsprojectconstants.h | 58 ++ .../autotoolsprojectfile.cpp | 109 ++++ .../autotoolsprojectfile.h | 82 +++ .../autotoolsprojectmanager.pro | 39 ++ .../autotoolsprojectmanager_dependencies.pri | 3 + .../autotoolsprojectnode.cpp | 123 ++++ .../autotoolsprojectnode.h | 93 +++ .../autotoolsprojectplugin.cpp | 85 +++ .../autotoolsprojectplugin.h | 84 +++ .../autotoolstarget.cpp | 186 ++++++ .../autotoolsprojectmanager/autotoolstarget.h | 101 ++++ .../autotoolsprojectmanager/configurestep.cpp | 303 ++++++++++ .../autotoolsprojectmanager/configurestep.h | 162 ++++++ .../makefileparser.cpp | 454 +++++++++++++++ .../autotoolsprojectmanager/makefileparser.h | 231 ++++++++ .../makefileparserthread.cpp | 112 ++++ .../makefileparserthread.h | 136 +++++ .../autotoolsprojectmanager/makestep.cpp | 326 +++++++++++ .../autotoolsprojectmanager/makestep.h | 163 ++++++ .../genericprojectwizard.cpp | 2 +- src/plugins/plugins.pro | 6 + 45 files changed, 5954 insertions(+), 3 deletions(-) create mode 100644 doc/images/qtcreator-autotools-buildrun.png create mode 100644 doc/images/qtcreator-autotools-buildsettings.png create mode 100644 doc/src/projects/creator-projects-autotools.qdoc create mode 100644 share/qtcreator/generic-highlighter/autoconf.xml create mode 100644 src/plugins/autotoolsprojectmanager/AutotoolsProject.mimetypes.xml create mode 100644 src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in create mode 100644 src/plugins/autotoolsprojectmanager/autogenstep.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autogenstep.h create mode 100644 src/plugins/autotoolsprojectmanager/autoreconfstep.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autoreconfstep.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsbuildsettingswidget.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsmanager.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsmanager.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsproject.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsproject.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsproject.qrc create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectfile.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectfile.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectmanager_dependencies.pri create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectnode.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectnode.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h create mode 100644 src/plugins/autotoolsprojectmanager/autotoolstarget.cpp create mode 100644 src/plugins/autotoolsprojectmanager/autotoolstarget.h create mode 100644 src/plugins/autotoolsprojectmanager/configurestep.cpp create mode 100644 src/plugins/autotoolsprojectmanager/configurestep.h create mode 100644 src/plugins/autotoolsprojectmanager/makefileparser.cpp create mode 100644 src/plugins/autotoolsprojectmanager/makefileparser.h create mode 100644 src/plugins/autotoolsprojectmanager/makefileparserthread.cpp create mode 100644 src/plugins/autotoolsprojectmanager/makefileparserthread.h create mode 100644 src/plugins/autotoolsprojectmanager/makestep.cpp create mode 100644 src/plugins/autotoolsprojectmanager/makestep.h diff --git a/doc/images/qtcreator-autotools-buildrun.png b/doc/images/qtcreator-autotools-buildrun.png new file mode 100644 index 0000000000000000000000000000000000000000..05ef57900b4abeed597f4f6ab62f5719dcb78823 GIT binary patch literal 25725 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%0A3LRhQ% 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 literal 0 HcmV?d00001 diff --git a/doc/images/qtcreator-autotools-buildsettings.png b/doc/images/qtcreator-autotools-buildsettings.png new file mode 100644 index 0000000000000000000000000000000000000000..d82b4c591f4911b6f6e580e1b8578ca51c6068ab GIT binary patch literal 16596 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 literal 0 HcmV?d00001 diff --git a/doc/src/projects/creator-projects-autotools.qdoc b/doc/src/projects/creator-projects-autotools.qdoc new file mode 100644 index 00000000000..449a7aa52ba --- /dev/null +++ b/doc/src/projects/creator-projects-autotools.qdoc @@ -0,0 +1,77 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010-2011 Openismus GmbH. +** Authors: Peter Penz (ppenz@openismus.com) +** Patricia Santana Cruz (patriciasc@openismus.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. +** +**************************************************************************/ + +/*! + \contentspage index.html + \previouspage creator-project-cmake.html + \page creator-projects-autotools.html + \nextpage creator-project-generic.html + + \title Setting Up an Autotools Project + The AutotoolsProjectManager is a plugin for autotools support. + + \image qtcreator-autotools-buildrun.png + + \image qtcreator-autotools-buildsettings.png + + \section1 Opening and Using Autotools Projects + + To work with your Autotools project in \QC: + + \list 1 + + \o Select \gui{File > Open File or Project}. + \o Select the Makefile.am from your project. This is the only way a + user can use the autotools plugin. Thus, a Makefile.am must + always exist before hand. + \o Select the build directory. Only in-source building is working + right now. + \o Select \gui Finish. + \QC displays the project tree structure. The root node displays + the project name. All project files are listed below it and you + can open them from the list. + \o Select \gui Run to build and run the application. This will + execute autogen.sh or autoreconf, configure and make. The first + time, when running the application, a dialog will ask you to + choose the executable's location, then, \QC will remember it for + the following times. Ideally, this will be changed in the future, + to be done in a more automated way. + \o To check and edit autotools build steps, select + \gui{Projects > Build Settings}. You can see the typical + autotools build steps: autogen.sh/autoreconf, configure and make. + You may configure some parameters such as adding new configure + parameters or changing the build directory (though, as mentiond + before, only in-source building is working at the moment). + \endlist +*/ diff --git a/doc/src/projects/creator-projects-cmake.qdoc b/doc/src/projects/creator-projects-cmake.qdoc index 2dd7ff90f30..a1471be9c57 100644 --- a/doc/src/projects/creator-projects-cmake.qdoc +++ b/doc/src/projects/creator-projects-cmake.qdoc @@ -29,7 +29,7 @@ \contentspage index.html \previouspage creator-project-wizards.html \page creator-project-cmake.html - \nextpage creator-project-generic.html + \nextpage creator-projects-autotools.html \title Setting Up a CMake Project diff --git a/doc/src/projects/creator-projects-generic.qdoc b/doc/src/projects/creator-projects-generic.qdoc index 671e4248b2f..51fd14dee1e 100644 --- a/doc/src/projects/creator-projects-generic.qdoc +++ b/doc/src/projects/creator-projects-generic.qdoc @@ -27,7 +27,7 @@ /*! \contentspage index.html - \previouspage creator-project-cmake.html + \previouspage creator-projects-autotools.html \page creator-project-generic.html \nextpage creator-version-control.html diff --git a/doc/src/qtcreator.qdoc b/doc/src/qtcreator.qdoc index 1b1f250dece..84f7ede9dbf 100644 --- a/doc/src/qtcreator.qdoc +++ b/doc/src/qtcreator.qdoc @@ -163,6 +163,7 @@ \o \l{Supported Platforms} \o \l{Adding New Custom Wizards} \o \l{Setting Up a CMake Project} + \o \l{Setting Up an Autotools Project} \o \l{Setting Up a Generic Project} \o \l{Using Version Control Systems} \o \l{Adding Qt Designer Plugins} diff --git a/share/qtcreator/generic-highlighter/autoconf.xml b/share/qtcreator/generic-highlighter/autoconf.xml new file mode 100644 index 00000000000..36498527a25 --- /dev/null +++ b/share/qtcreator/generic-highlighter/autoconf.xml @@ -0,0 +1,390 @@ + + + + + + + + if + then + elif + else + fi + for + in + do + don + function + select + until + while + set + ifelse + case + esac + + + + + : + source + alias + bg + bind + break + builtin + cd + caller + command + compgen + complete + continue + dirs + disown + echo + enable + eval + exec + exit + fc + fg + getopts + hash + help + history + jobs + kill + let + logout + popd + printf + pushd + pwd + return + set + shift + shopt + suspend + test + time + times + trap + type + ulimit + umask + unalias + wait + + + + no + yes + false + true + + + + + AS_BOURNE_COMPATIBLE + AS_BOX + AS_CASE + AS_DIRNAME + AS_ECHO + AS_ECHO_N + AS_ESCAPE + AS_EXIT + AS_HELP_STRING + AS_IF + AS_INIT + AS_INIT_GENERATED + AS_LINENO_PREPARE + AS_LITERAL_IF + AS_LITERAL_WORD_IF + AS_ME_PREPARE + AS_MESSAGE_FD + AS_MESSAGE_LOG_FD + AS_MKDIR_P + AS_ORIGINAL_STDIN_FD + AS_SET_CATFILE + AS_SET_STATUS + AS_SHELL_SANITIZE + AS_TMPDIR + AS_TR_CPP + AS_TR_SH + AS_UNSET + AS_VAR_APPEND + AS_VAR_ARITH + AS_VAR_COPY + AS_VAR_IF + AS_VAR_POPDEF + AS_VAR_PUSHDEF + AS_VAR_SET + AS_VAR_SET_IF + AS_VAR_TEST_SET + AS_VERSION_COMPARE + m4_append + m4_append_uniq + m4_append_uniq_w + m4_apply + m4_argn + m4_assert + m4_bmatch + m4_bpatsubst + m4_bpatsubsts + m4_bregexp + m4_builtin + m4_car + m4_case + m4_cdr + m4_changecom + m4_changequote + m4_chomp + m4_chomp_all + m4_cleardivert + m4_cmp + m4_combine + m4_cond + m4_copy + m4_copy_force + m4_count + m4_curry + m4_debugfile + m4_debugmode + m4_decr + m4_default + m4_default_nblank + m4_default_nblank_quoted + m4_default_quoted + m4_define + m4_define_default + m4_defn + m4_divert + m4_divert_once + m4_divert_pop + m4_divert_push + m4_divert_text + m4_divnum + m4_do + m4_dquote + m4_dquote_elt + m4_dumpdef + m4_dumpdefs + m4_echo + m4_errprint + m4_errprintn + m4_escape + m4_esyscmd + m4_esyscmd_s + m4_eval + m4_exit + m4_expand + m4_fatal + m4_flatten + m4_for + m4_foreach + m4_foreach_w + m4_format + m4_if + m4_ifblank + m4_ifdef + m4_ifnblank + m4_ifndef + m4_ifset + m4_ifval + m4_ifvaln + m4_ignore + m4_include + m4_incr + m4_index + m4_indir + m4_init + m4_join + m4_joinall + m4_len + m4_list_cmp + m4_location + m4_make_list + m4_maketemp + m4_map + m4_map_args + m4_map_args_pair + m4_map_args_sep + m4_map_args_w + m4_map_sep + m4_mapall + m4_mapall_sep + m4_max + m4_min + m4_mkstemp + m4_n + m4_newline + m4_normalize + m4_pattern_allow + m4_pattern_forbid + m4_popdef + m4_pushdef + m4_quote + m4_re_escape + m4_rename + m4_rename_force + m4_reverse + m4_set_add + m4_set_add_all + m4_set_contains + m4_set_contents + m4_set_delete + m4_set_difference + m4_set_dump + m4_set_empty + m4_set_foreach + m4_set_intersection + m4_set_list + m4_set_listc + m4_set_map + m4_set_map_sep + m4_set_remove + m4_set_size + m4_set_union + m4_shift + m4_shift2 + m4_shift3 + m4_shiftn + m4_sign + m4_sinclude + m4_split + m4_stack_foreach + m4_stack_foreach_lifo + m4_stack_foreach_sep + m4_stack_foreach_sep_lifo + m4_strip + m4_substr + m4_syscmd + m4_sysval + m4_text_box + m4_text_wrap + m4_tolower + m4_toupper + m4_traceoff + m4_traceon + m4_translit + m4_undefine + m4_undivert + m4_unquote + m4_version_compare + m4_version_prereq + m4_warn + m4_wrap + m4_wrap_lifo + + + + + AT_ARG_OPTION + AT_ARG_OPTION_ARG + AT_BANNER + AT_CAPTURE_FILE + AT_CHECK + AT_CHECK_EUNIT + AT_CHECK_UNQUOTED + AT_CLEANUP + AT_COLOR_TESTS + AT_COPYRIGHT + AT_DATA + AT_FAIL_IF + AT_INIT + AT_KEYWORDS + AT_PACKAGE_BUGREPORT + AT_PACKAGE_NAME + AT_PACKAGE_STRING + AT_PACKAGE_TARNAME + AT_PACKAGE_URL + AT_PACKAGE_VERSION + AT_SETUP + AT_SKIP_IF + AT_TESTED + AT_XFAIL_IF + + + + LT_PREREQ + LT_LANG + LT_INIT + LTDL_INIT + LT_CONFIG_LTDL_DIR + + + + PKG_CHECK_MODULES + PKG_PROG_PKG_CONFIG + PKG_CHECK_EXISTS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plugins/autotoolsprojectmanager/AutotoolsProject.mimetypes.xml b/src/plugins/autotoolsprojectmanager/AutotoolsProject.mimetypes.xml new file mode 100644 index 00000000000..6e32748d2cf --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/AutotoolsProject.mimetypes.xml @@ -0,0 +1,8 @@ + + + + + Automake based Makefile + + + diff --git a/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in b/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in new file mode 100644 index 00000000000..31bd06076a6 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/AutotoolsProjectManager.pluginspec.in @@ -0,0 +1,23 @@ + + Openismus GmbH + (C) 2010 Openismus GmbH + 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. + Build Systems + Autotools project integration. + http://qt.nokia.com + + + + + + diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.cpp b/src/plugins/autotoolsprojectmanager/autogenstep.cpp new file mode 100644 index 00000000000..f5144e8d9c2 --- /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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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(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(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 &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 00000000000..4fa05902115 --- /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 + +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 &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 00000000000..2769ec50e50 --- /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 +#include +#include +#include +#include +#include + +#include +#include +#include + +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(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(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 &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 00000000000..bafe0df6a03 --- /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 +#include + +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 &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 00000000000..80f7ba3ab04 --- /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 +#include +#include +#include +#include + +#include + +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(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(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(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(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(source); + AutotoolsTarget *target(static_cast(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(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 00000000000..9889a1c6772 --- /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 + +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 00000000000..7d05b051e63 --- /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 +#include + +#include +#include +#include +#include +#include +#include + +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(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(m_toolChainChooser->itemData(index).value()); + m_target->autotoolsProject()->setToolChain(tc); +} + +void AutotoolsBuildSettingsWidget::toolChainChanged(ProjectExplorer::ToolChain *tc) +{ + for (int i = 0; i < m_toolChainChooser->count(); ++i) { + ToolChain * currentTc = static_cast(m_toolChainChooser->itemData(i).value()); + if (currentTc != tc) + continue; + m_toolChainChooser->setCurrentIndex(i); + return; + } +} + +void AutotoolsBuildSettingsWidget::updateToolChainList() +{ + m_toolChainChooser->clear(); + + QList tcs = ToolChainManager::instance()->toolChains(); + if (!m_target->autotoolsProject()->toolChain()) { + m_toolChainChooser->addItem(tr(""), qVariantFromValue(static_cast(0))); + m_toolChainChooser->setCurrentIndex(0); + } + foreach (ToolChain *tc, tcs) { + m_toolChainChooser->addItem(tc->displayName(), qVariantFromValue(static_cast(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 00000000000..6fc3be08ade --- /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 +#include +#include +#include +#include + +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 00000000000..474fb6997e3 --- /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 +#include +#include +#include +#include +#include + +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 00000000000..2f9aaa6d1ef --- /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 + +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 00000000000..d53a42acc97 --- /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 +#include +#include +#include + +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 00000000000..5a1056a723e --- /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 +#include + +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 00000000000..7a1a514d8ee --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +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(Project::activeTarget()); +} + +QList AutotoolsProject::dependsOn() +{ + return QList(); +} + +QString AutotoolsProject::defaultBuildDirectory() const +{ + return sourceDirectory(); +} + +QList AutotoolsProject::subConfigWidgets() +{ + QList 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(); + 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 wizard = new AutotoolsOpenProjectWizard(m_manager, sourceDirectory()); + if (!wizard->exec() == QDialog::Accepted) + return false; + + AutotoolsBuildConfiguration *bc = + static_cast(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 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 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 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(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::const_iterator it = nodeHash.constBegin(); + while (it != nodeHash.constEnd()) { + if ((*it)->nodeType() == ProjectExplorer::FileNodeType) { + ProjectExplorer::FileNode* fileNode = static_cast(*it); + ProjectExplorer::FolderNode* parent = fileNode->parentFolderNode(); + m_rootNode->removeFileNodes(QList() << fileNode, parent); + + // Remove all empty parent folders + while (parent->subFolderNodes().isEmpty() && parent->fileNodes().isEmpty()) { + ProjectExplorer::FolderNode* grandParent = parent->parentFolderNode(); + m_rootNode->removeFolderNodes(QList() << parent, grandParent); + parent = grandParent; + if (parent == m_rootNode) + break; + } + } + ++it; + } +} + +ProjectExplorer::FolderNode* AutotoolsProject::insertFolderNode(const QDir &nodeDir, + QHash &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(nodes[parentDir]); + } + } + + m_rootNode->addFolderNodes(QList() << folder, parentFolder); + nodes.insert(nodePath, folder); + + return folder; +} + +QList AutotoolsProject::nodes(ProjectExplorer::FolderNode *parent) const +{ + QList 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 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 00000000000..e84c56c9923 --- /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 +#include +#include +#include +#include +#include + +#include +#include + +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 subConfigWidgets(); + ProjectExplorer::ProjectNode *rootProjectNode() const; + QStringList files(FilesMode fileMode) const; + QList 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 &nodes); + + /** + * @return All nodes (including sub-folder- and file-nodes) for the given parent folder. + */ + QList 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 00000000000..514790e9be5 --- /dev/null +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.qrc @@ -0,0 +1,5 @@ + + + AutotoolsProject.mimetypes.xml + + diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h new file mode 100644 index 00000000000..cbc442ec601 --- /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 00000000000..cdbb2b13ff7 --- /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 00000000000..9bf70aa1ad5 --- /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 + +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 00000000000..b642847aa7c --- /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 00000000000..614357cd4d5 --- /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 00000000000..52feb0368dd --- /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 AutotoolsProjectNode::supportedActions(Node *node) const +{ + Q_UNUSED(node); + return QList(); +} + +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 AutotoolsProjectNode::runConfigurationsFor(Node *node) +{ + Q_UNUSED(node); + return QList(); +} diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectnode.h new file mode 100644 index 00000000000..a615ce86bd1 --- /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 +#include + +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 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 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 00000000000..2e53addffcd --- /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 +#include + +#include +#include + +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 00000000000..2b5e15c4350 --- /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 + +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 00000000000..1c32bec871a --- /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 +#include +#include +#include + +#include +#include + +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(project()); +} + +AutotoolsBuildConfiguration *AutotoolsTarget::activeBuildConfiguration() const +{ + return static_cast(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(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(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(parent)); + AutotoolsTarget *t = new AutotoolsTarget(project); + + // Add default build configuration: + AutotoolsBuildConfigurationFactory *bcf = ExtensionSystem::PluginManager::instance()->getObject(); + 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(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 00000000000..6ac9481af8a --- /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 + +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 00000000000..80037bb0a6e --- /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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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(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(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& 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 00000000000..ffc5aea17ca --- /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 + +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 &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 00000000000..a9db927ee48 --- /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 + +#include +#include +#include + +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 00000000000..ede6bfe45cd --- /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 +#include +#include +#include +#include +#include +#include + +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 00000000000..eee5c718dc9 --- /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 + +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 00000000000..4815dc392b7 --- /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 + +#include +#include +#include + +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 00000000000..2cafcc82d36 --- /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 +#include +#include +#include +#include +#include + +#include +#include +#include + +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(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(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 &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("Unknown tool chain"); + } + + emit updateSummary(); +} diff --git a/src/plugins/autotoolsprojectmanager/makestep.h b/src/plugins/autotoolsprojectmanager/makestep.h new file mode 100644 index 00000000000..af849ff8709 --- /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 + +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 &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 00b961d8fe4..dfabed3b36b 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 b1eff599b78..419f1f2f5db 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