diff options
| -rw-r--r-- | src/lib/api/internaljobs.cpp | 16 | ||||
| -rw-r--r-- | src/lib/buildgraph/artifact.cpp | 11 | ||||
| -rw-r--r-- | src/lib/buildgraph/artifact.h | 5 | ||||
| -rw-r--r-- | src/lib/buildgraph/artifactcleaner.cpp | 2 | ||||
| -rw-r--r-- | src/lib/buildgraph/automoc.cpp | 4 | ||||
| -rw-r--r-- | src/lib/buildgraph/buildgraph.cpp | 6 | ||||
| -rw-r--r-- | src/lib/buildgraph/buildgraphloader.cpp | 148 | ||||
| -rw-r--r-- | src/lib/buildgraph/executor.cpp | 2 | ||||
| -rw-r--r-- | src/lib/buildgraph/inputartifactscanner.cpp | 4 | ||||
| -rw-r--r-- | src/lib/buildgraph/projectbuilddata.cpp | 6 | ||||
| -rw-r--r-- | src/lib/buildgraph/rulesapplicator.cpp | 2 |
11 files changed, 81 insertions, 125 deletions
diff --git a/src/lib/api/internaljobs.cpp b/src/lib/api/internaljobs.cpp index e2a5b7701..0510a87e4 100644 --- a/src/lib/api/internaljobs.cpp +++ b/src/lib/api/internaljobs.cpp @@ -196,19 +196,15 @@ void InternalSetupProjectJob::execute() setupPlatformEnvironment(); break; case SetupProjectParameters::RestoreOnly: - restoreProject(evalContext); + m_project = restoreProject(evalContext).loadedProject; break; case SetupProjectParameters::RestoreAndTrackChanges: { const BuildGraphLoadResult loadResult = restoreProject(evalContext); - if (!loadResult.discardLoadedProject) + m_project = loadResult.newlyResolvedProject; + if (!m_project && !loadResult.discardLoadedProject) m_project = loadResult.loadedProject; - if (!m_project) { - if (loadResult.newlyResolvedProject) { - m_project = loadResult.newlyResolvedProject; - } else { - resolveProjectFromScratch(evalContext->engine()); - } - } + if (!m_project) + resolveProjectFromScratch(evalContext->engine()); if (!m_project->buildData) { resolveBuildDataFromScratch(evalContext); if (loadResult.loadedProject) @@ -251,8 +247,6 @@ BuildGraphLoadResult InternalSetupProjectJob::restoreProject(const RulesEvaluati { BuildGraphLoader bgLoader(m_parameters.environment(), logger()); const BuildGraphLoadResult loadResult = bgLoader.load(m_parameters, evalContext); - if (!loadResult.discardLoadedProject) - m_project = loadResult.loadedProject; return loadResult; } diff --git a/src/lib/buildgraph/artifact.cpp b/src/lib/buildgraph/artifact.cpp index 60f62f768..9923ede18 100644 --- a/src/lib/buildgraph/artifact.cpp +++ b/src/lib/buildgraph/artifact.cpp @@ -57,13 +57,13 @@ QT_END_NAMESPACE namespace qbs { namespace Internal { -Artifact::Artifact() +Artifact::Artifact() : topLevelProject(0) { initialize(); } -Artifact::Artifact(const ResolvedProjectPtr &project) - : project(project) +Artifact::Artifact(TopLevelProject *project) + : topLevelProject(project) { initialize(); } @@ -143,10 +143,5 @@ void Artifact::disconnectAll(const Logger &logger) disconnectParents(logger); } -TopLevelProject *Artifact::topLevelProject() const -{ - return project->topLevelProject(); -} - } // namespace Internal } // namespace qbs diff --git a/src/lib/buildgraph/artifact.h b/src/lib/buildgraph/artifact.h index 88d9b677f..bc2a8025d 100644 --- a/src/lib/buildgraph/artifact.h +++ b/src/lib/buildgraph/artifact.h @@ -59,7 +59,7 @@ public: // include language.h in every file that includes artifact.h due to Qt 4's weird // QSharedPointer implementation. Artifact(); - explicit Artifact(const ResolvedProjectPtr &project); + explicit Artifact(TopLevelProject *project); ~Artifact(); @@ -67,7 +67,7 @@ public: ArtifactList children; ArtifactList fileDependencies; FileTags fileTags; - WeakPointer<ResolvedProject> project; + TopLevelProject *topLevelProject; WeakPointer<ResolvedProduct> product; // Note: file dependency artifacts don't belong to a product. TransformerPtr transformer; PropertyMapPtr properties; @@ -102,7 +102,6 @@ public: QString dirPath() const { return m_dirPath.toString(); } QString fileName() const { return m_fileName.toString(); } void disconnectAll(const Logger &logger); - TopLevelProject *topLevelProject() const; private: void load(PersistentPool &pool); diff --git a/src/lib/buildgraph/artifactcleaner.cpp b/src/lib/buildgraph/artifactcleaner.cpp index d1b76ca69..60b811154 100644 --- a/src/lib/buildgraph/artifactcleaner.cpp +++ b/src/lib/buildgraph/artifactcleaner.cpp @@ -61,7 +61,7 @@ static void invalidateArtifactTimestamp(Artifact *artifact) { if (artifact->timestamp.isValid()) { artifact->timestamp.clear(); - artifact->topLevelProject()->buildData->isDirty = true; + artifact->topLevelProject->buildData->isDirty = true; } } diff --git a/src/lib/buildgraph/automoc.cpp b/src/lib/buildgraph/automoc.cpp index b81444a55..6c750a307 100644 --- a/src/lib/buildgraph/automoc.cpp +++ b/src/lib/buildgraph/automoc.cpp @@ -344,7 +344,7 @@ void AutoMoc::unmoc(Artifact *artifact, const FileTag &mocFileTag) m_logger.qbsTrace() << "[AUTOMOC] removing moc obj artifact " << relativeArtifactFileName(mocObjArtifact); } - artifact->topLevelProject()->buildData->removeArtifact(mocObjArtifact, m_logger); + artifact->topLevelProject->buildData->removeArtifact(mocObjArtifact, m_logger); } } @@ -352,7 +352,7 @@ void AutoMoc::unmoc(Artifact *artifact, const FileTag &mocFileTag) m_logger.qbsTrace() << "[AUTOMOC] removing generated artifact " << relativeArtifactFileName(generatedMocArtifact); } - artifact->topLevelProject()->buildData->removeArtifact(generatedMocArtifact, m_logger); + artifact->topLevelProject->buildData->removeArtifact(generatedMocArtifact, m_logger); delete generatedMocArtifact; } diff --git a/src/lib/buildgraph/buildgraph.cpp b/src/lib/buildgraph/buildgraph.cpp index 95330f962..a52005b4d 100644 --- a/src/lib/buildgraph/buildgraph.cpp +++ b/src/lib/buildgraph/buildgraph.cpp @@ -246,7 +246,7 @@ void connect(Artifact *p, Artifact *c) QBS_CHECK(p != c); p->children.insert(c); c->parents.insert(p); - p->topLevelProject()->buildData->isDirty = true; + p->topLevelProject->buildData->isDirty = true; } void loggedConnect(Artifact *u, Artifact *v, const Logger &logger) @@ -318,7 +318,7 @@ void removeGeneratedArtifactFromDisk(Artifact *artifact, const Logger &logger) QString relativeArtifactFileName(const Artifact *n) { - const QString &buildDir = n->topLevelProject()->buildDirectory; + const QString &buildDir = n->topLevelProject->buildDirectory; QString str = n->filePath(); if (str.startsWith(buildDir)) str.remove(0, buildDir.count()); @@ -355,7 +355,7 @@ Artifact *lookupArtifact(const ResolvedProductConstPtr &product, const Artifact Artifact *createArtifact(const ResolvedProductPtr &product, const SourceArtifactConstPtr &sourceArtifact, const Logger &logger) { - Artifact *artifact = new Artifact(product->project); + Artifact *artifact = new Artifact(product->topLevelProject()); artifact->artifactType = Artifact::SourceFile; artifact->setFilePath(sourceArtifact->absoluteFilePath); artifact->fileTags = sourceArtifact->fileTags; diff --git a/src/lib/buildgraph/buildgraphloader.cpp b/src/lib/buildgraph/buildgraphloader.cpp index 181193d03..100dc059d 100644 --- a/src/lib/buildgraph/buildgraphloader.cpp +++ b/src/lib/buildgraph/buildgraphloader.cpp @@ -78,7 +78,7 @@ static void restoreBackPointers(const ResolvedProjectPtr &project) if (!product->buildData) continue; foreach (Artifact * const a, product->buildData->artifacts) { - a->project = project; + a->topLevelProject = project->topLevelProject(); project->topLevelProject()->buildData->insertIntoArtifactLookupTable(a); } } @@ -146,7 +146,7 @@ BuildGraphLoadResult BuildGraphLoader::load(const SetupProjectParameters ¶me restoreBackPointers(project); foreach (Artifact * const a, project->buildData->dependencyArtifacts) - a->project = project; + a->topLevelProject = project.data(); project->location = CodeLocation(parameters.projectFilePath(), project->location.line(), project->location.column()); @@ -163,54 +163,6 @@ BuildGraphLoadResult BuildGraphLoader::load(const SetupProjectParameters ¶me return m_result; } -static void exchangeDependencies(const ResolvedProductPtr &newProduct, - const QList<ResolvedProductPtr> &allRestoredProducts, - const QList<ResolvedProductPtr> &addedProducts) -{ - QSet<ResolvedProductPtr> newDependencies; - foreach (const ResolvedProductPtr &dependency, newProduct->dependencies) { - if (addedProducts.contains(dependency)) { - newDependencies << dependency; - exchangeDependencies(dependency, allRestoredProducts, addedProducts); - continue; - } - bool counterPartFound = false; - foreach (const ResolvedProductPtr &restoredProduct, allRestoredProducts) { - if (restoredProduct->name == dependency->name) { - newDependencies << restoredProduct; - counterPartFound = true; - break; - } - } - QBS_CHECK(counterPartFound); - } - newProduct->dependencies = newDependencies; -} - -static void manipulateAddedProducts(const QList<ResolvedProjectPtr> &allRestoredProjects, - const QList<ResolvedProductPtr> &allRestoredProducts, - const QList<ResolvedProductPtr> &addedProducts) -{ - foreach (const ResolvedProductPtr &product, addedProducts) { - // Find the right existing (sub-)project to put the new product into. - bool projectFound = false; - foreach (const ResolvedProjectPtr &project, allRestoredProjects) { - if (project->location != product->project->location) - continue; - product->project = project; - project->products.append(product); - projectFound = true; - break; - } - QBS_CHECK(projectFound); - - // Exchange dependencies that are not new with their counterparts from the restored project. - exchangeDependencies(product, allRestoredProducts, addedProducts); - } -} - -// TODO: Pay more attention to project metadata such as name and location. If these change, -// we must transfer them over to the old build graph. void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶meters, const QString &buildGraphFilePath, const TopLevelProjectPtr &restoredProject) { @@ -234,12 +186,12 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶met } } if (subProjectRemoved) { - m_logger.qbsTrace() << "A sub-project was removed, must re-resolve project"; + m_logger.qbsDebug() << "A sub-project was removed, must re-resolve project"; // Save build graph to prevent a re-resolve on every run now. restoredProject->buildData->isDirty = true; } if (projectFileChanged) { - m_logger.qbsTrace() << "A project file changed, must re-resolve project."; + m_logger.qbsDebug() << "A project file changed, must re-resolve project."; // Save build graph to prevent a re-resolve on every run now. restoredProject->buildData->isDirty = true; } @@ -250,10 +202,10 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶met environmentChanged = m_environment.value(it.key()) != it.value(); } if (environmentChanged) - m_logger.qbsTrace() << "A relevant environment variable changed, must re-resolve project."; + m_logger.qbsDebug() << "A relevant environment variable changed, must re-resolve project."; bool productRemoved = false; - const QList<ResolvedProductPtr> allRestoredProducts = restoredProject->allProducts(); + QList<ResolvedProductPtr> allRestoredProducts = restoredProject->allProducts(); QList<ResolvedProductPtr> changedProducts; foreach (const ResolvedProductPtr &product, allRestoredProducts) { const QString fileName = product->location.fileName(); @@ -288,11 +240,8 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶met break; } } - if (filesChanged) { - m_logger.qbsTrace() << "A qbs or js file changed, must re-resolve project"; - // Save build graph to prevent a re-resolve on every run now. - restoredProject->buildData->isDirty = true; - } + if (filesChanged) + m_logger.qbsDebug() << "A qbs or js file changed, must re-resolve project"; if (!filesChanged && !environmentChanged && !projectFileChanged && !subProjectRemoved && !productRemoved && changedProducts.isEmpty()) @@ -303,7 +252,7 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶met m_result.newlyResolvedProject = ldr.loadProject(parameters); QMap<QString, ResolvedProductPtr> freshProductsByName; - const QList<ResolvedProductPtr> allNewlyResolvedProducts + QList<ResolvedProductPtr> allNewlyResolvedProducts = m_result.newlyResolvedProject->allProducts(); foreach (const ResolvedProductPtr &cp, allNewlyResolvedProducts) freshProductsByName.insert(cp->name, cp); @@ -318,6 +267,8 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶met seenTransformers.insert(artifact->transformer); ResolvedProductPtr freshProduct = freshProductsByName.value(product->name); if (freshProduct && checkForPropertyChanges(artifact->transformer, freshProduct)) { + m_logger.qbsDebug() << "Cannot re-use build graph due to property changes " + "in product '" << freshProduct->name << "'."; m_result.discardLoadedProject = true; return; } @@ -333,41 +284,54 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters ¶met return; } - QSet<QString> oldProductNames, newProductNames; - foreach (const ResolvedProductConstPtr &product, allRestoredProducts) - oldProductNames += product->name; - foreach (const ResolvedProductConstPtr &product, allNewlyResolvedProducts) - newProductNames += product->name; - - const QSet<QString> removedProductsNames = oldProductNames - newProductNames; - if (!removedProductsNames.isEmpty()) { - foreach (const ResolvedProductPtr &product, allRestoredProducts) { - if (removedProductsNames.contains(product->name)) - onProductRemoved(product); + // Move over restored build data to newly resolved project. + m_result.newlyResolvedProject->buildData.swap(restoredProject->buildData); + QBS_CHECK(m_result.newlyResolvedProject->buildData); + foreach (Artifact * const a, m_result.newlyResolvedProject->buildData->dependencyArtifacts) + a->topLevelProject = m_result.newlyResolvedProject.data(); + m_result.newlyResolvedProject->buildData->isDirty = true; + for (int i = allNewlyResolvedProducts.count() - 1; i >= 0; --i) { + const ResolvedProductPtr &newlyResolvedProduct = allNewlyResolvedProducts.at(i); + for (int j = allRestoredProducts.count() - 1; j >= 0; --j) { + const ResolvedProductPtr &restoredProduct = allRestoredProducts.at(j); + if (newlyResolvedProduct->name == restoredProduct->name) { + newlyResolvedProduct->buildData.swap(restoredProduct->buildData); + if (newlyResolvedProduct->buildData) { + foreach (Artifact * const a, newlyResolvedProduct->buildData->artifacts) { + a->product = newlyResolvedProduct; + a->topLevelProject = newlyResolvedProduct->topLevelProject(); + } + } + + // Keep in list if build data still needs to be resolved. + if (!newlyResolvedProduct->enabled || newlyResolvedProduct->buildData) + allNewlyResolvedProducts.removeAt(i); + + allRestoredProducts.removeAt(j); + break; + } } } - const QSet<QString> addedProductNames = newProductNames - oldProductNames; - QList<ResolvedProductPtr> addedProducts; - foreach (const QString &productName, addedProductNames) { - const ResolvedProductPtr &freshProduct = freshProductsByName.value(productName); - QBS_ASSERT(freshProduct, continue); - addedProducts.append(freshProduct); - } - if (!addedProducts.isEmpty()) { - manipulateAddedProducts(allRestoredProjects, allRestoredProducts, addedProducts); + // Products still left in the list need resolving, either because they are new + // or because they are newly enabled. + if (!allNewlyResolvedProducts.isEmpty()) { BuildDataResolver bpr(m_logger); - bpr.resolveProductBuildDataForExistingProject(restoredProject, addedProducts); + bpr.resolveProductBuildDataForExistingProject(m_result.newlyResolvedProject, + allNewlyResolvedProducts); } - CycleDetector(m_logger).visitProject(restoredProject); + // Products still left in the list do not exist anymore. + foreach (const ResolvedProductPtr &removedProduct, allRestoredProducts) + onProductRemoved(removedProduct); + + CycleDetector(m_logger).visitProject(m_result.newlyResolvedProject); } void BuildGraphLoader::onProductRemoved(const ResolvedProductPtr &product) { m_logger.qbsDebug() << "[BG] product '" << product->name << "' removed."; - product->topLevelProject()->buildData->isDirty = true; product->project->products.removeOne(product); // delete all removed artifacts physically from the disk @@ -499,14 +463,14 @@ void BuildGraphLoader::removeArtifactAndExclusiveDependents(Artifact *artifact, if (parent->children.isEmpty()) { removeParent = true; } else if (parent->transformer) { - artifact->topLevelProject()->buildData->artifactsThatMustGetNewTransformers += parent; + artifact->topLevelProject->buildData->artifactsThatMustGetNewTransformers += parent; parent->transformer->inputs.remove(artifact); removeParent = parent->transformer->inputs.isEmpty(); } if (removeParent) removeArtifactAndExclusiveDependents(parent, removedArtifacts); } - artifact->topLevelProject()->buildData->removeArtifact(artifact, m_logger); + artifact->topLevelProject->buildData->removeArtifact(artifact, m_logger); } bool BuildGraphLoader::checkForPropertyChanges(const TransformerPtr &restoredTrafo, @@ -524,22 +488,26 @@ bool BuildGraphLoader::checkForPropertyChanges(const TransformerPtr &restoredTra v = finder.propertyValue(freshProduct->properties->value(), property.moduleName, property.propertyName); } - if (property.value != v) + if (property.value != v) { + m_logger.qbsDebug() << "Value for property '" << property.moduleName << "." + << property.propertyName << "' has changed."; + m_logger.qbsDebug() << "Old value was '" << property.value << "'."; + m_logger.qbsDebug() << "New value is '" << v << "'."; return true; + } } return false; } void BuildGraphLoader::replaceFileDependencyWithArtifact(Artifact *filedep, Artifact *artifact) { - QBS_ASSERT(filedep->project == artifact->project, return); if (m_logger.traceEnabled()) { m_logger.qbsTrace() << QString::fromLocal8Bit("[BG] replace file dependency '%1' " "with artifact of type '%2'") .arg(relativeArtifactFileName(filedep)).arg(artifact->artifactType); } - foreach (const ResolvedProductPtr &product, filedep->project->products) { + foreach (const ResolvedProductPtr &product, filedep->topLevelProject->allProducts()) { if (!product->buildData) continue; foreach (Artifact *artifactInProduct, product->buildData->artifacts) { @@ -550,8 +518,8 @@ void BuildGraphLoader::replaceFileDependencyWithArtifact(Artifact *filedep, Arti artifactInProduct->fileDependencies.remove(filedep); } } - filedep->topLevelProject()->buildData->dependencyArtifacts.remove(filedep); - filedep->topLevelProject()->buildData->removeFromArtifactLookupTable(filedep); + filedep->topLevelProject->buildData->dependencyArtifacts.remove(filedep); + filedep->topLevelProject->buildData->removeFromArtifactLookupTable(filedep); delete filedep; } diff --git a/src/lib/buildgraph/executor.cpp b/src/lib/buildgraph/executor.cpp index 11cdd9aad..d842eaf85 100644 --- a/src/lib/buildgraph/executor.cpp +++ b/src/lib/buildgraph/executor.cpp @@ -711,7 +711,7 @@ void Executor::onProcessSuccess() QBS_CHECK(processedArtifact); // Update the timestamps of the outputs of the transformer we just executed. - processedArtifact->topLevelProject()->buildData->isDirty = true; + processedArtifact->topLevelProject->buildData->isDirty = true; foreach (Artifact *artifact, processedArtifact->transformer->outputs) { if (artifact->alwaysUpdated) artifact->timestamp = FileTime::currentTime(); diff --git a/src/lib/buildgraph/inputartifactscanner.cpp b/src/lib/buildgraph/inputartifactscanner.cpp index f6863bc3b..c019ba7f0 100644 --- a/src/lib/buildgraph/inputartifactscanner.cpp +++ b/src/lib/buildgraph/inputartifactscanner.cpp @@ -315,11 +315,11 @@ void InputArtifactScanner::handleDependency(ResolvedDependency &dependency) m_logger.qbsTrace() << QString::fromLocal8Bit("[DEPSCAN] + '%1'") .arg(dependency.filePath); } - dependency.artifact = new Artifact(m_artifact->project); + dependency.artifact = new Artifact(m_artifact->topLevelProject); dependency.artifact->artifactType = Artifact::FileDependency; dependency.artifact->properties = m_artifact->properties; dependency.artifact->setFilePath(dependency.filePath); - m_artifact->topLevelProject()->buildData->insertFileDependency(dependency.artifact); + m_artifact->topLevelProject->buildData->insertFileDependency(dependency.artifact); } else if (dependency.artifact->artifactType == Artifact::FileDependency) { // The dependency exists in the project's list of file dependencies. if (m_logger.traceEnabled()) { diff --git a/src/lib/buildgraph/projectbuilddata.cpp b/src/lib/buildgraph/projectbuilddata.cpp index b81ada73f..14e20d2df 100644 --- a/src/lib/buildgraph/projectbuilddata.cpp +++ b/src/lib/buildgraph/projectbuilddata.cpp @@ -222,10 +222,10 @@ void BuildDataResolver::rescueBuildData(const TopLevelProjectConstPtr &source, const TopLevelProjectPtr &target, Logger logger) { QHash<QString, ResolvedProductConstPtr> sourceProductsByName; - foreach (const ResolvedProductConstPtr &product, source->products) + foreach (const ResolvedProductConstPtr &product, source->allProducts()) sourceProductsByName.insert(product->name, product); - foreach (const ResolvedProductPtr &product, target->products) { + foreach (const ResolvedProductPtr &product, target->allProducts()) { ResolvedProductConstPtr sourceProduct = sourceProductsByName.value(product->name); if (!sourceProduct) continue; @@ -296,7 +296,7 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc //add qbsFile artifact Artifact *qbsFileArtifact = lookupArtifact(product, product->location.fileName()); if (!qbsFileArtifact) { - qbsFileArtifact = new Artifact(product->project); + qbsFileArtifact = new Artifact(product->topLevelProject()); qbsFileArtifact->artifactType = Artifact::SourceFile; qbsFileArtifact->setFilePath(product->location.fileName()); qbsFileArtifact->properties = product->properties; diff --git a/src/lib/buildgraph/rulesapplicator.cpp b/src/lib/buildgraph/rulesapplicator.cpp index d51da8003..388da361a 100644 --- a/src/lib/buildgraph/rulesapplicator.cpp +++ b/src/lib/buildgraph/rulesapplicator.cpp @@ -261,7 +261,7 @@ Artifact *RulesApplicator::createOutputArtifact(const RuleArtifactConstPtr &rule } outputArtifact->fileTags += ruleArtifact->fileTags; } else { - outputArtifact = new Artifact(m_product->project); + outputArtifact = new Artifact(m_product->topLevelProject()); outputArtifact->artifactType = Artifact::Generated; outputArtifact->setFilePath(outputPath); outputArtifact->fileTags = ruleArtifact->fileTags; |
