aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/generators
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@qt.io>2016-08-11 18:16:53 -0700
committerJake Petroules <jake.petroules@qt.io>2016-08-22 15:12:35 +0000
commit323a52542f4e1a670f838082e1d88f0fdbf155da (patch)
treefbaffc53986b182690272ccb6fa895a5afa7220d /src/lib/corelib/generators
parentb44df152e922cead8510ccc6f94e0c35db284012 (diff)
Flesh out generators API
This puts in place some of the infrastructure needed by subsequent commits that will introduce the Visual Studio and Xcode generators. Change-Id: Ic8f127acef5c26e26edb7083ebd423848d81a6ff Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/lib/corelib/generators')
-rw-r--r--src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.cpp6
-rw-r--r--src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.h2
-rw-r--r--src/lib/corelib/generators/generatableprojectiterator.cpp80
-rw-r--r--src/lib/corelib/generators/generatableprojectiterator.h54
-rw-r--r--src/lib/corelib/generators/generator.cpp219
-rw-r--r--src/lib/corelib/generators/generator.h86
-rw-r--r--src/lib/corelib/generators/generatordata.cpp127
-rw-r--r--src/lib/corelib/generators/generatordata.h71
-rw-r--r--src/lib/corelib/generators/generators.pri10
-rw-r--r--src/lib/corelib/generators/igeneratableprojectvisitor.h97
10 files changed, 684 insertions, 68 deletions
diff --git a/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.cpp b/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.cpp
index b4b249732..89c6e7e3b 100644
--- a/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.cpp
+++ b/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.cpp
@@ -58,11 +58,9 @@ QString ClangCompilationDatabaseGenerator::generatorName() const
return QStringLiteral("clangdb");
}
-void ClangCompilationDatabaseGenerator::generate(const InstallOptions &installOptions)
+void ClangCompilationDatabaseGenerator::generate()
{
- Q_UNUSED(installOptions);
-
- for (const Project &project : projects()) {
+ for (const Project &project : project().projects.values()) {
QJsonArray database;
const ProjectData projectData = project.projectData();
const QString buildDir = projectData.buildDirectory();
diff --git a/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.h b/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.h
index 7281e4211..7708b81ea 100644
--- a/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.h
+++ b/src/lib/corelib/generators/clangcompilationdb/clangcompilationdbgenerator.h
@@ -45,7 +45,7 @@ public:
private:
QString generatorName() const override;
- void generate(const InstallOptions &installOptions) override;
+ void generate() override;
static const QString DefaultDatabaseFileName;
QJsonObject createEntry(const QString &filePath, const QString &buildDir,
const RuleCommand &ruleCommand);
diff --git a/src/lib/corelib/generators/generatableprojectiterator.cpp b/src/lib/corelib/generators/generatableprojectiterator.cpp
new file mode 100644
index 000000000..26a45f098
--- /dev/null
+++ b/src/lib/corelib/generators/generatableprojectiterator.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "generatableprojectiterator.h"
+
+namespace qbs {
+
+GeneratableProjectIterator::GeneratableProjectIterator(const GeneratableProject &project)
+ : project(project)
+{
+}
+
+void GeneratableProjectIterator::accept(IGeneratableProjectVisitor *visitor)
+{
+ visitor->visitProject(project);
+ QMapIterator<QString, qbs::Project> it(project.projects);
+ while (it.hasNext()) {
+ it.next();
+ visitor->visitProject(it.value(), it.key());
+ }
+
+ accept(project, GeneratableProjectData(), project, visitor);
+}
+
+void GeneratableProjectIterator::accept(const GeneratableProject &project,
+ const GeneratableProjectData &parentProjectData,
+ const GeneratableProjectData &projectData,
+ IGeneratableProjectVisitor *visitor)
+{
+ visitor->visitProjectData(project, parentProjectData, projectData);
+ visitor->visitProjectData(project, projectData);
+ QMapIterator<QString, qbs::ProjectData> it(projectData.data);
+ while (it.hasNext()) {
+ it.next();
+ visitor->visitProjectData(parentProjectData.data.value(it.key()), it.value(), it.key());
+ visitor->visitProjectData(it.value(), it.key());
+ }
+
+ for (const auto &subProject : projectData.subProjects) {
+ accept(project, projectData, subProject, visitor);
+ }
+
+ for (const auto &productDataMap : projectData.products) {
+ visitor->visitProduct(project, projectData, productDataMap);
+ QMapIterator<QString, qbs::ProductData> it(productDataMap.data);
+ while (it.hasNext()) {
+ it.next();
+ visitor->visitProduct(it.value(), it.key());
+ }
+ }
+}
+
+} // namespace qbs
diff --git a/src/lib/corelib/generators/generatableprojectiterator.h b/src/lib/corelib/generators/generatableprojectiterator.h
new file mode 100644
index 000000000..85e3cab6f
--- /dev/null
+++ b/src/lib/corelib/generators/generatableprojectiterator.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef GENERATABLEPROJECTITERATOR_H
+#define GENERATABLEPROJECTITERATOR_H
+
+#include "generatordata.h"
+#include "igeneratableprojectvisitor.h"
+
+namespace qbs {
+
+class GeneratableProjectIterator {
+ GeneratableProject project;
+
+public:
+ GeneratableProjectIterator(const GeneratableProject &project);
+ void accept(IGeneratableProjectVisitor *visitor);
+
+private:
+ void accept(const GeneratableProject &project, const GeneratableProjectData &parentProjectData,
+ const GeneratableProjectData &projectData,
+ IGeneratableProjectVisitor *visitor);
+};
+
+} // namespace qbs
+
+#endif // GENERATABLEPROJECTITERATOR_H
diff --git a/src/lib/corelib/generators/generator.cpp b/src/lib/corelib/generators/generator.cpp
new file mode 100644
index 000000000..93d78ea50
--- /dev/null
+++ b/src/lib/corelib/generators/generator.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "generator.h"
+#include <tools/error.h>
+#include <tools/hostosinfo.h>
+#include <tools/installoptions.h>
+#include <tools/qbsassert.h>
+#include <QCoreApplication>
+
+namespace qbs {
+
+class ProjectGeneratorPrivate {
+public:
+ QList<Project> projects;
+ QList<QVariantMap> buildConfigurations;
+ InstallOptions installOptions;
+};
+
+ProjectGenerator::ProjectGenerator()
+ : d(new ProjectGeneratorPrivate)
+{
+}
+
+ProjectGenerator::~ProjectGenerator()
+{
+ delete d;
+}
+
+static QString _configurationName(const qbs::Project &project)
+{
+ return project.projectConfiguration()
+ .value(QStringLiteral("qbs")).toMap()
+ .value(QStringLiteral("configurationName")).toString();
+}
+
+static QString _configurationName(const QVariantMap &buildConfiguration)
+{
+ return buildConfiguration.value(QStringLiteral("qbs.configurationName")).toString();
+}
+
+void ProjectGenerator::generate(const QList<Project> &projects,
+ const QList<QVariantMap> &buildConfigurations,
+ const InstallOptions &installOptions)
+{
+ d->projects = projects;
+ std::sort(d->projects.begin(), d->projects.end(),
+ [](const qbs::Project &a, const qbs::Project &b) {
+ return _configurationName(a) < _configurationName(b); });
+ d->buildConfigurations = buildConfigurations;
+ std::sort(d->buildConfigurations.begin(), d->buildConfigurations.end(),
+ [](const QVariantMap &a, const QVariantMap &b) {
+ return _configurationName(a) < _configurationName(b); });
+ d->installOptions = installOptions;
+ generate();
+}
+
+QList<Project> ProjectGenerator::projects() const
+{
+ return d->projects;
+}
+
+QList<QVariantMap> ProjectGenerator::buildConfigurations() const
+{
+ return d->buildConfigurations;
+}
+
+QVariantMap ProjectGenerator::buildConfiguration(const Project &project) const
+{
+ int idx = d->projects.indexOf(project);
+ if (idx < 0)
+ return QVariantMap();
+ return d->buildConfigurations.at(idx);
+}
+
+QStringList ProjectGenerator::buildConfigurationCommandLine(const Project &project) const
+{
+ QVariantMap config = buildConfiguration(project);
+
+ const QString name = config.take(QStringLiteral("qbs.configurationName")).toString();
+ if (name.isEmpty())
+ throw qbs::ErrorInfo(QStringLiteral("Can't find configuration name for project"));
+
+ QStringList commandLineParameters;
+ commandLineParameters += name;
+
+ QMapIterator<QString, QVariant> it(config);
+ while (it.hasNext()) {
+ it.next();
+ commandLineParameters += it.key() + QStringLiteral(":") + it.value().toString();
+ }
+
+ return commandLineParameters;
+}
+
+// Count the number of products in the project (singular)
+// Precondition: each project data (i.e. per-configuration project data)
+// has the same number of products.
+static int _productCount(const QList<qbs::ProjectData> &projects)
+{
+ int count = -1;
+ for (const auto &project : projects) {
+ int oldCount = count;
+ count = project.products().size();
+ QBS_CHECK(oldCount == -1 || oldCount == count);
+ }
+ return count;
+}
+
+static int _subprojectCount(const QList<qbs::ProjectData> &projects)
+{
+ int count = -1;
+ for (const auto &project : projects) {
+ int oldCount = count;
+ count = project.subProjects().size();
+ QBS_CHECK(oldCount == -1 || oldCount == count);
+ }
+ return count;
+}
+
+static GeneratableProjectData _reduceProjectConfigurations(
+ const QMap<QString, qbs::ProjectData> &map) {
+ GeneratableProjectData gproject;
+
+ // Add the project's project data for each configuration
+ QMapIterator<QString, qbs::ProjectData> it(map);
+ while (it.hasNext()) {
+ it.next();
+ gproject.data.insert(it.key(), it.value());
+ }
+
+ // Add the project's products...
+ for (int i = 0; i < _productCount(map.values()); ++i) {
+ GeneratableProductData prod;
+
+ // once for each configuration
+ QMapIterator<QString, qbs::ProjectData> it(map);
+ while (it.hasNext()) {
+ it.next();
+ prod.data.insert(it.key(), it.value().products().at(i));
+ }
+
+ gproject.products.append(prod);
+ }
+
+ // Add the project's subprojects...
+ for (int i = 0; i < _subprojectCount(map.values()); ++i) {
+ QMap<QString, qbs::ProjectData> subprojectMap;
+
+ // once for each configuration
+ QMapIterator<QString, qbs::ProjectData> it(map);
+ while (it.hasNext()) {
+ it.next();
+ subprojectMap.insert(it.key(), it.value().subProjects().at(i));
+ }
+
+ gproject.subProjects.append(_reduceProjectConfigurations(subprojectMap));
+ }
+
+ return gproject;
+}
+
+const GeneratableProject ProjectGenerator::project() const
+{
+ QMap<QString, qbs::ProjectData> rootProjects;
+ GeneratableProject proj;
+ for (const auto &project : projects()) {
+ const QString configurationName = _configurationName(project);
+ rootProjects.insert(configurationName, project.projectData());
+ proj.projects.insert(configurationName, project);
+ proj.buildConfigurations.insert(configurationName, buildConfiguration(project));
+ proj.commandLines.insert(configurationName, buildConfigurationCommandLine(project));
+ }
+ auto p = _reduceProjectConfigurations(rootProjects);
+ proj.data = p.data;
+ proj.products = p.products;
+ proj.subProjects = p.subProjects;
+ proj.installRoot = d->installOptions.installRoot();
+ return proj;
+}
+
+QFileInfo ProjectGenerator::qbsExecutableFilePath() const
+{
+ const QString qbsInstallDir = QString::fromLocal8Bit(qgetenv("QBS_INSTALL_DIR"));
+ auto file = QFileInfo(Internal::HostOsInfo::appendExecutableSuffix(!qbsInstallDir.isEmpty()
+ ? qbsInstallDir + QLatin1String("/bin/qbs")
+ : QCoreApplication::applicationDirPath() + QLatin1String("/qbs")));
+ QBS_CHECK(file.isAbsolute() && file.exists());
+ return file;
+}
+
+} // namespace qbs
diff --git a/src/lib/corelib/generators/generator.h b/src/lib/corelib/generators/generator.h
index a98bab1c2..18d2d9c0e 100644
--- a/src/lib/corelib/generators/generator.h
+++ b/src/lib/corelib/generators/generator.h
@@ -32,90 +32,52 @@
#ifndef GENERATORPLUGIN_H
#define GENERATORPLUGIN_H
-#include <api/project.h>
+#include "generatordata.h"
#include <QList>
#include <QString>
namespace qbs {
+class ProjectGeneratorPrivate;
+
/*!
* \class ProjectGenerator
* \brief The \c ProjectGenerator class is an abstract base class for generators which generate
* arbitrary output given a resolved Qbs project.
*/
-
-class ProjectGenerator
+class QBS_EXPORT ProjectGenerator : public QObject
{
+ Q_OBJECT
+ Q_DISABLE_COPY(ProjectGenerator)
public:
- virtual ~ProjectGenerator()
- {
- }
+ virtual ~ProjectGenerator();
/*!
* Returns the name of the generator used to create the external build system files.
*/
virtual QString generatorName() const = 0;
- virtual void generate(const InstallOptions &installOptions) = 0;
-
- QList<Project> projects() const
- {
- return m_projects;
- }
-
- void addProject(const Project &project)
- {
- m_projects << project;
- }
-
- void addProjects(const QList<Project> &projects)
- {
- m_projects << projects;
- }
-
- void removeProject(const Project &project)
- {
- m_projects.removeOne(project);
- }
-
- void clearProjects()
- {
- m_projects.clear();
- }
-
- QList<QVariantMap> buildConfigurations() const
- {
- return m_buildConfigurations;
- }
-
- void addBuildConfiguration(const QVariantMap &configuration)
- {
- m_buildConfigurations << configuration;
- }
-
- void addBuildConfigurations(const QList<QVariantMap> &configurations)
- {
- m_buildConfigurations << configurations;
- }
-
- void removeBuildConfiguration(const QVariantMap &configuration)
- {
- m_buildConfigurations.removeOne(configuration);
- }
-
- void clearBuildConfigurations()
- {
- m_buildConfigurations.clear();
- }
+ virtual void generate() = 0;
+
+ void generate(const QList<Project> &projects,
+ const QList<QVariantMap> &buildConfigurations,
+ const InstallOptions &installOptions);
+
+ const GeneratableProject project() const;
+ QFileInfo qbsExecutableFilePath() const;
+
+private:
+ QList<Project> projects() const;
+ QList<QVariantMap> buildConfigurations() const;
+ QVariantMap buildConfiguration(const Project &project) const;
+
+ QStringList buildConfigurationCommandLine(const Project &project) const;
protected:
- ProjectGenerator()
- {
- }
+ ProjectGenerator();
private:
- QList<Project> m_projects;
- QList<QVariantMap> m_buildConfigurations;
+ ProjectGeneratorPrivate *d;
};
} // namespace qbs
diff --git a/src/lib/corelib/generators/generatordata.cpp b/src/lib/corelib/generators/generatordata.cpp
new file mode 100644
index 000000000..0f578c642
--- /dev/null
+++ b/src/lib/corelib/generators/generatordata.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "generatordata.h"
+#include <tools/error.h>
+
+#include <QDir>
+
+namespace qbs {
+
+QString GeneratableProductData::name() const
+{
+ QString name;
+ QMapIterator<QString, qbs::ProductData> it(data);
+ while (it.hasNext()) {
+ it.next();
+ QString oldName = name;
+ name = it.value().name();
+ if (!oldName.isEmpty() && oldName != name)
+ throw qbs::ErrorInfo(QStringLiteral("Products with different names per-configuration "
+ "are not compatible with this generator. Consider "
+ "using the targetName property instead."));
+ }
+ return name;
+}
+
+QStringList GeneratableProductData::dependencies() const
+{
+ QStringList list;
+ QMapIterator<QString, qbs::ProductData> it(data);
+ while (it.hasNext()) {
+ it.next();
+ QStringList oldList = list;
+ list = it.value().dependencies();
+ if (!oldList.isEmpty() && oldList != list)
+ throw qbs::ErrorInfo(QStringLiteral("Products with different dependency lists "
+ "per-configuration are not compatible with this "
+ "generator."));
+ }
+ return list;
+}
+
+QString GeneratableProjectData::name() const
+{
+ QString name;
+ QMapIterator<QString, qbs::ProjectData> it(data);
+ while (it.hasNext()) {
+ it.next();
+ QString oldName = name;
+ name = it.value().name();
+ if (!oldName.isEmpty() && oldName != name)
+ throw qbs::ErrorInfo(QStringLiteral("Projects with different names per-configuration "
+ "are not compatible with this generator."));
+ }
+ return name;
+}
+
+QDir GeneratableProject::baseBuildDirectory() const
+{
+ QSet<QString> baseBuildDirectory;
+ QMapIterator<QString, qbs::ProjectData> it(data);
+ while (it.hasNext()) {
+ it.next();
+ QDir dir(it.value().buildDirectory());
+ dir.cdUp();
+ baseBuildDirectory.insert(dir.absolutePath());
+ }
+ Q_ASSERT(baseBuildDirectory.size() == 1);
+ return baseBuildDirectory.values().first();
+}
+
+QFileInfo GeneratableProject::filePath() const
+{
+ QSet<QString> filePath;
+ QMapIterator<QString, qbs::ProjectData> it(data);
+ while (it.hasNext()) {
+ it.next();
+ filePath.insert(it.value().location().filePath());
+ }
+ Q_ASSERT(filePath.size() == 1);
+ return filePath.values().first();
+}
+
+bool GeneratableProject::hasMultipleConfigurations() const
+{
+ return projects.size() > 1;
+}
+
+QStringList GeneratableProject::commandLine() const
+{
+ QStringList combinedCommandLine;
+ QMapIterator<QString, QStringList> it(commandLines);
+ while (it.hasNext()) {
+ it.next();
+ combinedCommandLine << it.value();
+ }
+ return combinedCommandLine;
+}
+
+} // namespace qbs
diff --git a/src/lib/corelib/generators/generatordata.h b/src/lib/corelib/generators/generatordata.h
new file mode 100644
index 000000000..2d394751b
--- /dev/null
+++ b/src/lib/corelib/generators/generatordata.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef GENERATORDATA_H
+#define GENERATORDATA_H
+
+#include <QDir>
+#include <QMap>
+#include <api/project.h>
+#include <api/projectdata.h>
+
+namespace qbs {
+
+typedef QMap<QString, qbs::Project> GeneratableProjectMap;
+typedef QMap<QString, qbs::ProjectData> GeneratableProjectDataMap;
+typedef QMap<QString, qbs::ProductData> GeneratableProductDataMap;
+
+struct GeneratableProductData {
+ GeneratableProductDataMap data;
+ QString name() const;
+ QStringList dependencies() const;
+};
+
+struct GeneratableProjectData {
+ GeneratableProjectDataMap data;
+ QList<GeneratableProjectData> subProjects;
+ QList<GeneratableProductData> products;
+ QString name() const;
+};
+
+struct GeneratableProject : public GeneratableProjectData {
+ GeneratableProjectMap projects;
+ QMap<QString, QVariantMap> buildConfigurations;
+ QMap<QString, QStringList> commandLines;
+ QString installRoot;
+ QDir baseBuildDirectory() const;
+ QFileInfo filePath() const;
+ bool hasMultipleConfigurations() const;
+ QStringList commandLine() const;
+};
+
+} // namespace qbs
+
+#endif // GENERATORDATA_H
diff --git a/src/lib/corelib/generators/generators.pri b/src/lib/corelib/generators/generators.pri
index fa1e26ea9..b59b0592a 100644
--- a/src/lib/corelib/generators/generators.pri
+++ b/src/lib/corelib/generators/generators.pri
@@ -1,4 +1,12 @@
+SOURCES += \
+ $$PWD/generatableprojectiterator.cpp \
+ $$PWD/generator.cpp \
+ $$PWD/generatordata.cpp
+
HEADERS += \
- $$PWD/generator.h
+ $$PWD/generatableprojectiterator.h \
+ $$PWD/generator.h \
+ $$PWD/generatordata.h \
+ $$PWD/igeneratableprojectvisitor.h
include(clangcompilationdb/clangcompilationdb.pri)
diff --git a/src/lib/corelib/generators/igeneratableprojectvisitor.h b/src/lib/corelib/generators/igeneratableprojectvisitor.h
new file mode 100644
index 000000000..d805d878f
--- /dev/null
+++ b/src/lib/corelib/generators/igeneratableprojectvisitor.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef IGENERATABLEPROJECTVISITOR_H
+#define IGENERATABLEPROJECTVISITOR_H
+
+#include "generatordata.h"
+
+namespace qbs {
+
+class IGeneratableProjectVisitor {
+public:
+ // Collapsed configurations
+ virtual void visitProject(const GeneratableProject &project) {
+ Q_UNUSED(project);
+ }
+
+ virtual void visitProjectData(const GeneratableProject &project,
+ const GeneratableProjectData &parentProjectData,
+ const GeneratableProjectData &projectData) {
+ Q_UNUSED(project);
+ Q_UNUSED(parentProjectData);
+ Q_UNUSED(projectData);
+ }
+
+ virtual void visitProjectData(const GeneratableProject &project,
+ const GeneratableProjectData &projectData) {
+ Q_UNUSED(project);
+ Q_UNUSED(projectData);
+ }
+
+ virtual void visitProduct(const GeneratableProject &project,
+ const GeneratableProjectData &projectData,
+ const GeneratableProductData &productData) {
+ Q_UNUSED(project);
+ Q_UNUSED(projectData);
+ Q_UNUSED(productData);
+ }
+
+ // Expanded configurations
+ virtual void visitProject(const qbs::Project &project,
+ const QString &configuration) {
+ Q_UNUSED(project);
+ Q_UNUSED(configuration);
+ }
+
+ virtual void visitProjectData(const qbs::ProjectData &parentProjectData,
+ const qbs::ProjectData &projectData,
+ const QString &configuration) {
+ Q_UNUSED(parentProjectData);
+ Q_UNUSED(projectData);
+ Q_UNUSED(configuration);
+ }
+
+ virtual void visitProjectData(const qbs::ProjectData &projectData,
+ const QString &configuration) {
+ Q_UNUSED(projectData);
+ Q_UNUSED(configuration);
+ }
+
+ virtual void visitProduct(const qbs::ProductData &productData,
+ const QString &configuration) {
+ Q_UNUSED(productData);
+ Q_UNUSED(configuration);
+ }
+};
+
+} // namespace qbs
+
+#endif // IGENERATABLEPROJECTVISITOR_H