Chromium Code Reviews| Index: pylib/gyp/xcode_emulation.py |
| =================================================================== |
| --- pylib/gyp/xcode_emulation.py (revision 1364) |
| +++ pylib/gyp/xcode_emulation.py (working copy) |
| @@ -979,6 +979,7 @@ |
| """Takes a dict |env| whose values are strings that can refer to other keys, |
| for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of |
| env such that key2 is after key1 in L if env[key2] refers to env[key1]. |
| + (This is really reversed topological order). |
|
Nico
2012/05/10 19:20:23
Remove useless comment addition
bradn
2012/05/10 20:17:56
Yeah the double reversing thing seems goofy.
I had
|
| Throws an Exception in case of dependency cycles. |
| """ |
| @@ -986,62 +987,22 @@ |
| # order is important. Below is the logic to compute the dependency graph |
| # and sort it. |
| regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}') |
| - |
| - # First sort the list of keys. |
| - key_list = sorted(env.keys()) |
| - |
| - # Phase 1: Create a set of edges of (DEPENDEE, DEPENDER) where in the graph, |
| - # DEPENDEE -> DEPENDER. Also create sets of dependers and dependees. |
| - edges = set() |
| - dependees = set() |
| - dependers = set() |
| - for k in key_list: |
| - matches = regex.findall(env[k]) |
| - if not len(matches): |
| - continue |
| - |
| - depends_on_other_var = False |
| + def GetEdges(node): |
| + # Get all variable references for variable defined in env. |
| + matches = set([v for v in regex.findall(env[node]) if v in env]) |
| for dependee in matches: |
| assert '${' not in dependee, 'Nested variables not supported: ' + dependee |
| - if dependee in env: |
| - edges.add((dependee, k)) |
| - dependees.add(dependee) |
| - depends_on_other_var = True |
| - if depends_on_other_var: |
| - dependers.add(k) |
| + return matches |
| - # Phase 2: Create a list of graph nodes with no incoming edges. |
| - sorted_nodes = [] |
| - edgeless_nodes = dependees - dependers |
| + try: |
| + order = gyp.common.TopologicallySorted(env.keys(), GetEdges) |
| + order.reverse() |
|
Nico
2012/05/10 19:20:23
Err g.c.TS also reverses last thing. Maybe it shou
bradn
2012/05/10 20:17:56
Yeah, I think I'll just move to forward topologica
|
| + return order |
| + except CycleError, e: |
| + raise Exception( |
| + 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) |
| - # Phase 3: Perform Kahn topological sort. |
| - while len(edgeless_nodes): |
| - # Find a node with no incoming edges, add it to the sorted list, and |
| - # remove it from the list of nodes that aren't part of the graph. |
| - node = edgeless_nodes.pop() |
| - sorted_nodes.append(node) |
| - key_list.remove(node) |
| - # Find all the edges between |node| and other nodes. |
| - edges_to_node = [e for e in edges if e[0] == node] |
| - for edge in edges_to_node: |
| - edges.remove(edge) |
| - # If the node connected to |node| by |edge| has no other incoming edges, |
| - # add it to |edgeless_nodes|. |
| - if not len([e for e in edges if e[1] == edge[1]]): |
| - edgeless_nodes.add(edge[1]) |
| - |
| - # Any remaining edges indicate a cycle. |
| - if len(edges): |
| - raise Exception('Xcode environment variables are cyclically dependent: ' + |
| - str(edges)) |
| - |
| - # Append the "nodes" not in the graph to those that were just sorted. |
| - sorted_nodes.extend(key_list) |
| - |
| - return sorted_nodes |
| - |
| - |
| def GetSpecPostbuildCommands(spec, quiet=False): |
| """Returns the list of postbuilds explicitly defined on |spec|, in a form |
| executable by a shell.""" |