diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2013-06-06 10:06:30 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2013-06-17 14:23:19 +0200 |
commit | ab60f6e4c489ace089785c002d75018ac6a31e30 (patch) | |
tree | 91053ec752d9aa56df8061ba5e62c13431804a6b /src/lib/api | |
parent | d3877c67d060d454ac66fde7b6ad41a2bb50d808 (diff) |
Allow projects to be nested.
This is nice to have for grouping products and
a requirement for aggregating existing projects
into a bigger one.
Change-Id: I3394642e95ea57dbc6bf1603cfed6902a5906e4c
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'src/lib/api')
-rw-r--r-- | src/lib/api/internaljobs.cpp | 23 | ||||
-rw-r--r-- | src/lib/api/internaljobs.h | 20 | ||||
-rw-r--r-- | src/lib/api/jobs.cpp | 9 | ||||
-rw-r--r-- | src/lib/api/jobs.h | 8 | ||||
-rw-r--r-- | src/lib/api/project.cpp | 63 | ||||
-rw-r--r-- | src/lib/api/project.h | 2 | ||||
-rw-r--r-- | src/lib/api/projectdata.cpp | 51 | ||||
-rw-r--r-- | src/lib/api/projectdata.h | 5 | ||||
-rw-r--r-- | src/lib/api/projectdata_p.h | 3 |
9 files changed, 132 insertions, 52 deletions
diff --git a/src/lib/api/internaljobs.cpp b/src/lib/api/internaljobs.cpp index 946a87fa6..2f67243d3 100644 --- a/src/lib/api/internaljobs.cpp +++ b/src/lib/api/internaljobs.cpp @@ -119,7 +119,7 @@ void InternalJob::cancel() m_observer->cancel(); } -void InternalJob::storeBuildGraph(const ResolvedProjectConstPtr &project) +void InternalJob::storeBuildGraph(const TopLevelProjectConstPtr &project) { try { project->store(logger()); @@ -154,7 +154,7 @@ void InternalSetupProjectJob::reportError(const Error &error) Q_ARG(Internal::InternalJob *, this)); } -ResolvedProjectPtr InternalSetupProjectJob::project() const +TopLevelProjectPtr InternalSetupProjectJob::project() const { return m_project; } @@ -201,10 +201,6 @@ void InternalSetupProjectJob::execute() loader.setProgressObserver(observer()); m_project = loader.loadProject(m_parameters); } - if (m_project->products.isEmpty()) { - throw Error(Tr::tr("Project '%1' does not contain products.") - .arg(m_parameters.projectFilePath())); - } } // copy the environment from the platform config into the project's config @@ -216,7 +212,7 @@ void InternalSetupProjectJob::execute() foreach (const ResolvedProductConstPtr &p, m_project->products) { logger().qbsDebug() << QString::fromLocal8Bit(" - [%1] %2 as %3") .arg(p->fileTags.toStringList().join(QLatin1String(", "))) - .arg(p->name).arg(p->project->id()); + .arg(p->name).arg(p->topLevelProject()->id()); } logger().qbsDebug() << '\n'; @@ -244,7 +240,7 @@ BuildGraphTouchingJob::~BuildGraphTouchingJob() { } -void BuildGraphTouchingJob::setup(const ResolvedProjectPtr &project, +void BuildGraphTouchingJob::setup(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, bool dryRun) { m_project = project; @@ -263,7 +259,7 @@ InternalBuildJob::InternalBuildJob(const Logger &logger, QObject *parent) { } -void InternalBuildJob::build(const ResolvedProjectPtr &project, +void InternalBuildJob::build(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, const BuildOptions &buildOptions) { setup(project, products, buildOptions.dryRun()); @@ -308,7 +304,7 @@ InternalCleanJob::InternalCleanJob(const Logger &logger, QObject *parent) { } -void InternalCleanJob::clean(const ResolvedProjectPtr &project, +void InternalCleanJob::clean(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, const CleanOptions &options) { setup(project, products, options.dryRun()); @@ -350,9 +346,10 @@ InternalInstallJob::~InternalInstallJob() { } -void InternalInstallJob::install(const QList<ResolvedProductPtr> &products, - const InstallOptions &options) +void InternalInstallJob::install(const TopLevelProjectPtr &project, + const QList<ResolvedProductPtr> &products, const InstallOptions &options) { + m_project = project; m_products = products; m_options = options; setTimed(options.logElapsedTime()); @@ -374,7 +371,7 @@ void InternalInstallJob::start() void InternalInstallJob::doInstall() { try { - ProductInstaller(m_products, m_options, observer(), logger()).install(); + ProductInstaller(m_project, m_products, m_options, observer(), logger()).install(); } catch (const Error &error) { setError(error); } diff --git a/src/lib/api/internaljobs.h b/src/lib/api/internaljobs.h index b94403fcb..37b2f607d 100644 --- a/src/lib/api/internaljobs.h +++ b/src/lib/api/internaljobs.h @@ -68,7 +68,7 @@ protected: JobObserver *observer() const { return m_observer; } void setError(const Error &error) { m_error = error; } void setTimed(bool timed) { m_timed = timed; } - void storeBuildGraph(const ResolvedProjectConstPtr &project); + void storeBuildGraph(const TopLevelProjectConstPtr &project); signals: void finished(Internal::InternalJob *job); @@ -94,7 +94,7 @@ public: void resolve(const SetupProjectParameters ¶meters); void reportError(const Error &error); - ResolvedProjectPtr project() const; + TopLevelProjectPtr project() const; private slots: void start(); @@ -108,7 +108,7 @@ private: QMutex m_runMutex; QWaitCondition m_runWaitCondition; - ResolvedProjectPtr m_project; + TopLevelProjectPtr m_project; SetupProjectParameters m_parameters; }; @@ -118,7 +118,7 @@ class BuildGraphTouchingJob : public InternalJob Q_OBJECT public: const QList<ResolvedProductPtr> &products() const { return m_products; } - const ResolvedProjectPtr &project() const { return m_project; } + const TopLevelProjectPtr &project() const { return m_project; } signals: void reportCommandDescription(const QString &highlight, const QString &message); @@ -128,12 +128,12 @@ protected: BuildGraphTouchingJob(const Logger &logger, QObject *parent = 0); ~BuildGraphTouchingJob(); - void setup(const ResolvedProjectPtr &project, const QList<ResolvedProductPtr> &products, + void setup(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, bool dryRun); void storeBuildGraph(); private: - ResolvedProjectPtr m_project; + TopLevelProjectPtr m_project; QList<ResolvedProductPtr> m_products; bool m_dryRun; }; @@ -145,7 +145,7 @@ class InternalBuildJob : public BuildGraphTouchingJob public: InternalBuildJob(const Logger &logger, QObject *parent = 0); - void build(const ResolvedProjectPtr &project, const QList<ResolvedProductPtr> &products, + void build(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, const BuildOptions &buildOptions); private slots: @@ -163,7 +163,7 @@ class InternalCleanJob : public BuildGraphTouchingJob public: InternalCleanJob(const Logger &logger, QObject *parent = 0); - void clean(const ResolvedProjectPtr &project, const QList<ResolvedProductPtr> &products, + void clean(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, const CleanOptions &options); private slots: @@ -185,7 +185,8 @@ public: InternalInstallJob(const Logger &logger, QObject *parent = 0); ~InternalInstallJob(); - void install(const QList<ResolvedProductPtr> &products, const InstallOptions &options); + void install(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, + const InstallOptions &options); private slots: void handleFinished(); @@ -195,6 +196,7 @@ private: void doInstall(); private: + TopLevelProjectPtr m_project; QList<ResolvedProductPtr> m_products; InstallOptions m_options; }; diff --git a/src/lib/api/jobs.cpp b/src/lib/api/jobs.cpp index a344cc5c0..47bda7191 100644 --- a/src/lib/api/jobs.cpp +++ b/src/lib/api/jobs.cpp @@ -242,7 +242,7 @@ BuildJob::BuildJob(const Logger &logger, QObject *parent) this, SIGNAL(reportProcessResult(qbs::ProcessResult))); } -void BuildJob::build(const ResolvedProjectPtr &project, const QList<ResolvedProductPtr> &products, +void BuildJob::build(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, const BuildOptions &options) { qobject_cast<InternalBuildJob *>(internalJob())->build(project, products, options); @@ -259,7 +259,7 @@ CleanJob::CleanJob(const Logger &logger, QObject *parent) { } -void CleanJob::clean(const ResolvedProjectPtr &project, const QList<ResolvedProductPtr> &products, +void CleanJob::clean(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products, const qbs::CleanOptions &options) { qobject_cast<InternalCleanJob *>(internalJob())->clean(project, products, options); @@ -275,9 +275,10 @@ InstallJob::InstallJob(const Logger &logger, QObject *parent) { } -void InstallJob::install(const QList<ResolvedProductPtr> &products, const InstallOptions &options) +void InstallJob::install(const TopLevelProjectPtr &project, + const QList<ResolvedProductPtr> &products, const InstallOptions &options) { - qobject_cast<InternalInstallJob *>(internalJob())->install(products, options); + qobject_cast<InternalInstallJob *>(internalJob())->install(project, products, options); } } // namespace qbs diff --git a/src/lib/api/jobs.h b/src/lib/api/jobs.h index 19d4f8dcb..791ad2af7 100644 --- a/src/lib/api/jobs.h +++ b/src/lib/api/jobs.h @@ -113,7 +113,7 @@ signals: private: BuildJob(const Internal::Logger &logger, QObject *parent); - void build(const Internal::ResolvedProjectPtr &project, + void build(const Internal::TopLevelProjectPtr &project, const QList<qbs::Internal::ResolvedProductPtr> &products, const BuildOptions &options); }; @@ -127,7 +127,7 @@ class QBS_EXPORT CleanJob : public AbstractJob private: CleanJob(const Internal::Logger &logger, QObject *parent); - void clean(const Internal::ResolvedProjectPtr &project, + void clean(const Internal::TopLevelProjectPtr &project, const QList<Internal::ResolvedProductPtr> &products, const CleanOptions &options); }; @@ -138,8 +138,8 @@ class QBS_EXPORT InstallJob : public AbstractJob private: InstallJob(const Internal::Logger &logger, QObject *parent); - void install(const QList<Internal::ResolvedProductPtr> &products, - const InstallOptions &options); + void install(const Internal::TopLevelProjectPtr &project, + const QList<Internal::ResolvedProductPtr> &products, const InstallOptions &options); }; } // namespace qbs diff --git a/src/lib/api/project.cpp b/src/lib/api/project.cpp index f9744d648..dca2104d8 100644 --- a/src/lib/api/project.cpp +++ b/src/lib/api/project.cpp @@ -91,7 +91,7 @@ static void loadPlugins(const QStringList &_pluginPaths, const Logger &logger) class ProjectPrivate : public QSharedData { public: - ProjectPrivate(const ResolvedProjectPtr &internalProject, const Logger &logger) + ProjectPrivate(const TopLevelProjectPtr &internalProject, const Logger &logger) : internalProject(internalProject), logger(logger), m_projectDataRetrieved(false) { } @@ -109,11 +109,12 @@ public: QList<ResolvedProductPtr> allEnabledInternalProducts() const; ResolvedProductPtr internalProduct(const ProductData &product) const; - const ResolvedProjectPtr internalProject; + const TopLevelProjectPtr internalProject; Logger logger; private: - void retrieveProjectData(); + void retrieveProjectData(ProjectData &projectData, + const ResolvedProjectConstPtr &internalProject); ProjectData m_projectData; bool m_projectDataRetrieved; @@ -121,8 +122,11 @@ private: ProjectData ProjectPrivate::projectData() { - if (!m_projectDataRetrieved) - retrieveProjectData(); + if (!m_projectDataRetrieved) { + retrieveProjectData(m_projectData, internalProject); + m_projectData.d->buildDir = internalProject->buildDirectory; + m_projectDataRetrieved = true; + } return m_projectData; } @@ -165,7 +169,7 @@ InstallJob *ProjectPrivate::installProducts(const QList<ResolvedProductPtr> &pro if (needsDepencencyResolving) addDependencies(productsToInstall); InstallJob * const job = new InstallJob(logger, jobOwner); - job->install(productsToInstall, options); + job->install(internalProject, productsToInstall, options); return job; } @@ -179,30 +183,49 @@ QList<ResolvedProductPtr> ProjectPrivate::internalProducts(const QList<ProductDa return internalProducts; } -QList<ResolvedProductPtr> ProjectPrivate::allEnabledInternalProducts() const +static QList<ResolvedProductPtr> enabledInternalProducts(const ResolvedProjectConstPtr &project) { QList<ResolvedProductPtr> products; - foreach (const ResolvedProductPtr &p, internalProject->products) { + foreach (const ResolvedProductPtr &p, project->products) { if (p->enabled) products << p; } + foreach (const ResolvedProjectConstPtr &subProject, project->subProjects) + products << enabledInternalProducts(subProject); return products; } -ResolvedProductPtr ProjectPrivate::internalProduct(const ProductData &product) const +QList<ResolvedProductPtr> ProjectPrivate::allEnabledInternalProducts() const +{ + return enabledInternalProducts(internalProject); +} + +static ResolvedProductPtr internalProductForProject(const ResolvedProjectConstPtr &project, + const ProductData &product) { - foreach (const ResolvedProductPtr &resolvedProduct, internalProject->products) { + foreach (const ResolvedProductPtr &resolvedProduct, project->products) { if (product.name() == resolvedProduct->name) return resolvedProduct; } - qFatal("No build product '%s'", qPrintable(product.name())); + foreach (const ResolvedProjectConstPtr &subProject, project->subProjects) { + const ResolvedProductPtr &p = internalProductForProject(subProject, product); + if (p) + return p; + } return ResolvedProductPtr(); } -void ProjectPrivate::retrieveProjectData() +ResolvedProductPtr ProjectPrivate::internalProduct(const ProductData &product) const +{ + return internalProductForProject(internalProject, product); +} + +void ProjectPrivate::retrieveProjectData(ProjectData &projectData, + const ResolvedProjectConstPtr &internalProject) { - m_projectData.d->location = internalProject->location; - m_projectData.d->buildDir = internalProject->buildDirectory; + projectData.d->name = internalProject->name; + projectData.d->location = internalProject->location; + projectData.d->enabled = internalProject->enabled; foreach (const ResolvedProductConstPtr &resolvedProduct, internalProject->products) { ProductData product; product.d->name = resolvedProduct->name; @@ -227,9 +250,15 @@ void ProjectPrivate::retrieveProjectData() product.d->groups << group; } qSort(product.d->groups); - m_projectData.d->products << product; + projectData.d->products << product; + } + foreach (const ResolvedProjectConstPtr &internalSubProject, internalProject->subProjects) { + ProjectData subProject; + retrieveProjectData(subProject, internalSubProject); + projectData.d->subProjects << subProject; } - qSort(m_projectData.d->products); + qSort(projectData.d->products); + qSort(projectData.d->subProjects); m_projectDataRetrieved = true; } @@ -242,7 +271,7 @@ using namespace Internal; * \brief The \c Project class provides services related to a qbs project. */ -Project::Project(const ResolvedProjectPtr &internalProject, const Logger &logger) +Project::Project(const TopLevelProjectPtr &internalProject, const Logger &logger) : d(new ProjectPrivate(internalProject, logger)) { } diff --git a/src/lib/api/project.h b/src/lib/api/project.h index 099b82d9a..48c3fd71b 100644 --- a/src/lib/api/project.h +++ b/src/lib/api/project.h @@ -107,7 +107,7 @@ public: private: Project(); - Project(const Internal::ResolvedProjectPtr &internalProject, const Internal::Logger &logger); + Project(const Internal::TopLevelProjectPtr &internalProject, const Internal::Logger &logger); QExplicitlySharedDataPointer<Internal::ProjectPrivate> d; }; diff --git a/src/lib/api/projectdata.cpp b/src/lib/api/projectdata.cpp index 7b46f1829..9d48f5f2f 100644 --- a/src/lib/api/projectdata.cpp +++ b/src/lib/api/projectdata.cpp @@ -130,6 +130,11 @@ QStringList GroupData::allFilePaths() const return d->filePaths + d->expandedWildcards; } +bool operator!=(const GroupData &lhs, const GroupData &rhs) +{ + return !(lhs == rhs); +} + bool operator==(const GroupData &lhs, const GroupData &rhs) { return lhs.name() == rhs.name() @@ -140,9 +145,9 @@ bool operator==(const GroupData &lhs, const GroupData &rhs) && lhs.isEnabled() == rhs.isEnabled(); } -bool operator!=(const GroupData &lhs, const GroupData &rhs) +bool operator<(const GroupData &lhs, const GroupData &rhs) { - return !(lhs == rhs); + return lhs.name() < rhs.name(); } /*! @@ -237,7 +242,7 @@ bool operator!=(const ProductData &lhs, const ProductData &rhs) return !(lhs == rhs); } -bool operator<(const GroupData &lhs, const GroupData &rhs) +bool operator<(const ProductData &lhs, const ProductData &rhs) { return lhs.name() < rhs.name(); } @@ -271,6 +276,14 @@ ProjectData::~ProjectData() } /*! + * \brief The name of this project. + */ +QString ProjectData::name() const +{ + return d->name; +} + +/*! * \brief The location at which the project is defined in a qbs source file. */ CodeLocation ProjectData::location() const @@ -279,7 +292,17 @@ CodeLocation ProjectData::location() const } /*! + * \brief Whether the project is enabled. + * \note Disabled projects never have any products or sub-projects. + */ +bool ProjectData::isEnabled() const +{ + return d->enabled; +} + +/*! * \brief The base directory under which the build artifacts of this project will be created. + * This is only valid for the top-level project. */ QString ProjectData::buildDirectory() const { @@ -295,9 +318,29 @@ QList<ProductData> ProjectData::products() const return d->products; } +/*! + * The sub-projects of this project. + */ +QList<ProjectData> ProjectData::subProjects() const +{ + return d->subProjects; +} + +/*! + * All products in this projects and its direct and indirect sub-projects. + */ +QList<ProductData> ProjectData::allProducts() const +{ + QList<ProductData> productList = products(); + foreach (const ProjectData &pd, subProjects()) + productList << pd.allProducts(); + return productList; +} + bool operator==(const ProjectData &lhs, const ProjectData &rhs) { return lhs.location() == rhs.location() + && lhs.subProjects() == rhs.subProjects() && lhs.products() == rhs.products(); } @@ -306,7 +349,7 @@ bool operator!=(const ProjectData &lhs, const ProjectData &rhs) return !(lhs == rhs); } -bool operator<(const ProductData &lhs, const ProductData &rhs) +bool operator<(const ProjectData &lhs, const ProjectData &rhs) { return lhs.name() < rhs.name(); } diff --git a/src/lib/api/projectdata.h b/src/lib/api/projectdata.h index 1097c5e24..d7ae66b8f 100644 --- a/src/lib/api/projectdata.h +++ b/src/lib/api/projectdata.h @@ -139,9 +139,13 @@ public: ProjectData &operator=(const ProjectData &other); ~ProjectData(); + QString name() const; CodeLocation location() const; + bool isEnabled() const; QString buildDirectory() const; QList<ProductData> products() const; + QList<ProjectData> subProjects() const; + QList<ProductData> allProducts() const; private: QExplicitlySharedDataPointer<Internal::ProjectDataPrivate> d; @@ -149,6 +153,7 @@ private: QBS_EXPORT bool operator==(const ProjectData &lhs, const ProjectData &rhs); QBS_EXPORT bool operator!=(const ProjectData &lhs, const ProjectData &rhs); +QBS_EXPORT bool operator<(const ProjectData &lhs, const ProjectData &rhs); } // namespace qbs diff --git a/src/lib/api/projectdata_p.h b/src/lib/api/projectdata_p.h index c544dd9d9..14ed79efd 100644 --- a/src/lib/api/projectdata_p.h +++ b/src/lib/api/projectdata_p.h @@ -61,8 +61,11 @@ public: class ProjectDataPrivate : public QSharedData { public: + QString name; CodeLocation location; + bool enabled; QList<ProductData> products; + QList<ProjectData> subProjects; QString buildDir; }; |