Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(616)

Side by Side Diff: pylib/gyp/input.py

Issue 1506733002: GYP: Make GYP build deterministic (Closed) Base URL: https://chromium.googlesource.com/external/gyp.git@master
Patch Set: All tested Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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]
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698