diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2014-02-04 17:11:04 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@digia.com> | 2014-02-18 10:22:40 +0100 |
commit | f5697c64ef4f1c2784b18702e6ff842ae124deb5 (patch) | |
tree | da5defee48d401f29e03306f75b86bb5f4e368f5 /src/lib | |
parent | 58eab9ee4ca2f9f34d6ecb6648e7d5095de5aeb0 (diff) |
De-obfuscate Executor.
Transformers are what jobs work on, not artifacts.
Change-Id: Ib267ec247dd6d165347511f0a0fdb3db00c58832
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/corelib/buildgraph/executor.cpp | 187 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/executor.h | 7 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/executorjob.cpp | 8 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/executorjob.h | 2 |
4 files changed, 100 insertions, 104 deletions
diff --git a/src/lib/corelib/buildgraph/executor.cpp b/src/lib/corelib/buildgraph/executor.cpp index dadcb1f70..304e038d6 100644 --- a/src/lib/corelib/buildgraph/executor.cpp +++ b/src/lib/corelib/buildgraph/executor.cpp @@ -191,7 +191,6 @@ void Executor::doBuild() m_error.clear(); m_explicitlyCanceled = false; m_activeFileTags = FileTags::fromStringList(m_buildOptions.activeFileTags()); - setState(ExecutorRunning); if (m_productsToBuild.isEmpty()) { @@ -407,11 +406,11 @@ bool Executor::mustExecuteTransformer(const TransformerPtr &transformer) const void Executor::buildArtifact(Artifact *artifact) { - QBS_CHECK(!m_availableJobs.isEmpty()); - if (m_doDebug) m_logger.qbsDebug() << "[EXEC] " << relativeArtifactFileName(artifact); + QBS_CHECK(artifact->buildState == BuildGraphNode::Buildable); + // skip artifacts without transformer if (artifact->artifactType != Artifact::Generated) { // For source artifacts, that were not reachable when initializing the build, we must @@ -429,79 +428,7 @@ void Executor::buildArtifact(Artifact *artifact) // Every generated artifact must have a transformer. QBS_CHECK(artifact->transformer); - - bool childrenAddedDueToRescue; - rescueOldBuildData(artifact, &childrenAddedDueToRescue); - if (childrenAddedDueToRescue && checkForUnbuiltDependencies(artifact)) - return; - - // Skip if outputs of this transformer are already built. - // That means we already ran the transformation. - foreach (Artifact *sideBySideArtifact, artifact->transformer->outputs) { - if (sideBySideArtifact == artifact) - continue; - switch (sideBySideArtifact->buildState) - { - case BuildGraphNode::Untouched: - case BuildGraphNode::Buildable: - break; - case BuildGraphNode::Built: - if (m_doDebug) - m_logger.qbsDebug() << "[EXEC] Side by side artifact already finished. Skipping."; - finishArtifact(artifact); - return; - case BuildGraphNode::Building: - if (m_doDebug) - m_logger.qbsDebug() << "[EXEC] Side by side artifact processing. Skipping."; - artifact->buildState = BuildGraphNode::Building; - return; - } - } - - // Skip if we're building just one file and the file tags do not match. - if (!m_activeFileTags.isEmpty() && !m_activeFileTags.matches(artifact->fileTags)) { - if (m_doDebug) - m_logger.qbsDebug() << "[EXEC] file tags do not match. Skipping."; - finishArtifact(artifact); - return; - } - - // Skip transformers that do not need to be built. - if (!mustExecuteTransformer(artifact->transformer)) { - if (m_doDebug) - m_logger.qbsDebug() << "[EXEC] Up to date. Skipping."; - finishArtifact(artifact); - return; - } - - // create the output directories - if (!m_buildOptions.dryRun()) { - ArtifactSet::const_iterator it = artifact->transformer->outputs.begin(); - for (; it != artifact->transformer->outputs.end(); ++it) { - Artifact *output = *it; - QDir outDir = QFileInfo(output->filePath()).absoluteDir(); - if (!outDir.exists()) - outDir.mkpath(QLatin1String(".")); - } - } - - // scan all input artifacts - InputArtifactScanner scanner(artifact, m_inputArtifactScanContext, m_logger); - scanner.scan(); - - // postpone the build of this artifact, if new dependencies found - if (scanner.newDependencyAdded() && checkForUnbuiltDependencies(artifact)) - return; - - ExecutorJob *job = m_availableJobs.takeFirst(); - artifact->buildState = BuildGraphNode::Building; - m_processingJobs.insert(job, artifact); - - Q_ASSERT_X(artifact->product, Q_FUNC_INFO, - qPrintable(QString::fromLatin1("Generated artifact '%1' belongs to no product.") - .arg(QDir::toNativeSeparators(artifact->filePath())))); - - job->run(artifact->transformer.data(), artifact->product); + potentiallyRunTransformer(artifact->transformer); } void Executor::executeRuleNode(RuleNode *ruleNode) @@ -571,10 +498,19 @@ void Executor::finishJob(ExecutorJob *job, bool success) QBS_CHECK(job); QBS_CHECK(m_state != ExecutorIdle); - const QHash<ExecutorJob *, Artifact *>::Iterator it = m_processingJobs.find(job); + const JobMap::Iterator it = m_processingJobs.find(job); QBS_CHECK(it != m_processingJobs.end()); - if (success) - finishArtifact(it.value()); + const TransformerPtr transformer = it.value(); + if (success) { + m_project->buildData->isDirty = true; + foreach (Artifact *artifact, transformer->outputs) { + if (artifact->alwaysUpdated) + artifact->setTimestamp(FileTime::currentTime()); + else + artifact->setTimestamp(FileInfo(artifact->filePath()).lastModified()); + } + finishTransformer(transformer); + } m_processingJobs.erase(it); m_availableJobs.append(job); @@ -644,14 +580,6 @@ void Executor::finishArtifact(Artifact *leaf) finishNode(leaf); m_scanResultCache.remove(leaf->filePath()); - - if (leaf->transformer) { - foreach (Artifact *sideBySideArtifact, leaf->transformer->outputs) - if (leaf != sideBySideArtifact - && sideBySideArtifact->buildState == BuildGraphNode::Building) { - finishArtifact(sideBySideArtifact); - } - } } QString Executor::configString() const @@ -808,6 +736,79 @@ bool Executor::checkForUnbuiltDependencies(Artifact *artifact) return false; } +void Executor::potentiallyRunTransformer(const TransformerPtr &transformer) +{ + bool matchingFileTagsExist = m_activeFileTags.isEmpty(); + + foreach (Artifact * const output, transformer->outputs) { + // Rescuing build data can introduce new dependencies, potentially delaying execution of + // this transformer. + bool childrenAddedDueToRescue; + rescueOldBuildData(output, &childrenAddedDueToRescue); + if (childrenAddedDueToRescue && checkForUnbuiltDependencies(output)) + return; + + if (!matchingFileTagsExist && m_activeFileTags.matches(output->fileTags)) + matchingFileTagsExist = true; + } + + // Skip if we're building just one file and the file tags do not match. + if (!matchingFileTagsExist) { + if (m_doDebug) + m_logger.qbsDebug() << "[EXEC] file tags do not match. Skipping."; + finishTransformer(transformer); + return; + } + + // Skip transformers that do not need to be built. + if (!mustExecuteTransformer(transformer)) { + if (m_doDebug) + m_logger.qbsDebug() << "[EXEC] Up to date. Skipping."; + finishTransformer(transformer); + return; + } + + foreach (Artifact * const output, transformer->outputs) { + // Scan all input artifacts. If new dependencies were found during scanning, delay + // execution of this transformer. + InputArtifactScanner scanner(output, m_inputArtifactScanContext, m_logger); + scanner.scan(); + if (scanner.newDependencyAdded() && checkForUnbuiltDependencies(output)) + return; + } + + runTransformer(transformer); +} + +void Executor::runTransformer(const TransformerPtr &transformer) +{ + QBS_CHECK(transformer); + + // create the output directories + if (!m_buildOptions.dryRun()) { + ArtifactSet::const_iterator it = transformer->outputs.begin(); + for (; it != transformer->outputs.end(); ++it) { + Artifact *output = *it; + QDir outDir = QFileInfo(output->filePath()).absoluteDir(); + if (!outDir.exists()) + outDir.mkpath(QLatin1String(".")); + } + } + + QBS_CHECK(!m_availableJobs.isEmpty()); + ExecutorJob *job = m_availableJobs.takeFirst(); + foreach (Artifact * const artifact, transformer->outputs) + artifact->buildState = BuildGraphNode::Building; + m_processingJobs.insert(job, transformer); + job->run(transformer.data()); +} + +void Executor::finishTransformer(const TransformerPtr &transformer) +{ + foreach (Artifact * const artifact, transformer->outputs) + finishArtifact(artifact); +} + void Executor::onProcessError(const qbs::ErrorInfo &err) { try { @@ -830,18 +831,6 @@ void Executor::onProcessSuccess() try { ExecutorJob *job = qobject_cast<ExecutorJob *>(sender()); QBS_CHECK(job); - Artifact *processedArtifact = m_processingJobs.value(job); - QBS_CHECK(processedArtifact); - - // Update the timestamps of the outputs of the transformer we just executed. - processedArtifact->product->topLevelProject()->buildData->isDirty = true; - foreach (Artifact *artifact, processedArtifact->transformer->outputs) { - if (artifact->alwaysUpdated) - artifact->setTimestamp(FileTime::currentTime()); - else - artifact->setTimestamp(FileInfo(artifact->filePath()).lastModified()); - } - finishJob(job, true); } catch (const ErrorInfo &error) { handleError(error); diff --git a/src/lib/corelib/buildgraph/executor.h b/src/lib/corelib/buildgraph/executor.h index c0e059472..68afe6083 100644 --- a/src/lib/corelib/buildgraph/executor.h +++ b/src/lib/corelib/buildgraph/executor.h @@ -121,6 +121,9 @@ private: void handleError(const ErrorInfo &error); void rescueOldBuildData(Artifact *artifact, bool *childrenAdded); bool checkForUnbuiltDependencies(Artifact *artifact); + void potentiallyRunTransformer(const TransformerPtr &transformer); + void runTransformer(const TransformerPtr &transformer); + void finishTransformer(const TransformerPtr &transformer); bool mustExecuteTransformer(const TransformerPtr &transformer) const; bool isUpToDate(Artifact *artifact) const; @@ -128,12 +131,14 @@ private: FileTime recursiveFileTime(const QString &filePath) const; QString configString() const; + typedef QHash<ExecutorJob *, TransformerPtr> JobMap; + JobMap m_processingJobs; + RulesEvaluationContextPtr m_evalContext; BuildOptions m_buildOptions; Logger m_logger; ProgressObserver *m_progressObserver; QList<ExecutorJob*> m_availableJobs; - QHash<ExecutorJob*, Artifact *> m_processingJobs; ExecutorState m_state; TopLevelProjectPtr m_project; QList<ResolvedProductPtr> m_productsToBuild; diff --git a/src/lib/corelib/buildgraph/executorjob.cpp b/src/lib/corelib/buildgraph/executorjob.cpp index 281d82e36..f747ca7d8 100644 --- a/src/lib/corelib/buildgraph/executorjob.cpp +++ b/src/lib/corelib/buildgraph/executorjob.cpp @@ -29,6 +29,7 @@ #include "executorjob.h" +#include "artifact.h" #include "command.h" #include "jscommandexecutor.h" #include "processcommandexecutor.h" @@ -78,7 +79,7 @@ void ExecutorJob::setDryRun(bool enabled) m_jsCommandExecutor->setDryRunEnabled(enabled); } -void ExecutorJob::run(Transformer *t, const ResolvedProductPtr &product) +void ExecutorJob::run(Transformer *t) { QBS_ASSERT(m_currentCommandIdx == -1, return); @@ -88,8 +89,9 @@ void ExecutorJob::run(Transformer *t, const ResolvedProductPtr &product) } t->propertiesRequestedInCommands.clear(); - m_processCommandExecutor->setProcessEnvironment(product->buildEnvironment); - + QBS_CHECK(!t->outputs.isEmpty()); + m_processCommandExecutor->setProcessEnvironment( + (*t->outputs.begin())->product->buildEnvironment); m_transformer = t; runNextCommand(); } diff --git a/src/lib/corelib/buildgraph/executorjob.h b/src/lib/corelib/buildgraph/executorjob.h index fcd06cc6d..339b1f82a 100644 --- a/src/lib/corelib/buildgraph/executorjob.h +++ b/src/lib/corelib/buildgraph/executorjob.h @@ -57,7 +57,7 @@ public: void setMainThreadScriptEngine(ScriptEngine *engine); void setDryRun(bool enabled); - void run(Transformer *t, const ResolvedProductPtr &product); + void run(Transformer *t); void cancel(); void waitForFinished(); |