summaryrefslogtreecommitdiffstats
path: root/pym/emerge
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-09-05 23:09:21 +0000
committerZac Medico <zmedico@gentoo.org>2007-09-05 23:09:21 +0000
commit6df0b0f6bf116d920fe3a98933340dfe52a33280 (patch)
tree730b2665b3185aed89a09213df8ce28ca89f6a1f /pym/emerge
parent5f440bdf16d2963d499c41e3c521bb875067fa2d (diff)
downloadportage-6df0b0f6bf116d920fe3a98933340dfe52a33280.tar.gz
portage-6df0b0f6bf116d920fe3a98933340dfe52a33280.tar.bz2
portage-6df0b0f6bf116d920fe3a98933340dfe52a33280.zip
In the topological sort for merge order, try to avoid selecting root nodes
whenever possible. This helps ensure that the maximimum possible number of soft dependencies have been removed from the graph before their parent nodes have been selected. This is especially important when those dependencies are going to be rebuilt by revdep-rebuild or `emerge -e system` after the CHOST has been changed (like when building a stage3 from a stage2). With this patch, `emerge -e system` properly rebuilds dev-lang/python before sys-apps/file, which helps to avoid a potential build failure. svn path=/main/trunk/; revision=7728
Diffstat (limited to 'pym/emerge')
-rw-r--r--pym/emerge/__init__.py36
1 files changed, 34 insertions, 2 deletions
diff --git a/pym/emerge/__init__.py b/pym/emerge/__init__.py
index 8354da39f..2550da4c4 100644
--- a/pym/emerge/__init__.py
+++ b/pym/emerge/__init__.py
@@ -2246,6 +2246,26 @@ class depgraph(object):
# failed to select any nodes. It is reset whenever nodes are
# successfully selected.
prefer_asap = True
+
+ # By default, try to avoid selecting root nodes whenever possible. This
+ # helps ensure that the maximimum possible number of soft dependencies
+ # have been removed from the graph before their parent nodes have
+ # selected. This is especially important when those dependencies are
+ # going to be rebuilt by revdep-rebuild or `emerge -e system` after the
+ # CHOST has been changed (like when building a stage3 from a stage2).
+ accept_root_node = False
+
+ # State of prefer_asap and accept_root_node flags for successive
+ # iterations that loosen the criteria for node selection.
+ #
+ # iteration prefer_asap accept_root_node
+ # 1 True False
+ # 2 False False
+ # 3 False True
+ #
+ # If no nodes are selected on the 4th iteration, it is due to
+ # unresolved blockers or circular dependencies.
+
while not mygraph.empty():
selected_nodes = None
if prefer_asap and asap_nodes:
@@ -2280,7 +2300,8 @@ class depgraph(object):
# found a non-root node
selected_nodes = [node]
break
- if not selected_nodes:
+ if not selected_nodes and \
+ (accept_root_node or ignore_priority is None):
# settle for a root node
selected_nodes = [nodes[0]]
if not selected_nodes:
@@ -2313,6 +2334,9 @@ class depgraph(object):
for ignore_priority in xrange(DepPriority.SOFT,
DepPriority.MEDIUM_SOFT + 1):
for node in nodes:
+ if not accept_root_node and \
+ not mygraph.parent_nodes(node):
+ continue
selected_nodes = set()
if gather_deps(ignore_priority,
mergeable_nodes, selected_nodes, node):
@@ -2328,6 +2352,12 @@ class depgraph(object):
prefer_asap = False
continue
+ if not selected_nodes and not accept_root_node:
+ # Maybe there are only root nodes left, so accept them
+ # for the next iteration.
+ accept_root_node = True
+ continue
+
if selected_nodes and ignore_priority > DepPriority.SOFT:
# Try to merge ignored medium deps as soon as possible.
for node in selected_nodes:
@@ -2408,8 +2438,10 @@ class depgraph(object):
sys.exit(1)
# At this point, we've succeeded in selecting one or more nodes, so
- # it's now safe to reset the prefer_asap to it's default state.
+ # it's now safe to reset the prefer_asap and accept_root_node flags
+ # to their default states.
prefer_asap = True
+ accept_root_node = False
for node in selected_nodes:
if node[-1] != "nomerge":