diff options
Diffstat (limited to 'src/lib/corelib/tools/setupprojectparameters.cpp')
-rw-r--r-- | src/lib/corelib/tools/setupprojectparameters.cpp | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/src/lib/corelib/tools/setupprojectparameters.cpp b/src/lib/corelib/tools/setupprojectparameters.cpp new file mode 100644 index 000000000..c3b00f3c4 --- /dev/null +++ b/src/lib/corelib/tools/setupprojectparameters.cpp @@ -0,0 +1,434 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "setupprojectparameters.h" + +#include <logging/translator.h> +#include <tools/profile.h> +#include <tools/qbsassert.h> +#include <tools/scripttools.h> +#include <tools/settings.h> + +namespace qbs { +namespace Internal { + +/*! + * \class SetupProjectParameters + * \brief The \c SetupProjectParameters class comprises data required to set up a qbs project. + */ + +class SetupProjectParametersPrivate : public QSharedData +{ +public: + SetupProjectParametersPrivate() + : ignoreDifferentProjectFilePath(false) + , dryRun(false) + , logElapsedTime(false) + , restoreBehavior(SetupProjectParameters::RestoreAndTrackChanges) + , environment(QProcessEnvironment::systemEnvironment()) + { + } + + QString projectFilePath; + QString buildRoot; + QStringList searchPaths; + QStringList pluginPaths; + QVariantMap overriddenValues; + QVariantMap buildConfiguration; + mutable QVariantMap overriddenValuesTree; + mutable QVariantMap buildConfigurationTree; + mutable QVariantMap finalBuildConfigtree; + bool ignoreDifferentProjectFilePath; + bool dryRun; + bool logElapsedTime; + SetupProjectParameters::RestoreBehavior restoreBehavior; + QProcessEnvironment environment; +}; + +} // namespace Internal + +SetupProjectParameters::SetupProjectParameters() : d(new Internal::SetupProjectParametersPrivate) +{ +} + +SetupProjectParameters::SetupProjectParameters(const SetupProjectParameters &other) : d(other.d) +{ +} + +SetupProjectParameters::~SetupProjectParameters() +{ +} + +SetupProjectParameters &SetupProjectParameters::operator=(const SetupProjectParameters &other) +{ + d = other.d; + return *this; +} + +/*! + * \brief Returns the absolute path to the qbs project file. + * This file typically has a ".qbs" suffix. + */ +QString SetupProjectParameters::projectFilePath() const +{ + return d->projectFilePath; +} + +/*! + * \brief Sets the path to the main project file. + * \note The argument must be an absolute file path. + */ +void SetupProjectParameters::setProjectFilePath(const QString &projectFilePath) +{ + d->projectFilePath = projectFilePath; +} + +/*! + * \brief Returns the base path of where to put the build artifacts and store the build graph. + */ +QString SetupProjectParameters::buildRoot() const +{ + return d->buildRoot; +} + +/*! + * \brief Sets the base path of where to put the build artifacts and store the build graph. + * The same base path can be used for several build profiles of the same project without them + * interfering with each other. + * It might look as if this parameter would not be needed at the time of setting up the project, + * but keep in mind that the project information could already exist on disk, in which case + * loading it will be much faster than setting up the project from scratch. + * \note The argument must be an absolute path to a directory. + */ +void SetupProjectParameters::setBuildRoot(const QString &buildRoot) +{ + d->buildRoot = buildRoot; +} + +/*! + * \brief Where to look for modules and items to import. + */ +QStringList SetupProjectParameters::searchPaths() const +{ + return d->searchPaths; +} + +/*! + * \brief Sets the information about where to look for modules and items to import. + * \note The elements of the list must be absolute paths to directories. + */ +void SetupProjectParameters::setSearchPaths(const QStringList &searchPaths) +{ + d->searchPaths = searchPaths; +} + +/*! + * \brief Where to look for plugins. + */ +QStringList SetupProjectParameters::pluginPaths() const +{ + return d->pluginPaths; +} + +/*! + * \brief Sets the information about where to look for plugins. + * \note The elements of the list must be absolute paths to directories. + */ +void SetupProjectParameters::setPluginPaths(const QStringList &pluginPaths) +{ + d->pluginPaths = pluginPaths; +} + +/*! + * Returns the overridden values of the build configuration. + */ +QVariantMap SetupProjectParameters::overriddenValues() const +{ + return d->overriddenValues; +} + +/*! + * Set the overridden values of the build configuration. + */ +void SetupProjectParameters::setOverriddenValues(const QVariantMap &values) +{ + // warn if somebody tries to set a build configuration tree: + for (QVariantMap::const_iterator i = values.constBegin(); + i != values.constEnd(); ++i) { + QBS_ASSERT(i.value().type() != QVariant::Map, return); + } + d->overriddenValues = values; + d->overriddenValuesTree.clear(); + d->finalBuildConfigtree.clear(); +} + +static void provideValuesTree(const QVariantMap &values, QVariantMap *valueTree) +{ + if (!valueTree->isEmpty() || values.isEmpty()) + return; + + valueTree->clear(); + for (QVariantMap::const_iterator it = values.constBegin(); it != values.constEnd(); ++it) { + QStringList nameElements = it.key().split(QLatin1Char('.')); + if (nameElements.count() > 2) { // ### workaround for submodules being represented internally as a single module of name "module/submodule" rather than two nested modules "module" and "submodule" + const QString last = nameElements.takeLast(); + nameElements = QStringList(nameElements.join(QLatin1String("/"))); + nameElements.append(last); + } + Internal::setConfigProperty(*valueTree, nameElements, it.value()); + } +} + +QVariantMap SetupProjectParameters::overriddenValuesTree() const +{ + provideValuesTree(d->overriddenValues, &d->overriddenValuesTree); + return d->overriddenValuesTree; +} + +/*! + * \brief The collection of properties to use for resolving the project. + */ +QVariantMap SetupProjectParameters::buildConfiguration() const +{ + return d->buildConfiguration; +} + +/*! + * Sets the collection of properties to use for resolving the project. + * + * Keys are expected to be in dotted syntax (e.g. Qt.declarative.qmlDebugging) that is + * used by "qbs config". + */ +void SetupProjectParameters::setBuildConfiguration(const QVariantMap &buildConfiguration) +{ + // warn if somebody tries to set a build configuration tree: + for (QVariantMap::const_iterator i = buildConfiguration.constBegin(); + i != buildConfiguration.constEnd(); ++i) { + QBS_ASSERT(i.value().type() != QVariant::Map, return); + } + d->buildConfiguration = buildConfiguration; + d->buildConfigurationTree.clear(); + d->finalBuildConfigtree.clear(); +} + +/*! + * \brief Returns the build configuration in tree form. + * \return the tree form of the build configuration. + */ +QVariantMap SetupProjectParameters::buildConfigurationTree() const +{ + provideValuesTree(d->buildConfiguration, &d->buildConfigurationTree); + return d->buildConfigurationTree; +} + +/*! + * \brief Expands the build configuration based on the given settings. + * + * Expansion is the process by which the build configuration is completed based on the given + * settings. E.g. the information configured in a profile is filled into the build + * configuration by this step. + * + * This method returns an Error. The list of entries in this error will be empty is the + * expansion was successful. + */ +ErrorInfo SetupProjectParameters::expandBuildConfiguration(Settings *settings) +{ + ErrorInfo err; + + // Generates a full build configuration from user input, using the settings. + QVariantMap expandedConfig = d->buildConfiguration; + + const QString buildVariant = expandedConfig.value(QLatin1String("qbs.buildVariant")).toString(); + if (buildVariant.isEmpty()) + return ErrorInfo(Internal::Tr::tr("No build variant set.")); + if (buildVariant != QLatin1String("debug") && buildVariant != QLatin1String("release")) { + err.append(Internal::Tr::tr("Invalid build variant '%1'. Must be 'debug' or 'release'.") + .arg(buildVariant)); + return err; + } + + // Fill in buildCfg in this order (making sure not to overwrite a key already set by a previous stage) + // 1) Things specified on command line (already in buildCfg at this point) + // 2) Everything from the profile key + QString profileName = expandedConfig.value("qbs.profile").toString(); + if (profileName.isNull()) { + profileName = settings->defaultProfile(); + if (profileName.isNull()) { + const QString profileNames = settings->profiles().join(QLatin1String(", ")); + err.append(Internal::Tr::tr("No profile given and no default profile set.\n" + "Either set the configuration value 'defaultProfile' to a " + "valid profile name\n" + "or specify the profile with the command line parameter " + "'profile:name'.\n" + "The following profiles are available:\n%1") + .arg(profileNames)); + return err; + } + expandedConfig.insert("qbs.profile", profileName); + } + + // (2) + const Profile profile(profileName, settings); + const QStringList profileKeys = profile.allKeys(Profile::KeySelectionRecursive); + if (profileKeys.isEmpty()) { + err.append(Internal::Tr::tr("Unknown or empty profile '%1'.").arg(profileName)); + return err; + } + foreach (const QString &profileKey, profileKeys) { + if (!expandedConfig.contains(profileKey)) + expandedConfig.insert(profileKey, profile.value(profileKey)); + } + + if (d->buildConfiguration != expandedConfig) { + d->buildConfigurationTree.clear(); + d->buildConfiguration = expandedConfig; + } + return err; +} + +/*! + * \brief Returns the build configuration in tree form, with overridden values taken into account. + */ +QVariantMap SetupProjectParameters::finalBuildConfigurationTree() const +{ + if (d->finalBuildConfigtree.isEmpty()) { + QVariantMap finalMap = d->buildConfiguration; + for (QVariantMap::ConstIterator it = d->overriddenValues.constBegin(); + it != d->overriddenValues.constEnd(); ++it) { + finalMap.insert(it.key(), it.value()); + } + provideValuesTree(finalMap, &d->finalBuildConfigtree); + } + return d->finalBuildConfigtree; +} + +/*! + * \variable SetupProjectParameters::ignoreDifferentProjectFilePath + * \brief Returns true iff the saved build graph should be used even if its path to the + * project file is different from \c SetupProjectParameters::projectFilePath() + */ +bool SetupProjectParameters::ignoreDifferentProjectFilePath() const +{ + return d->ignoreDifferentProjectFilePath; +} + +/*! + * \brief Controls whether the path to the main project file may be different from the one + * stored in a possible build graph file. + * The default is false. + */ +void SetupProjectParameters::setIgnoreDifferentProjectFilePath(bool doIgnore) +{ + d->ignoreDifferentProjectFilePath = doIgnore; +} + + /*! + * \brief if true, qbs will not store the build graph of the resolved project. + */ +bool SetupProjectParameters::dryRun() const +{ + return d->dryRun; +} + + /*! + * \brief Controls whether the build graph will be stored. + * If the argument is true, qbs will not store the build graph after resolving the project. + * The default is false. + */ +void SetupProjectParameters::setDryRun(bool dryRun) +{ + d->dryRun = dryRun; +} + + /*! + * \brief Returns true iff the time the operation takes should be logged + */ +bool SetupProjectParameters::logElapsedTime() const +{ + return d->logElapsedTime; +} + +/*! + * Controls whether to log the time taken up for resolving the project. + * The default is false. + */ +void SetupProjectParameters::setLogElapsedTime(bool logElapsedTime) +{ + d->logElapsedTime = logElapsedTime; +} + +/*! + * \brief Gets the environment used while resolving the project. + */ +QProcessEnvironment SetupProjectParameters::environment() const +{ + return d->environment; +} + +/*! + * \brief Sets the environment used while resolving the project. + */ +void SetupProjectParameters::setEnvironment(const QProcessEnvironment &env) +{ + d->environment = env; +} + + +/*! + * \enum SetupProjectParamaters::RestoreBehavior + * This enum type specifies how to deal with existing on-disk build information. + * \value RestoreOnly Indicates that a stored build graph is to be loaded and the information + * therein assumed to be up to date. It is then considered an error if no + * such build graph exists. + * \value ResolveOnly Indicates that no attempt should be made to restore an existing build graph. + * Instead, the project is to be resolved from scratch. + * \value RestoreAndTrackChanges Indicates that the build graph should be restored from disk + * if possible and otherwise set up from scratch. In the first case, + * (parts of) the project might still be re-resolved if certain + * parameters have changed (e.g. environment variables used in the + * project files). + */ + + +/*! + * Returns information about how restored build data will be handled. + */ +SetupProjectParameters::RestoreBehavior SetupProjectParameters::restoreBehavior() const +{ + return d->restoreBehavior; +} + +/*! + * Controls how restored build data will be handled. + */ +void SetupProjectParameters::setRestoreBehavior(SetupProjectParameters::RestoreBehavior behavior) +{ + d->restoreBehavior = behavior; +} + +} // namespace qbs |