diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2012-11-14 12:46:00 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2012-11-15 09:48:11 +0100 |
commit | c2f82cc551388af51029a7b4c1e8187b908e1c5a (patch) | |
tree | 36764aaee6f6d386ad632f8d5af28e6c68ff01ae | |
parent | 7137d6c3ae2b953ae42ffb06f22a7ce5327917b8 (diff) |
Move build root information out of BuildGraph.
With the current implementation, we would need to create a new QbsEngine
object for every project file.
Instead, attach a build directory to every ResolvedProject. Also remove
ResolvedProduct::buildDirectory, since it is the same for all products
in a project.
Along the way:
- Integrate BuildProject::restoreBuildGraph() into
BuildProject::loadProject(). The latter currently just forwards to the
former for no apparent reason.
- Remove some checks for things that can never happen.
- Remove unused metatype declaration for internal class.
Change-Id: Ib97b37ddfdc0f4f4334449f64cde1a33eda4316d
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r-- | src/app/qbs/main.cpp | 5 | ||||
-rw-r--r-- | src/lib/buildgraph/buildgraph.cpp | 95 | ||||
-rw-r--r-- | src/lib/buildgraph/buildgraph.h | 19 | ||||
-rw-r--r-- | src/lib/language/language.cpp | 7 | ||||
-rw-r--r-- | src/lib/language/language.h | 5 | ||||
-rw-r--r-- | src/lib/language/loader.cpp | 21 | ||||
-rw-r--r-- | src/lib/language/loader.h | 2 | ||||
-rw-r--r-- | src/lib/language/qbsengine.cpp | 27 | ||||
-rw-r--r-- | src/lib/language/qbsengine.h | 4 | ||||
-rw-r--r-- | src/lib/tools/persistence.cpp | 2 |
10 files changed, 68 insertions, 119 deletions
diff --git a/src/app/qbs/main.cpp b/src/app/qbs/main.cpp index 2f7513328..2c1a91a99 100644 --- a/src/app/qbs/main.cpp +++ b/src/app/qbs/main.cpp @@ -260,14 +260,13 @@ int main(int argc, char *argv[]) QList<Project::Id> projectIds; QbsEngine qbsEngine; - qbsEngine.setBuildRoot(QDir::currentPath()); if (parser.showProgress()) app.observer()->setShowProgress(true); qbsEngine.setProgressObserver(app.observer()); try { foreach (const QVariantMap &buildConfig, parser.buildConfigurations()) { - const Project::Id projectId - = qbsEngine.setupProject(parser.projectFileName(), buildConfig); + const Project::Id projectId = qbsEngine.setupProject(parser.projectFileName(), + buildConfig, QDir::currentPath()); projectIds << projectId; } } catch (const Error &error) { diff --git a/src/lib/buildgraph/buildgraph.cpp b/src/lib/buildgraph/buildgraph.cpp index b22bbde8e..0c82195ab 100644 --- a/src/lib/buildgraph/buildgraph.cpp +++ b/src/lib/buildgraph/buildgraph.cpp @@ -736,17 +736,6 @@ Artifact *BuildGraph::createArtifact(BuildProduct::Ptr product, SourceArtifact:: return artifact; } -QString BuildGraph::buildDirectory(const QString &projectId) const -{ - Q_ASSERT(!m_outputDirectoryRoot.isEmpty()); - return FileInfo::resolvePath(m_outputDirectoryRoot, projectId); -} - -QString BuildGraph::buildGraphFilePath(const QString &projectId) const -{ - return buildDirectory(projectId) + QLatin1Char('/') + projectId + QLatin1String(".bg"); -} - void Transformer::load(PersistentPool &pool) { rule = pool.idLoadS<Rule>(); @@ -879,50 +868,43 @@ static bool isConfigCompatible(const QVariantMap &userCfg, const QVariantMap &pr return true; } -void BuildProject::restoreBuildGraph(const QString &projectFilePath, BuildGraph *bg, - const FileTime &minTimeStamp, - const QVariantMap &cfg, - const QStringList &loaderSearchPaths, - LoadResult *loadResult) +BuildProject::LoadResult BuildProject::load(const QString &projectFilePath, BuildGraph *bg, + const QString &buildRoot, const QVariantMap &cfg, const QStringList &loaderSearchPaths) { + LoadResult result; + result.discardLoadedProject = false; const QString projectId = ResolvedProject::deriveId(cfg); - const QString buildGraphFilePath = bg->buildGraphFilePath(projectId); - if (buildGraphFilePath.isNull()) { - qbsDebug() << "[BG] No stored build graph found that's compatible to the desired build configuration."; - return; - } + const QString buildDir = ResolvedProject::deriveBuildDirectory(buildRoot, projectId); + const QString buildGraphFilePath = deriveBuildGraphFilePath(buildDir, projectId); PersistentPool pool; - BuildProject::Ptr project; qbsDebug() << "[BG] trying to load: " << buildGraphFilePath; if (!pool.load(buildGraphFilePath)) - return; + return result; if (!isConfigCompatible(cfg, pool.headData().projectConfig)) { qbsDebug() << "[BG] Cannot use stored build graph: Incompatible project configuration."; - return; + return result; } - FileInfo bgfi(buildGraphFilePath); - project = BuildProject::Ptr(new BuildProject(bg)); + const Ptr project = BuildProject::Ptr(new BuildProject(bg)); TimedActivityLogger loadLogger(QLatin1String("Loading build graph"), QLatin1String("[BG] ")); project->load(pool); foreach (const BuildProduct::Ptr &bp, project->buildProducts()) bp->project = project; project->resolvedProject()->qbsFile = projectFilePath; project->resolvedProject()->setBuildConfiguration(pool.headData().projectConfig); - loadResult->loadedProject = project; + project->resolvedProject()->buildDirectory = buildDir; + result.loadedProject = project; loadLogger.finishActivity(); - bool projectFileChanged = false; - if (bgfi.lastModified() < minTimeStamp) { - projectFileChanged = true; - } + const FileInfo bgfi(buildGraphFilePath); + const bool projectFileChanged = bgfi.lastModified() < FileInfo(projectFilePath).lastModified(); bool referencedProductRemoved = false; QList<BuildProduct::Ptr> changedProducts; foreach (BuildProduct::Ptr product, project->buildProducts()) { const ResolvedProduct::ConstPtr &resolvedProduct = product->rProduct; - FileInfo pfi(resolvedProduct->qbsFile); + const FileInfo pfi(resolvedProduct->qbsFile); if (!pfi.exists()) { referencedProductRemoved = true; } else if (bgfi.lastModified() < pfi.lastModified()) { @@ -945,17 +927,11 @@ void BuildProject::restoreBuildGraph(const QString &projectFilePath, BuildGraph } if (projectFileChanged || referencedProductRemoved || !changedProducts.isEmpty()) { - Loader ldr(bg->engine()); ldr.setSearchPaths(loaderSearchPaths); ProjectFile::Ptr projectFile = ldr.loadProject(project->resolvedProject()->qbsFile); - ResolvedProject::Ptr changedProject = ldr.resolveProject(projectFile, - bg->buildDirectory(projectId), cfg); - if (!changedProject) { - QString msg("Trying to load '%1' failed."); - throw Error(msg.arg(project->resolvedProject()->qbsFile)); - } - loadResult->changedResolvedProject = changedProject; + const ResolvedProject::Ptr changedProject = ldr.resolveProject(projectFile, buildRoot, cfg); + result.changedResolvedProject = changedProject; QMap<QString, ResolvedProduct::Ptr> changedProductsMap; foreach (BuildProduct::Ptr product, changedProducts) { @@ -965,9 +941,9 @@ void BuildProject::restoreBuildGraph(const QString &projectFilePath, BuildGraph ResolvedProduct::Ptr changedProduct = changedProductsMap.value(product->rProduct->name); if (!changedProduct) continue; - bg->onProductChanged(product, changedProduct, &loadResult->discardLoadedProject); - if (loadResult->discardLoadedProject) - return; + bg->onProductChanged(product, changedProduct, &result.discardLoadedProject); + if (result.discardLoadedProject) + return result; } QSet<QString> oldProductNames, newProductNames; @@ -977,8 +953,8 @@ void BuildProject::restoreBuildGraph(const QString &projectFilePath, BuildGraph newProductNames += product->name; QSet<QString> addedProductNames = newProductNames - oldProductNames; if (!addedProductNames.isEmpty()) { - loadResult->discardLoadedProject = true; - return; + result.discardLoadedProject = true; + return result; } QSet<QString> removedProductsNames = oldProductNames - newProductNames; if (!removedProductsNames.isEmpty()) { @@ -989,14 +965,7 @@ void BuildProject::restoreBuildGraph(const QString &projectFilePath, BuildGraph CycleDetector().visitProject(project); } -} -BuildProject::LoadResult BuildProject::load(const QString &projectFilePath, BuildGraph *bg, - const FileTime &minTimeStamp, const QVariantMap &cfg, const QStringList &loaderSearchPaths) -{ - LoadResult result; - result.discardLoadedProject = false; - restoreBuildGraph(projectFilePath, bg, minTimeStamp, cfg, loaderSearchPaths, &result); return result; } @@ -1006,7 +975,7 @@ void BuildProject::store() const qbsDebug() << "[BG] build graph is unchanged in project " << resolvedProject()->id() << "."; return; } - const QString fileName = buildGraph()->buildGraphFilePath(resolvedProject()->id()); + const QString fileName = buildGraphFilePath(); qbsDebug() << "[BG] storing: " << fileName; PersistentPool pool; PersistentPool::HeadData headData; @@ -1017,6 +986,16 @@ void BuildProject::store() const m_dirty = false; } +QString BuildProject::deriveBuildGraphFilePath(const QString &buildDir, const QString projectId) +{ + return buildDir + QLatin1Char('/') + projectId + QLatin1String(".bg"); +} + +QString BuildProject::buildGraphFilePath() const +{ + return deriveBuildGraphFilePath(resolvedProject()->buildDirectory, resolvedProject()->id()); +} + void BuildProject::load(PersistentPool &pool) { m_resolvedProject = pool.idLoadS<ResolvedProject>(); @@ -1197,10 +1176,10 @@ void BuildProject::setResolvedProject(const ResolvedProject::Ptr &resolvedProjec QString fileName(Artifact *n) { - class BuildGraph *bg = n->project->buildGraph(); + const QString &buildDir = n->project->resolvedProject()->buildDirectory; QString str = n->filePath(); - if (str.startsWith(bg->outputDirectoryRoot())) - str.remove(0, bg->outputDirectoryRoot().count()); + if (str.startsWith(buildDir)) + str.remove(0, buildDir.count()); if (str.startsWith('/')) str.remove(0, 1); return str; @@ -1358,7 +1337,7 @@ void RulesApplicator::setupScriptEngineForArtifact(Artifact *artifact) QDir sourceDir(m_buildProduct->rProduct->sourceDirectory); basedir = FileInfo::path(sourceDir.relativeFilePath(artifact->filePath())); } else { - QDir buildDir(m_buildProduct->project->buildGraph()->buildDirectory(m_buildProduct->project->resolvedProject()->id())); + QDir buildDir(m_buildProduct->project->resolvedProject()->buildDirectory); basedir = FileInfo::path(buildDir.relativeFilePath(artifact->filePath())); } @@ -1454,7 +1433,7 @@ Artifact *RulesApplicator::createOutputArtifact(const RuleArtifact::ConstPtr &ru QString RulesApplicator::resolveOutPath(const QString &path) const { - QString buildDir = m_buildProduct->rProduct->buildDirectory; + QString buildDir = m_buildProduct->project->resolvedProject()->buildDirectory; QString result = FileInfo::resolvePath(buildDir, path); result = QDir::cleanPath(result); return result; diff --git a/src/lib/buildgraph/buildgraph.h b/src/lib/buildgraph/buildgraph.h index 446ea4b9c..28c1d9ca6 100644 --- a/src/lib/buildgraph/buildgraph.h +++ b/src/lib/buildgraph/buildgraph.h @@ -105,12 +105,11 @@ public: bool discardLoadedProject; }; - static LoadResult load(const QString &projectFilePath, BuildGraph *bg, - const FileTime &minTimeStamp, - const QVariantMap &cfg, - const QStringList &loaderSearchPaths); + static LoadResult load(const QString &projectFilePath, BuildGraph *bg, const QString &buildRoot, + const QVariantMap &cfg, const QStringList &loaderSearchPaths); void store() const; - + static QString deriveBuildGraphFilePath(const QString &buildDir, const QString projectId); + QString buildGraphFilePath() const; BuildGraph *buildGraph() const; ResolvedProject::Ptr resolvedProject() const; @@ -127,11 +126,6 @@ public: void onProductRemoved(const BuildProduct::Ptr &product); private: - static void restoreBuildGraph(const QString &projectFilePath, BuildGraph *buildGraph, - const FileTime &minTimeStamp, - const QVariantMap &configuration, - const QStringList &loaderSearchPaths, - LoadResult *loadResult); void load(PersistentPool &pool); void store(PersistentPool &pool) const; void addBuildProduct(const BuildProduct::Ptr &product); @@ -169,10 +163,6 @@ public: void applyRules(BuildProduct *product, ArtifactsPerFileTagMap &artifactsPerFileTag); void setProgressObserver(ProgressObserver *observer); - void setOutputDirectoryRoot(const QString &buildDirectoryRoot) { m_outputDirectoryRoot = buildDirectoryRoot; } - const QString &outputDirectoryRoot() const { return m_outputDirectoryRoot; } - QString buildDirectory(const QString &projectId) const; - QString buildGraphFilePath(const QString &projectId) const; static bool findPath(Artifact *u, Artifact *v, QList<Artifact*> &path); static void connect(Artifact *p, Artifact *c); @@ -218,7 +208,6 @@ private: }; ProgressObserver *m_progressObserver; - QString m_outputDirectoryRoot; /// The directory where the 'build' and 'targets' subdirectories end up. ScriptEngine *m_engine; unsigned int m_initEngineCalls; QScriptValue m_scope; diff --git a/src/lib/language/language.cpp b/src/lib/language/language.cpp index 60d25d670..ec5f88fdb 100644 --- a/src/lib/language/language.cpp +++ b/src/lib/language/language.cpp @@ -375,7 +375,6 @@ void ResolvedProduct::load(PersistentPool &pool) >> additionalFileTags >> name >> targetName - >> buildDirectory >> sourceDirectory >> destinationDirectory >> qbsFile; @@ -394,7 +393,6 @@ void ResolvedProduct::store(PersistentPool &pool) const << additionalFileTags << name << targetName - << buildDirectory << sourceDirectory << destinationDirectory << qbsFile; @@ -568,6 +566,11 @@ QString ResolvedProject::deriveId(const QVariantMap &config) return profile + QLatin1Char('-') + buildVariant; } +QString ResolvedProject::deriveBuildDirectory(const QString &buildRoot, const QString &id) +{ + return buildRoot + QLatin1Char('/') + id; +} + void ResolvedProject::setBuildConfiguration(const QVariantMap &config) { m_buildConfiguration = config; diff --git a/src/lib/language/language.h b/src/lib/language/language.h index 89463133b..187de7c54 100644 --- a/src/lib/language/language.h +++ b/src/lib/language/language.h @@ -321,7 +321,6 @@ public: QStringList additionalFileTags; QString name; QString targetName; - QString buildDirectory; QString sourceDirectory; QString destinationDirectory; QString qbsFile; @@ -359,8 +358,10 @@ public: static Ptr create() { return Ptr(new ResolvedProject); } static QString deriveId(const QVariantMap &config); + static QString deriveBuildDirectory(const QString &buildRoot, const QString &id); QString qbsFile; // Not saved. + QString buildDirectory; // Not saved QVariantMap platformEnvironment; QList<ResolvedProduct::Ptr> products; @@ -381,8 +382,6 @@ private: } // namespace Internal } // namespace qbs -Q_DECLARE_METATYPE(qbs::Internal::ResolvedProject::Ptr) - QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(qbs::Internal::JsImport, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(qbs::Internal::RuleArtifact::Binding, Q_MOVABLE_TYPE); diff --git a/src/lib/language/loader.cpp b/src/lib/language/loader.cpp index 4144e567c..d492f75ff 100644 --- a/src/lib/language/loader.cpp +++ b/src/lib/language/loader.cpp @@ -1820,10 +1820,10 @@ static bool checkCondition(EvaluationObject *object) return true; } -ResolvedProject::Ptr Loader::resolveProject(ProjectFile::Ptr projectFile, const QString &buildDirectory, +ResolvedProject::Ptr Loader::resolveProject(ProjectFile::Ptr projectFile, const QString &buildRoot, const QVariantMap &userProperties, bool resolveProductDependencies) { - Q_ASSERT(FileInfo::isAbsolute(buildDirectory)); + Q_ASSERT(FileInfo::isAbsolute(buildRoot)); if (qbsLogLevel(LoggerTrace)) qbsTrace() << "[LDR] resolving " << m_project->fileName; m_project = projectFile; @@ -1833,6 +1833,7 @@ ResolvedProject::Ptr Loader::resolveProject(ProjectFile::Ptr projectFile, const ResolvedProject::Ptr rproject = ResolvedProject::create(); rproject->qbsFile = m_project->fileName; rproject->setBuildConfiguration(userProperties); + rproject->buildDirectory = ResolvedProject::deriveBuildDirectory(buildRoot, rproject->id()); Scope::Ptr context = buildFileContext(m_project.data()); ScopeChain::Ptr scope(new ScopeChain(m_engine, context)); @@ -1874,13 +1875,12 @@ ResolvedProject::Ptr Loader::resolveProject(ProjectFile::Ptr projectFile, const // insert property "buildDirectory" { - Property p(m_engine->toScriptValue(buildDirectory)); + Property p(m_engine->toScriptValue(rproject->buildDirectory)); productProps->properties.insert("buildDirectory", p); } rproduct->fileTags = productProps->stringListValue("type"); rproduct->destinationDirectory = productProps->stringValue("destination"); - rproduct->buildDirectory = buildDirectory; foreach (const Rule::Ptr &rule, globalRules) rproduct->rules.insert(rule); foreach (const FileTagger::ConstPtr &fileTagger, globalFileTaggers) @@ -1997,17 +1997,6 @@ ResolvedProject::Ptr Loader::resolveProject(ProjectFile::Ptr projectFile, const foreach (Module::Ptr module, projectData.products.value(rproduct).product->modules) checkModuleDependencies(module); - // Change build directory for products with the same name. - foreach (const QString &name, uniqueStrings) { - QList<ResolvedProduct::Ptr> products = resolvedProducts.values(name); - if (products.count() < 2) - continue; - foreach (ResolvedProduct::Ptr product, products) { - product->buildDirectory.append('/'); - product->buildDirectory.append(product->fileTags.join("-")); - } - } - // Resolve inter-product dependencies. if (resolveProductDependencies) { @@ -2263,7 +2252,7 @@ void Loader::resolveTransformer(ResolvedProduct::Ptr rproduct, EvaluationObject QString fileName = child->scope->stringValue("fileName"); if (fileName.isEmpty()) throw Error(Tr::tr("Artifact fileName must not be empty.")); - artifact->absoluteFilePath = FileInfo::resolvePath(rproduct->buildDirectory, + artifact->absoluteFilePath = FileInfo::resolvePath(rproduct->project->buildDirectory, fileName); artifact->fileTags = child->scope->stringListValue("fileTags").toSet(); rtrafo->outputs += artifact; diff --git a/src/lib/language/loader.h b/src/lib/language/loader.h index a91d1881b..336e499d6 100644 --- a/src/lib/language/loader.h +++ b/src/lib/language/loader.h @@ -367,7 +367,7 @@ public: void setProgressObserver(ProgressObserver *observer); void setSearchPaths(const QStringList &searchPaths); ProjectFile::Ptr loadProject(const QString &fileName); - ResolvedProject::Ptr resolveProject(ProjectFile::Ptr projectFile, const QString &buildDirectory, + ResolvedProject::Ptr resolveProject(ProjectFile::Ptr projectFile, const QString &buildRoot, const QVariantMap &userProperties, bool resolveProductDependencies = true); protected: ProjectFile::Ptr parseFile(const QString &fileName); diff --git a/src/lib/language/qbsengine.cpp b/src/lib/language/qbsengine.cpp index 06fbc0a28..518ffe5f0 100644 --- a/src/lib/language/qbsengine.cpp +++ b/src/lib/language/qbsengine.cpp @@ -114,22 +114,13 @@ void QbsEngine::setProgressObserver(ProgressObserver *observer) d->buildGraph->setProgressObserver(observer); } -void QbsEngine::setBuildRoot(const QString &directory) +Project::Id QbsEngine::setupProject(const QString &projectFileName, const QVariantMap &_buildConfig, + const QString &buildRoot) { - d->buildGraph->setOutputDirectoryRoot(directory); -} - -Project::Id QbsEngine::setupProject(const QString &projectFileName, const QVariantMap &_buildConfig) -{ - Loader loader(&d->engine); - loader.setSearchPaths(d->settings.searchPaths()); - loader.setProgressObserver(d->observer); - ProjectFile::Ptr projectFile; const QVariantMap buildConfig = d->expandedBuildConfiguration(_buildConfig); - const FileTime projectFileTimeStamp = FileInfo(projectFileName).lastModified(); const BuildProject::LoadResult loadResult = BuildProject::load(projectFileName, - d->buildGraph.data(), projectFileTimeStamp, buildConfig, d->settings.searchPaths()); + d->buildGraph.data(), buildRoot, buildConfig, d->settings.searchPaths()); BuildProject::Ptr bProject; ResolvedProject::Ptr rProject; @@ -140,14 +131,14 @@ Project::Id QbsEngine::setupProject(const QString &projectFileName, const QVaria rProject = bProject->resolvedProject(); } else { TimedActivityLogger loadLogger(QLatin1String("Loading project")); + Loader loader(&d->engine); + loader.setSearchPaths(d->settings.searchPaths()); + loader.setProgressObserver(d->observer); projectFile = loader.loadProject(projectFileName); - if (loadResult.changedResolvedProject) { + if (loadResult.changedResolvedProject) rProject = loadResult.changedResolvedProject; - } else { - const QString buildDir = d->buildGraph->buildDirectory( - ResolvedProject::deriveId(buildConfig)); - rProject = loader.resolveProject(projectFile, buildDir, buildConfig); - } + else + rProject = loader.resolveProject(projectFile, buildRoot, buildConfig); if (rProject->products.isEmpty()) throw Error(QString("'%1' does not contain products.").arg(projectFileName)); if (loadResult.loadedProject) diff --git a/src/lib/language/qbsengine.h b/src/lib/language/qbsengine.h index 541064930..f24a14de1 100644 --- a/src/lib/language/qbsengine.h +++ b/src/lib/language/qbsengine.h @@ -54,10 +54,10 @@ public: ~QbsEngine(); void setProgressObserver(ProgressObserver *observer); - void setBuildRoot(const QString &directory); // All of these may throw qbs::Error. - Project::Id setupProject(const QString &projectFileName, const QVariantMap &buildConfig); + Project::Id setupProject(const QString &projectFileName, const QVariantMap &buildConfig, + const QString &buildRoot); void buildProjects(const QList<Project::Id> &projectIds, const BuildOptions &buildOptions); void buildProjects(const QList<Project> &projects, const BuildOptions &buildOptions); void buildProject(Project::Id projectId, const BuildOptions &buildOptions) { diff --git a/src/lib/tools/persistence.cpp b/src/lib/tools/persistence.cpp index bc9bea07d..acfc784ae 100644 --- a/src/lib/tools/persistence.cpp +++ b/src/lib/tools/persistence.cpp @@ -39,7 +39,7 @@ namespace qbs { namespace Internal { -static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE0_0_1__23"; +static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE0_0_1__24"; PersistentPool::PersistentPool() { |