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

Unified Diff: pylib/gyp/generator/analyzer.py

Issue 1402813002: Change analyzer to search for build_targets from supplied targets (Closed) Base URL: https://chromium.googlesource.com/external/gyp@master
Patch Set: make targets same as build_targets Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/analyzer/gyptest-analyzer.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pylib/gyp/generator/analyzer.py
diff --git a/pylib/gyp/generator/analyzer.py b/pylib/gyp/generator/analyzer.py
index f403d4e266b048e59b81512ad43c2a95e37dcc74..0e01e9c811e287e90d9d07f5e7b293ec65f0cdf9 100644
--- a/pylib/gyp/generator/analyzer.py
+++ b/pylib/gyp/generator/analyzer.py
@@ -11,17 +11,32 @@ targets: list of targets to search for. The target names are unqualified.
The following is output:
error: only supplied if there is an error.
-targets: the set of targets passed in via targets that either directly or
- indirectly depend upon the set of paths supplied in files.
build_targets: minimal set of targets that directly depend on the changed
files and need to be built. The expectation is this set of targets is passed
- into a build step.
+ into a build step. The returned values are either values in the supplied
+ targets, or have a dependency on one of the supplied targets.
status: outputs one of three values: none of the supplied files were found,
one of the include files changed so that it should be assumed everything
changed (in this case targets and build_targets are not output) or at
least one file was found.
invalid_targets: list of supplied targets thare were not found.
+Example:
+Consider a graph like the following:
+ A D
+ / \
+B C
+A depends upon both B and C, A is of type none and B and C are executables.
+D is an executable, has no dependencies and nothing depends on it.
+If |targets| = ["A"] and files = ["b.cc", "d.cc"] (B depends upon b.cc and D
+depends upon d.cc), then the following is output:
+|build_targets| = ["B"] B must built as it depends upon the changed file b.cc
+and the supplied target A depends upon it. A is not output as a build_target
+as it is of type none with no rules and actions.
+
+Even though the file d.cc, which D depends upon, has changed D is not output
+as none of the supplied targets (A) depend upon D.
+
If the generator flag analyzer_output_path is specified, output is written
there. Otherwise output is written to stdout.
"""
@@ -259,13 +274,12 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir):
def _GetOrCreateTargetByName(targets, target_name):
"""Creates or returns the Target at targets[target_name]. If there is no
- Target for |target_name| one is created. Returns a tuple of whether a new
- Target was created and the Target."""
+ Target for |target_name| one is created."""
if target_name in targets:
- return False, targets[target_name]
+ return targets[target_name]
target = Target(target_name)
targets[target_name] = target
- return True, target
+ return target
def _DoesTargetTypeRequireBuild(target_dict):
@@ -280,7 +294,6 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files,
"""Returns a tuple of the following:
. A dictionary mapping from fully qualified name to Target.
. A list of the targets that have a source file in |files|.
- . Set of root Targets reachable from the the files |build_files|.
This sets the |match_status| of the targets that contain any of the source
files in |files| to MATCH_STATUS_MATCHES.
|toplevel_dir| is the root of the source tree."""
@@ -297,18 +310,10 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files,
# |files|.
build_file_in_files = {}
- # Root targets across all files.
- roots = set()
-
- # Set of Targets in |build_files|.
- build_file_targets = set()
-
while len(targets_to_visit) > 0:
target_name = targets_to_visit.pop()
- created_target, target = _GetOrCreateTargetByName(targets, target_name)
- if created_target:
- roots.add(target)
- elif target.visited:
+ target = _GetOrCreateTargetByName(targets, target_name)
+ if target.visited:
continue
target.visited = True
@@ -325,9 +330,6 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files,
build_file_in_files[build_file] = \
_WasBuildFileModified(build_file, data, files, toplevel_dir)
- if build_file in build_files:
- build_file_targets.add(target)
-
# If a build file (or any of its included files) is modified we assume all
# targets in the file are modified.
if build_file_in_files[build_file]:
@@ -348,14 +350,12 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files,
for dep in target_dicts[target_name].get('dependencies', []):
targets_to_visit.append(dep)
- created_dep_target, dep_target = _GetOrCreateTargetByName(targets, dep)
- if not created_dep_target:
- roots.discard(dep_target)
+ dep_target = _GetOrCreateTargetByName(targets, dep)
target.deps.add(dep_target)
dep_target.back_deps.add(target)
- return targets, matching_targets, roots & build_file_targets
+ return targets, matching_targets
def _GetUnqualifiedToTargetMapping(all_targets, to_find):
@@ -375,51 +375,19 @@ def _GetUnqualifiedToTargetMapping(all_targets, to_find):
return result
-def _DoesTargetDependOn(target):
- """Returns true if |target| or any of its dependencies matches the supplied
- set of paths. This updates |matches| of the Targets as it recurses.
- target: the Target to look for."""
- if target.match_status == MATCH_STATUS_DOESNT_MATCH:
- return False
- if target.match_status == MATCH_STATUS_MATCHES or \
- target.match_status == MATCH_STATUS_MATCHES_BY_DEPENDENCY:
- return True
- for dep in target.deps:
- if _DoesTargetDependOn(dep):
- target.match_status = MATCH_STATUS_MATCHES_BY_DEPENDENCY
- print '\t', target.name, 'matches by dep', dep.name
- return True
- target.match_status = MATCH_STATUS_DOESNT_MATCH
- return False
-
-
-def _GetTargetsDependingOn(possible_targets):
- """Returns the list of Targets in |possible_targets| that depend (either
- directly on indirectly) on the matched targets.
- possible_targets: targets to search from."""
- found = []
- print 'Targets that matched by dependency:'
- for target in possible_targets:
- if _DoesTargetDependOn(target):
- found.append(target)
- return found
-
-
-def _AddBuildTargets(target, roots, add_if_no_ancestor, result):
+def _AddBuildTargets(target, roots, result):
"""Recurses through all targets that depend on |target|, adding all targets
that need to be built (and are in |roots|) to |result|.
roots: set of root targets.
- add_if_no_ancestor: If true and there are no ancestors of |target| then add
- |target| to |result|. |target| must still be in |roots|.
result: targets that need to be built are added here."""
if target.visited:
return
target.visited = True
- target.in_roots = not target.back_deps and target in roots
+ target.in_roots = target in roots
for back_dep_target in target.back_deps:
- _AddBuildTargets(back_dep_target, roots, False, result)
+ _AddBuildTargets(back_dep_target, roots, result)
target.added_to_compile_targets |= back_dep_target.added_to_compile_targets
target.in_roots |= back_dep_target.in_roots
target.is_or_has_linked_ancestor |= (
@@ -433,16 +401,14 @@ def _AddBuildTargets(target, roots, add_if_no_ancestor, result):
# static libraries themselves, which are not compile time dependencies.
if target.in_roots and \
(target.is_executable or
- (not target.added_to_compile_targets and
- (add_if_no_ancestor or target.requires_build)) or
- (target.is_static_library and add_if_no_ancestor and
- not target.is_or_has_linked_ancestor)):
+ (not target.added_to_compile_targets and target.requires_build) or
+ (target.is_static_library and not target.is_or_has_linked_ancestor)):
print '\t\tadding to build targets', target.name, 'executable', \
target.is_executable, 'added_to_compile_targets', \
- target.added_to_compile_targets, 'add_if_no_ancestor', \
- add_if_no_ancestor, 'requires_build', target.requires_build, \
- 'is_static_library', target.is_static_library, \
- 'is_or_has_linked_ancestor', target.is_or_has_linked_ancestor
+ target.added_to_compile_targets, 'requires_build', \
+ target.requires_build, 'is_static_library', \
+ target.is_static_library, 'is_or_has_linked_ancestor', \
+ target.is_or_has_linked_ancestor
result.add(target)
target.added_to_compile_targets = True
@@ -454,7 +420,7 @@ def _GetBuildTargets(matching_targets, roots):
result = set()
for target in matching_targets:
print '\tfinding build targets for match', target.name
- _AddBuildTargets(target, roots, True, result)
+ _AddBuildTargets(target, roots, result)
return result
@@ -557,14 +523,10 @@ def GenerateOutput(target_list, target_dicts, data, params):
_WriteOutput(params, **result_dict)
return
- all_targets, matching_targets, roots = _GenerateTargets(
+ all_targets, matching_targets = _GenerateTargets(
data, target_list, target_dicts, toplevel_dir, frozenset(config.files),
params['build_files'])
- print 'roots:'
- for root in roots:
- print '\t', root.name
-
unqualified_mapping = _GetUnqualifiedToTargetMapping(all_targets,
config.targets)
invalid_targets = None
@@ -579,24 +541,18 @@ def GenerateOutput(target_list, target_dicts, data, params):
print 'expanded supplied targets'
for target in search_targets:
print '\t', target.name
- matched_search_targets = _GetTargetsDependingOn(search_targets)
- print 'raw matched search targets:'
- for target in matched_search_targets:
- print '\t', target.name
# Reset the visited status for _GetBuildTargets.
for target in all_targets.itervalues():
target.visited = False
print 'Finding build targets'
- build_targets = _GetBuildTargets(matching_targets, roots)
- matched_search_targets = [gyp.common.ParseQualifiedTarget(target.name)[1]
- for target in matched_search_targets]
+ build_targets = _GetBuildTargets(matching_targets, search_targets)
build_targets = [gyp.common.ParseQualifiedTarget(target.name)[1]
for target in build_targets]
else:
- matched_search_targets = []
build_targets = []
- result_dict = { 'targets': matched_search_targets,
+ # TODO(sky): nuke 'targets'.
+ result_dict = { 'targets': build_targets,
'status': found_dependency_string if matching_targets else
no_dependency_string,
'build_targets': build_targets}
« no previous file with comments | « no previous file | test/analyzer/gyptest-analyzer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698