OLD | NEW |
---|---|
1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 from compiler.ast import Const | 5 from compiler.ast import Const |
6 from compiler.ast import Dict | 6 from compiler.ast import Dict |
7 from compiler.ast import Discard | 7 from compiler.ast import Discard |
8 from compiler.ast import List | 8 from compiler.ast import List |
9 from compiler.ast import Module | 9 from compiler.ast import Module |
10 from compiler.ast import Node | 10 from compiler.ast import Node |
11 from compiler.ast import Stmt | 11 from compiler.ast import Stmt |
12 import compiler | 12 import compiler |
13 import gyp.common | 13 import gyp.common |
14 import gyp.simple_copy | 14 import gyp.simple_copy |
15 import multiprocessing | 15 import multiprocessing |
16 import optparse | 16 import optparse |
17 import os.path | 17 import os.path |
18 import re | 18 import re |
19 import shlex | 19 import shlex |
20 import signal | 20 import signal |
21 import subprocess | 21 import subprocess |
22 import sys | 22 import sys |
23 import threading | 23 import threading |
24 import time | 24 import time |
25 import traceback | 25 import traceback |
26 from gyp.common import GypError | 26 from gyp.common import GypError |
27 from gyp.common import OrderedSet | 27 from gyp.common import OrderedSet |
28 from gyp.common import OrderDeterministically | |
29 | |
28 | 30 |
29 | 31 |
30 # A list of types that are treated as linkable. | 32 # A list of types that are treated as linkable. |
31 linkable_types = [ | 33 linkable_types = [ |
32 'executable', | 34 'executable', |
33 'shared_library', | 35 'shared_library', |
34 'loadable_module', | 36 'loadable_module', |
35 'mac_kernel_extension', | 37 'mac_kernel_extension', |
36 ] | 38 ] |
37 | 39 |
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1532 def __repr__(self): | 1534 def __repr__(self): |
1533 return '<DependencyGraphNode: %r>' % self.ref | 1535 return '<DependencyGraphNode: %r>' % self.ref |
1534 | 1536 |
1535 def FlattenToList(self): | 1537 def FlattenToList(self): |
1536 # flat_list is the sorted list of dependencies - actually, the list items | 1538 # flat_list is the sorted list of dependencies - actually, the list items |
1537 # are the "ref" attributes of DependencyGraphNodes. Every target will | 1539 # are the "ref" attributes of DependencyGraphNodes. Every target will |
1538 # appear in flat_list after all of its dependencies, and before all of its | 1540 # appear in flat_list after all of its dependencies, and before all of its |
1539 # dependents. | 1541 # dependents. |
1540 flat_list = OrderedSet() | 1542 flat_list = OrderedSet() |
1541 | 1543 |
1544 def ExtractNodeRef(node): | |
1545 """Extracts the object that the node represents from the given node.""" | |
1546 return node.ref | |
1547 | |
1542 # in_degree_zeros is the list of DependencyGraphNodes that have no | 1548 # in_degree_zeros is the list of DependencyGraphNodes that have no |
1543 # dependencies not in flat_list. Initially, it is a copy of the children | 1549 # dependencies not in flat_list. Initially, it is a copy of the children |
1544 # of this node, because when the graph was built, nodes with no | 1550 # of this node, because when the graph was built, nodes with no |
1545 # dependencies were made implicit dependents of the root node. | 1551 # dependencies were made implicit dependents of the root node. |
1546 in_degree_zeros = set(self.dependents[:]) | 1552 in_degree_zeros = OrderDeterministically(self.dependents[:], |
Nico
2015/12/10 20:30:24
should this just be an gyp.common.OrderedSet?
Zachary Forman
2015/12/30 02:18:43
Nope, that fails the test; I believe because the o
| |
1553 key=ExtractNodeRef) | |
1547 | 1554 |
1548 while in_degree_zeros: | 1555 while in_degree_zeros: |
1549 # Nodes in in_degree_zeros have no dependencies not in flat_list, so they | 1556 # Nodes in in_degree_zeros have no dependencies not in flat_list, so they |
1550 # can be appended to flat_list. Take these nodes out of in_degree_zeros | 1557 # can be appended to flat_list. Take these nodes out of in_degree_zeros |
1551 # as work progresses, so that the next node to process from the list can | 1558 # as work progresses, so that the next node to process from the list can |
1552 # always be accessed at a consistent position. | 1559 # always be accessed at a consistent position. |
1553 node = in_degree_zeros.pop() | 1560 node = in_degree_zeros.pop() |
1554 flat_list.add(node.ref) | 1561 flat_list.add(node.ref) |
1555 | 1562 |
1556 # Look at dependents of the node just added to flat_list. Some of them | 1563 # Look at dependents of the node just added to flat_list. Some of them |
1557 # may now belong in in_degree_zeros. | 1564 # may now belong in in_degree_zeros. |
1558 for node_dependent in node.dependents: | 1565 for node_dependent in OrderDeterministically(node.dependents, |
1566 key=ExtractNodeRef): | |
1559 is_in_degree_zero = True | 1567 is_in_degree_zero = True |
1560 # TODO: We want to check through the | 1568 # TODO: We want to check through the |
1561 # node_dependent.dependencies list but if it's long and we | 1569 # node_dependent.dependencies list but if it's long and we |
1562 # always start at the beginning, then we get O(n^2) behaviour. | 1570 # always start at the beginning, then we get O(n^2) behaviour. |
1563 for node_dependent_dependency in node_dependent.dependencies: | 1571 for node_dependent_dependency in ( |
1572 OrderDeterministically(node_dependent.dependencies, | |
1573 key=ExtractNodeRef)): | |
1564 if not node_dependent_dependency.ref in flat_list: | 1574 if not node_dependent_dependency.ref in flat_list: |
1565 # The dependent one or more dependencies not in flat_list. There | 1575 # The dependent one or more dependencies not in flat_list. There |
1566 # will be more chances to add it to flat_list when examining | 1576 # will be more chances to add it to flat_list when examining |
1567 # it again as a dependent of those other dependencies, provided | 1577 # it again as a dependent of those other dependencies, provided |
1568 # that there are no cycles. | 1578 # that there are no cycles. |
1569 is_in_degree_zero = False | 1579 is_in_degree_zero = False |
1570 break | 1580 break |
1571 | 1581 |
1572 if is_in_degree_zero: | 1582 if is_in_degree_zero: |
1573 # All of the dependent's dependencies are already in flat_list. Add | 1583 # All of the dependent's dependencies are already in flat_list. Add |
1574 # it to in_degree_zeros where it will be processed in a future | 1584 # it to in_degree_zeros where it will be processed in a future |
1575 # iteration of the outer loop. | 1585 # iteration of the outer loop. |
1576 in_degree_zeros.add(node_dependent) | 1586 in_degree_zeros += [node_dependent] |
1577 | 1587 |
1578 return list(flat_list) | 1588 return list(flat_list) |
1579 | 1589 |
1580 def FindCycles(self): | 1590 def FindCycles(self): |
1581 """ | 1591 """ |
1582 Returns a list of cycles in the graph, where each cycle is its own list. | 1592 Returns a list of cycles in the graph, where each cycle is its own list. |
1583 """ | 1593 """ |
1584 results = [] | 1594 results = [] |
1585 visited = set() | 1595 visited = set() |
1586 | 1596 |
(...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2885 ValidateRunAsInTarget(target, target_dict, build_file) | 2895 ValidateRunAsInTarget(target, target_dict, build_file) |
2886 ValidateActionsInTarget(target, target_dict, build_file) | 2896 ValidateActionsInTarget(target, target_dict, build_file) |
2887 | 2897 |
2888 # Generators might not expect ints. Turn them into strs. | 2898 # Generators might not expect ints. Turn them into strs. |
2889 TurnIntIntoStrInDict(data) | 2899 TurnIntIntoStrInDict(data) |
2890 | 2900 |
2891 # TODO(mark): Return |data| for now because the generator needs a list of | 2901 # TODO(mark): Return |data| for now because the generator needs a list of |
2892 # build files that came in. In the future, maybe it should just accept | 2902 # build files that came in. In the future, maybe it should just accept |
2893 # a list, and not the whole data dict. | 2903 # a list, and not the whole data dict. |
2894 return [flat_list, targets, data] | 2904 return [flat_list, targets, data] |
OLD | NEW |