aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/buildgraph/executor.cpp
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2018-01-31 16:36:17 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2018-01-31 16:36:17 +0100
commit028a2d908f269958331610b21f86cb03f1957b98 (patch)
tree4fefc28e07411b169412fd7670b039d65f44571c /src/lib/corelib/buildgraph/executor.cpp
parent606c5cd196e3345b42931306481fe8691f5bb9b6 (diff)
parent764fd1f6ea3f317ad4b50a865ab56b8a8c93080f (diff)
Merge 1.10 into 1.11
Diffstat (limited to 'src/lib/corelib/buildgraph/executor.cpp')
-rw-r--r--src/lib/corelib/buildgraph/executor.cpp57
1 files changed, 48 insertions, 9 deletions
diff --git a/src/lib/corelib/buildgraph/executor.cpp b/src/lib/corelib/buildgraph/executor.cpp
index fd2a22116..a7a98982c 100644
--- a/src/lib/corelib/buildgraph/executor.cpp
+++ b/src/lib/corelib/buildgraph/executor.cpp
@@ -149,7 +149,7 @@ void Executor::retrieveSourceFileTimestamp(Artifact *artifact) const
void Executor::build()
{
try {
- m_partialBuild = m_productsToBuild.size() != m_project->allProducts().size();
+ m_partialBuild = m_productsToBuild.size() != m_allProducts.size();
doBuild();
} catch (const ErrorInfo &e) {
handleError(e);
@@ -159,6 +159,7 @@ void Executor::build()
void Executor::setProject(const TopLevelProjectPtr &project)
{
m_project = project;
+ m_allProducts = project->allProducts();
}
void Executor::setProducts(const QList<ResolvedProductPtr> &productsToBuild)
@@ -168,23 +169,22 @@ void Executor::setProducts(const QList<ResolvedProductPtr> &productsToBuild)
class ProductPrioritySetter
{
- const TopLevelProject *m_topLevelProject;
+ const QList<ResolvedProductPtr> &m_allProducts;
unsigned int m_priority;
Set<ResolvedProductPtr> m_seenProducts;
public:
- ProductPrioritySetter(const TopLevelProject *tlp)
- : m_topLevelProject(tlp)
+ ProductPrioritySetter(const QList<ResolvedProductPtr> &allProducts) // TODO: Use only products to build?
+ : m_allProducts(allProducts)
{
}
void apply()
{
- const QList<ResolvedProductPtr> &allProducts = m_topLevelProject->allProducts();
Set<ResolvedProductPtr> allDependencies;
- for (const ResolvedProductPtr &product : allProducts)
+ for (const ResolvedProductPtr &product : m_allProducts)
allDependencies += product->dependencies;
const Set<ResolvedProductPtr> rootProducts
- = Set<ResolvedProductPtr>::fromList(allProducts) - allDependencies;
+ = Set<ResolvedProductPtr>::fromList(m_allProducts) - allDependencies;
m_priority = UINT_MAX;
m_seenProducts.clear();
for (const ResolvedProductPtr &rootProduct : rootProducts)
@@ -270,6 +270,7 @@ void Executor::doBuild()
m_productInstaller->removeInstallRoot();
addExecutorJobs();
+ syncFileDependencies();
prepareAllNodes();
prepareProducts();
setupRootNodes();
@@ -1111,7 +1112,7 @@ bool Executor::visit(RuleNode *ruleNode)
*/
void Executor::prepareAllNodes()
{
- for (const ResolvedProductPtr &product : m_project->allProducts()) {
+ for (const ResolvedProductPtr &product : m_allProducts) {
if (product->enabled) {
QBS_CHECK(product->buildData);
for (BuildGraphNode * const node : qAsConst(product->buildData->nodes))
@@ -1125,6 +1126,41 @@ void Executor::prepareAllNodes()
}
}
+void Executor::syncFileDependencies()
+{
+ Set<FileDependency *> &globalFileDepList = m_project->buildData->fileDependencies;
+ for (auto it = globalFileDepList.begin(); it != globalFileDepList.end(); ) {
+ FileDependency * const dep = *it;
+ if (FileInfo(dep->filePath()).exists()) {
+ ++it;
+ continue;
+ }
+ qCDebug(lcBuildGraph()) << "file dependency" << dep->filePath() << "no longer exists; "
+ "removing from lookup table";
+ m_project->buildData->removeFromLookupTable(dep);
+ bool isReferencedByArtifact = false;
+ for (const ResolvedProductConstPtr &product : m_allProducts) {
+ if (!product->buildData)
+ continue;
+ const auto artifactList = filterByType<Artifact>(product->buildData->nodes);
+ isReferencedByArtifact = std::any_of(artifactList.begin(), artifactList.end(),
+ [dep](const Artifact *a) { return a->fileDependencies.contains(dep); });
+ // TODO: Would it be safe to mark the artifact as "not up to date" here and clear
+ // its list of file dependencies, rather than doing the check again in
+ // isUpToDate()?
+ if (isReferencedByArtifact)
+ break;
+ }
+ if (!isReferencedByArtifact) {
+ qCDebug(lcBuildGraph()) << "dependency is not referenced by any artifact, deleting";
+ it = globalFileDepList.erase(it);
+ delete dep;
+ } else {
+ ++it;
+ }
+ }
+}
+
void Executor::prepareArtifact(Artifact *artifact)
{
artifact->inputsScanned = false;
@@ -1139,6 +1175,9 @@ void Executor::prepareArtifact(Artifact *artifact)
}
// Timestamps of file dependencies must be invalid for every build.
+ // TODO: These should be a subset of ProjectBuildData::fileDependencies, so clear the
+ // timestamps in syncFileDepencencies() instead.
+ // TODO: Verify this assumption in the sanity checks.
for (FileDependency * const fileDependency : qAsConst(artifact->fileDependencies))
fileDependency->clearTimestamp();
}
@@ -1189,7 +1228,7 @@ void Executor::prepareReachableNodes_impl(BuildGraphNode *node)
void Executor::prepareProducts()
{
- ProductPrioritySetter prioritySetter(m_project.get());
+ ProductPrioritySetter prioritySetter(m_allProducts);
prioritySetter.apply();
for (const ResolvedProductPtr &product : qAsConst(m_productsToBuild)) {
EnvironmentScriptRunner(product.get(), m_evalContext.get(), m_project->environment)