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

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

Issue 600149: Check for circular dependencies between .gyp files.... (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « pylib/gyp/__init__.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2009 Google Inc. All rights reserved. 3 # Copyright (c) 2009 Google Inc. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 from compiler.ast import Const 7 from compiler.ast import Const
8 from compiler.ast import Dict 8 from compiler.ast import Dict
9 from compiler.ast import Discard 9 from compiler.ast import Discard
10 from compiler.ast import List 10 from compiler.ast import List
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 # If there's anything left unvisited, there must be a circular dependency 1297 # If there's anything left unvisited, there must be a circular dependency
1298 # (cycle). If you need to figure out what's wrong, look for elements of 1298 # (cycle). If you need to figure out what's wrong, look for elements of
1299 # targets that are not in flat_list. 1299 # targets that are not in flat_list.
1300 if len(flat_list) != len(targets): 1300 if len(flat_list) != len(targets):
1301 raise DependencyGraphNode.CircularException, \ 1301 raise DependencyGraphNode.CircularException, \
1302 'Some targets not reachable, cycle in dependency graph detected' 1302 'Some targets not reachable, cycle in dependency graph detected'
1303 1303
1304 return [dependency_nodes, flat_list] 1304 return [dependency_nodes, flat_list]
1305 1305
1306 1306
1307 def VerifyNoGYPFileCircularDependencies(targets):
1308 # Create a DependencyGraphNode for each gyp file containing a target. Put
1309 # it into a dict for easy access.
1310 dependency_nodes = {}
1311 for target in targets.iterkeys():
1312 build_file = gyp.common.BuildFile(target)
1313 if not build_file in dependency_nodes:
1314 dependency_nodes[build_file] = DependencyGraphNode(build_file)
1315
1316 # Set up the dependency links.
1317 for target, spec in targets.iteritems():
1318 build_file = gyp.common.BuildFile(target)
1319 build_file_node = dependency_nodes[build_file]
1320 target_dependencies = spec.get('dependencies', [])
1321 for dependency in target_dependencies:
1322 try:
1323 dependency_build_file = gyp.common.BuildFile(dependency)
1324 if dependency_build_file == build_file:
1325 # A .gyp file is allowed to refer back to itself.
1326 continue
1327 dependency_node = dependency_nodes[dependency_build_file]
1328 if dependency_node not in build_file_node.dependencies:
1329 build_file_node.dependencies.append(dependency_node)
1330 dependency_node.dependents.append(build_file_node)
1331 except KeyError, e:
1332 gyp.common.ExceptionAppend(
1333 e, 'while computing dependencies of .gyp file %s' % build_file)
1334 raise
1335
1336 # Files that have no dependencies are treated as dependent on root_node.
1337 root_node = DependencyGraphNode(None)
1338 for build_file_node in dependency_nodes.itervalues():
1339 if len(build_file_node.dependencies) == 0:
1340 build_file_node.dependencies.append(root_node)
1341 root_node.dependents.append(build_file_node)
1342
1343 flat_list = root_node.FlattenToList()
1344
1345 # If there's anything left unvisited, there must be a circular dependency
1346 # (cycle).
1347 if len(flat_list) != len(dependency_nodes):
1348 bad_files = []
1349 for file in dependency_nodes.iterkeys():
1350 if not file in flat_list:
1351 bad_files.append(file)
1352 raise DependencyGraphNode.CircularException, \
1353 'Some files not reachable, cycle in .gyp file dependency graph ' + \
1354 'detected involving some or all of: ' + \
1355 ' '.join(bad_files)
1356
1357
1307 def DoDependentSettings(key, flat_list, targets, dependency_nodes): 1358 def DoDependentSettings(key, flat_list, targets, dependency_nodes):
1308 # key should be one of all_dependent_settings, direct_dependent_settings, 1359 # key should be one of all_dependent_settings, direct_dependent_settings,
1309 # or link_settings. 1360 # or link_settings.
1310 1361
1311 for target in flat_list: 1362 for target in flat_list:
1312 target_dict = targets[target] 1363 target_dict = targets[target]
1313 build_file = gyp.common.BuildFile(target) 1364 build_file = gyp.common.BuildFile(target)
1314 1365
1315 if key == 'all_dependent_settings': 1366 if key == 'all_dependent_settings':
1316 dependencies = dependency_nodes[target].DeepDependencies() 1367 dependencies = dependency_nodes[target].DeepDependencies()
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 for index in xrange(0, len(the_list)): 2010 for index in xrange(0, len(the_list)):
1960 item = the_list[index] 2011 item = the_list[index]
1961 if isinstance(item, int): 2012 if isinstance(item, int):
1962 the_list[index] = str(item) 2013 the_list[index] = str(item)
1963 elif isinstance(item, dict): 2014 elif isinstance(item, dict):
1964 TurnIntIntoStrInDict(item) 2015 TurnIntIntoStrInDict(item)
1965 elif isinstance(item, list): 2016 elif isinstance(item, list):
1966 TurnIntIntoStrInList(item) 2017 TurnIntIntoStrInList(item)
1967 2018
1968 2019
1969 def Load(build_files, variables, includes, depth, generator_input_info, check): 2020 def Load(build_files, variables, includes, depth, generator_input_info, check,
2021 circular_check):
1970 # Set up path_sections and non_configuration_keys with the default data plus 2022 # Set up path_sections and non_configuration_keys with the default data plus
1971 # the generator-specifc data. 2023 # the generator-specifc data.
1972 global path_sections 2024 global path_sections
1973 path_sections = base_path_sections[:] 2025 path_sections = base_path_sections[:]
1974 path_sections.extend(generator_input_info['path_sections']) 2026 path_sections.extend(generator_input_info['path_sections'])
1975 2027
1976 global non_configuration_keys 2028 global non_configuration_keys
1977 non_configuration_keys = base_non_configuration_keys[:] 2029 non_configuration_keys = base_non_configuration_keys[:]
1978 non_configuration_keys.extend(generator_input_info['non_configuration_keys']) 2030 non_configuration_keys.extend(generator_input_info['non_configuration_keys'])
1979 2031
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 2067
2016 # Build a dict to access each target's subdict by qualified name. 2068 # Build a dict to access each target's subdict by qualified name.
2017 targets = BuildTargetsDict(data) 2069 targets = BuildTargetsDict(data)
2018 2070
2019 # Fully qualify all dependency links. 2071 # Fully qualify all dependency links.
2020 QualifyDependencies(targets) 2072 QualifyDependencies(targets)
2021 2073
2022 # Expand dependencies specified as build_file:*. 2074 # Expand dependencies specified as build_file:*.
2023 ExpandWildcardDependencies(targets, data) 2075 ExpandWildcardDependencies(targets, data)
2024 2076
2077 if circular_check:
2078 # Make sure that any targets in a.gyp don't contain dependencies in other
2079 # .gyp files that further depend on a.gyp.
2080 VerifyNoGYPFileCircularDependencies(targets)
2081
2025 [dependency_nodes, flat_list] = BuildDependencyList(targets) 2082 [dependency_nodes, flat_list] = BuildDependencyList(targets)
2026 2083
2027 # Handle dependent settings of various types. 2084 # Handle dependent settings of various types.
2028 for settings_type in ['all_dependent_settings', 2085 for settings_type in ['all_dependent_settings',
2029 'direct_dependent_settings', 2086 'direct_dependent_settings',
2030 'link_settings']: 2087 'link_settings']:
2031 DoDependentSettings(settings_type, flat_list, targets, dependency_nodes) 2088 DoDependentSettings(settings_type, flat_list, targets, dependency_nodes)
2032 2089
2033 # Take out the dependent settings now that they've been published to all 2090 # Take out the dependent settings now that they've been published to all
2034 # of the targets that require them. 2091 # of the targets that require them.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2069 ValidateRunAsInTarget(target, target_dict, build_file) 2126 ValidateRunAsInTarget(target, target_dict, build_file)
2070 ValidateActionsInTarget(target, target_dict, build_file) 2127 ValidateActionsInTarget(target, target_dict, build_file)
2071 2128
2072 # Generators might not expect ints. Turn them into strs. 2129 # Generators might not expect ints. Turn them into strs.
2073 TurnIntIntoStrInDict(data) 2130 TurnIntIntoStrInDict(data)
2074 2131
2075 # TODO(mark): Return |data| for now because the generator needs a list of 2132 # TODO(mark): Return |data| for now because the generator needs a list of
2076 # build files that came in. In the future, maybe it should just accept 2133 # build files that came in. In the future, maybe it should just accept
2077 # a list, and not the whole data dict. 2134 # a list, and not the whole data dict.
2078 return [flat_list, targets, data] 2135 return [flat_list, targets, data]
OLDNEW
« no previous file with comments | « pylib/gyp/__init__.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698