[Driver] Handle outstanding jobs by reading the build record.

r23968 wrote out a record of which source files were included in a build,
and whether they were succesfully compiled or not...and if not, whether
they were out of date because of a cascading or non-cascading dependency.
This commit uses that information to decide what files might need to be
rebuilt even if a particular input doesn't change and doesn't appear to
have any changed dependencies. The two interesting cases are:

- A file was going to be built last time, but the build was halted
  because of an error. Build it this time.
- One of the files was removed and thus we've lost a source of dependency
  information; rebuild everything!

rdar://problem/19270980

Swift SVN r24018
This commit is contained in:
Jordan Rose
2014-12-18 21:24:18 +00:00
parent 53964a44c4
commit 43bcbb8f9e
13 changed files with 269 additions and 46 deletions

View File

@@ -158,9 +158,11 @@ int Compilation::performJobsInList(const JobList &JL, PerformJobsState &State) {
switch (Condition) {
case Job::Condition::Always:
scheduleCommandIfNecessaryAndPossible(Cmd);
if (getIncrementalBuildEnabled() && !DependenciesFile.empty())
InitialOutOfDateCommands.push_back(Cmd);
SWIFT_FALLTHROUGH;
case Job::Condition::RunWithoutCascading:
scheduleCommandIfNecessaryAndPossible(Cmd);
break;
case Job::Condition::CheckDependencies:
DeferredCommands.insert(Cmd);
@@ -332,16 +334,13 @@ int Compilation::performJobsInList(const JobList &JL, PerformJobsState &State) {
assert(State.BlockingCommands.empty() &&
"some blocking commands never finished properly");
} else {
// Make sure we record any files that haven't been touched but nonetheless
// need to be rebuilt.
// Make sure we record any files that still need to be rebuilt.
for (const Job *Cmd : JL) {
switch (Cmd->getCondition()) {
case Job::Condition::Always:
// Don't worry about files that would be rebuilt anyway.
// Skip files that don't use dependency analysis.
StringRef DependenciesFile =
Cmd->getOutput().getAdditionalOutputForType(types::TY_SwiftDeps);
if (DependenciesFile.empty())
continue;
case Job::Condition::CheckDependencies:
break;
}
// Don't worry about commands that finished or weren't going to run.
if (State.FinishedCommands.count(Cmd))
@@ -349,6 +348,7 @@ int Compilation::performJobsInList(const JobList &JL, PerformJobsState &State) {
if (!State.ScheduledCommands.count(Cmd))
continue;
State.UnfinishedCommands.insert({Cmd, DepGraph.isMarked(Cmd)});
}
}
@@ -373,6 +373,7 @@ int Compilation::performSingleCommand(const Job *Cmd) {
switch (Cmd->getCondition()) {
case Job::Condition::CheckDependencies:
return 0;
case Job::Condition::RunWithoutCascading:
case Job::Condition::Always:
break;
}