Build derivations in a more predictable order
Derivations are now built in order of derivation name, so a package named "aardvark" is built before "baboon". Fixes #399.
This commit is contained in:
parent
9e3389c337
commit
b7b6e3ddec
1 changed files with 41 additions and 7 deletions
|
@ -84,8 +84,12 @@ class Goal;
|
||||||
typedef std::shared_ptr<Goal> GoalPtr;
|
typedef std::shared_ptr<Goal> GoalPtr;
|
||||||
typedef std::weak_ptr<Goal> WeakGoalPtr;
|
typedef std::weak_ptr<Goal> WeakGoalPtr;
|
||||||
|
|
||||||
|
struct CompareGoalPtrs {
|
||||||
|
bool operator() (const GoalPtr & a, const GoalPtr & b);
|
||||||
|
};
|
||||||
|
|
||||||
/* Set of goals. */
|
/* Set of goals. */
|
||||||
typedef set<GoalPtr> Goals;
|
typedef set<GoalPtr, CompareGoalPtrs> Goals;
|
||||||
typedef list<WeakGoalPtr> WeakGoals;
|
typedef list<WeakGoalPtr> WeakGoals;
|
||||||
|
|
||||||
/* A map of paths to goals (and the other way around). */
|
/* A map of paths to goals (and the other way around). */
|
||||||
|
@ -172,11 +176,20 @@ public:
|
||||||
(important!), etc. */
|
(important!), etc. */
|
||||||
virtual void cancel(bool timeout) = 0;
|
virtual void cancel(bool timeout) = 0;
|
||||||
|
|
||||||
|
virtual string key() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void amDone(ExitCode result);
|
void amDone(ExitCode result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) {
|
||||||
|
string s1 = a->key();
|
||||||
|
string s2 = b->key();
|
||||||
|
return s1 < s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A mapping used to remember for each child process to what goal it
|
/* A mapping used to remember for each child process to what goal it
|
||||||
belongs, and file descriptors for receiving log data and output
|
belongs, and file descriptors for receiving log data and output
|
||||||
path creation commands. */
|
path creation commands. */
|
||||||
|
@ -303,6 +316,7 @@ public:
|
||||||
void addToWeakGoals(WeakGoals & goals, GoalPtr p)
|
void addToWeakGoals(WeakGoals & goals, GoalPtr p)
|
||||||
{
|
{
|
||||||
// FIXME: necessary?
|
// FIXME: necessary?
|
||||||
|
// FIXME: O(n)
|
||||||
foreach (WeakGoals::iterator, i, goals)
|
foreach (WeakGoals::iterator, i, goals)
|
||||||
if (i->lock() == p) return;
|
if (i->lock() == p) return;
|
||||||
goals.push_back(p);
|
goals.push_back(p);
|
||||||
|
@ -767,6 +781,15 @@ public:
|
||||||
|
|
||||||
void cancel(bool timeout);
|
void cancel(bool timeout);
|
||||||
|
|
||||||
|
string key()
|
||||||
|
{
|
||||||
|
/* Ensure that derivations get built in order of their name,
|
||||||
|
i.e. a derivation named "aardvark" always comes before
|
||||||
|
"baboon". And substitution goals always happen before
|
||||||
|
derivation goals (due to "b$"). */
|
||||||
|
return "b$" + storePathToName(drvPath) + "$" + drvPath;
|
||||||
|
}
|
||||||
|
|
||||||
void work();
|
void work();
|
||||||
|
|
||||||
Path getDrvPath()
|
Path getDrvPath()
|
||||||
|
@ -2575,6 +2598,13 @@ public:
|
||||||
|
|
||||||
void cancel(bool timeout);
|
void cancel(bool timeout);
|
||||||
|
|
||||||
|
string key()
|
||||||
|
{
|
||||||
|
/* "a$" ensures substitution goals happen before derivation
|
||||||
|
goals. */
|
||||||
|
return "a$" + storePathToName(storePath) + "$" + storePath;
|
||||||
|
}
|
||||||
|
|
||||||
void work();
|
void work();
|
||||||
|
|
||||||
/* The states. */
|
/* The states. */
|
||||||
|
@ -3085,15 +3115,19 @@ void Worker::run(const Goals & _topGoals)
|
||||||
|
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
/* Call every wake goal. */
|
/* Call every wake goal (in the ordering established by
|
||||||
|
CompareGoalPtrs). */
|
||||||
while (!awake.empty() && !topGoals.empty()) {
|
while (!awake.empty() && !topGoals.empty()) {
|
||||||
WeakGoals awake2(awake);
|
Goals awake2;
|
||||||
|
for (auto & i : awake) {
|
||||||
|
GoalPtr goal = i.lock();
|
||||||
|
if (goal) awake2.insert(goal);
|
||||||
|
}
|
||||||
awake.clear();
|
awake.clear();
|
||||||
foreach (WeakGoals::iterator, i, awake2) {
|
for (auto & goal : awake2) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
GoalPtr goal = i->lock();
|
goal->work();
|
||||||
if (goal) goal->work();
|
if (topGoals.empty()) break; // stuff may have been cancelled
|
||||||
if (topGoals.empty()) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue