diff options
author | sbaig1@bloomberg.net <sbaig1@bloomberg.net> | 2014-09-26 16:14:11 +0000 |
---|---|---|
committer | sbaig1@bloomberg.net <sbaig1@bloomberg.net> | 2014-09-26 16:14:11 +0000 |
commit | 55e3f25dfe2aa3e3321708d4a2a919a1e4577695 (patch) | |
tree | c4987ecc0a89aa434a19b5a63d4daba2c2c5ca23 | |
parent | 05c509393b3fcf42ee8f10ca7da7842df0434ca7 (diff) | |
download | gyp-55e3f25dfe2aa3e3321708d4a2a919a1e4577695.tar.gz |
ninja: Don't rerun actions/rules based on where gyp was invoked
Right now, ninja generates unique names for actions/rules by combining the
action/rule name with a hash on the qualified_target. However, the path of the
qualified_target is relative to where gyp was invoked from. So, the following
gyp command:
gyp --depth=. foo/bar.gyp
will generate a different hash than:
cd foo
gyp --depth=../ bar.gyp
Since the hash is different, this causes actions/rules to get rerun based on
where gyp happened to be invoked from.
This commit fixes this issue by using a qualified_target relative to the
toplevel_dir, rather than the current working directory. Also, the
self.qualified_target in NinjaWriter is only used for the hash, so we can
remove it and replace it with a precomputed hash for all actions/rules.
BUG=
R=scottmg@chromium.org
Review URL: https://codereview.chromium.org/607083002
git-svn-id: http://gyp.googlecode.com/svn/trunk@1987 78cadc50-ecff-11dd-a971-7dbc132099af
-rw-r--r-- | pylib/gyp/generator/ninja.py | 16 | ||||
-rw-r--r-- | test/ninja/action-rule-hash/gyptest-action-rule-hash.py | 27 | ||||
-rw-r--r-- | test/ninja/action-rule-hash/subdir/action-rule-hash.gyp | 29 | ||||
-rw-r--r-- | test/ninja/action-rule-hash/subdir/emit.py | 13 |
4 files changed, 78 insertions, 7 deletions
diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py index 7b7f8f23..677ce3c2 100644 --- a/pylib/gyp/generator/ninja.py +++ b/pylib/gyp/generator/ninja.py @@ -213,7 +213,7 @@ class Target: # to the input file name as well as the output target name. class NinjaWriter: - def __init__(self, qualified_target, target_outputs, base_dir, build_dir, + def __init__(self, hash_for_rules, target_outputs, base_dir, build_dir, output_file, toplevel_build, output_file_name, flavor, toplevel_dir=None): """ @@ -223,7 +223,7 @@ class NinjaWriter: toplevel_dir: path to the toplevel directory """ - self.qualified_target = qualified_target + self.hash_for_rules = hash_for_rules self.target_outputs = target_outputs self.base_dir = base_dir self.build_dir = build_dir @@ -591,8 +591,7 @@ class NinjaWriter: all_outputs = [] for action in actions: # First write out a rule for the action. - name = '%s_%s' % (action['action_name'], - hashlib.md5(self.qualified_target).hexdigest()) + name = '%s_%s' % (action['action_name'], self.hash_for_rules) description = self.GenerateDescription('ACTION', action.get('message', None), name) @@ -629,8 +628,7 @@ class NinjaWriter: continue # First write out a rule for the rule action. - name = '%s_%s' % (rule['rule_name'], - hashlib.md5(self.qualified_target).hexdigest()) + name = '%s_%s' % (rule['rule_name'], self.hash_for_rules) args = rule['action'] description = self.GenerateDescription( @@ -2183,6 +2181,10 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, build_file = gyp.common.RelativePath(build_file, options.toplevel_dir) + qualified_target_for_hash = gyp.common.QualifiedTarget(build_file, name, + toolset) + hash_for_rules = hashlib.md5(qualified_target_for_hash).hexdigest() + base_path = os.path.dirname(build_file) obj = 'obj' if toolset != 'target': @@ -2190,7 +2192,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, output_file = os.path.join(obj, base_path, name + '.ninja') ninja_output = StringIO() - writer = NinjaWriter(qualified_target, target_outputs, base_path, build_dir, + writer = NinjaWriter(hash_for_rules, target_outputs, base_path, build_dir, ninja_output, toplevel_build, output_file, flavor, toplevel_dir=options.toplevel_dir) diff --git a/test/ninja/action-rule-hash/gyptest-action-rule-hash.py b/test/ninja/action-rule-hash/gyptest-action-rule-hash.py new file mode 100644 index 00000000..631e176a --- /dev/null +++ b/test/ninja/action-rule-hash/gyptest-action-rule-hash.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +# Copyright (c) 2014 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +Verify that running gyp in a different directory does not cause actions and +rules to rerun. +""" + +import os +import sys +import TestGyp + +test = TestGyp.TestGyp(formats=['ninja']) + +test.run_gyp('subdir/action-rule-hash.gyp') +test.build('subdir/action-rule-hash.gyp', test.ALL) +test.up_to_date('subdir/action-rule-hash.gyp') + +# Verify that everything is still up-to-date when we re-invoke gyp from a +# different directory. +test.run_gyp('action-rule-hash.gyp', '--depth=../', chdir='subdir') +test.up_to_date('subdir/action-rule-hash.gyp') + +test.pass_test() diff --git a/test/ninja/action-rule-hash/subdir/action-rule-hash.gyp b/test/ninja/action-rule-hash/subdir/action-rule-hash.gyp new file mode 100644 index 00000000..0e88a301 --- /dev/null +++ b/test/ninja/action-rule-hash/subdir/action-rule-hash.gyp @@ -0,0 +1,29 @@ +# Copyright (c) 2014 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'targets': [ + { + 'target_name': 'program', + 'type': 'executable', + 'sources': [ + '<(INTERMEDIATE_DIR)/main.cc', + ], + 'actions': [ + { + 'action_name': 'emit_main_cc', + 'inputs': ['emit.py'], + 'outputs': ['<(INTERMEDIATE_DIR)/main.cc'], + 'action': [ + 'python', + 'emit.py', + '<(INTERMEDIATE_DIR)/main.cc', + ], + # Allows the test to run without hermetic cygwin on windows. + 'msvs_cygwin_shell': 0, + }, + ], + }, + ], +} diff --git a/test/ninja/action-rule-hash/subdir/emit.py b/test/ninja/action-rule-hash/subdir/emit.py new file mode 100644 index 00000000..fcb715a9 --- /dev/null +++ b/test/ninja/action-rule-hash/subdir/emit.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +# Copyright (c) 2014 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import sys + +f = open(sys.argv[1], 'wb') +f.write('int main() {\n') +f.write(' return 0;\n') +f.write('}\n') +f.close() |