diff options
author | Android Chromium Automerger <chromium-automerger@android> | 2014-07-31 02:31:31 +0000 |
---|---|---|
committer | Android Chromium Automerger <chromium-automerger@android> | 2014-07-31 02:31:31 +0000 |
commit | 184447a86e6c01ecb2a0b9bed8d08290d252c989 (patch) | |
tree | f6f76ef714a625269daf1492f9016a5c576579a1 | |
parent | ca71079834e202e1e137343d755322b4795f6084 (diff) | |
parent | ac2684beed6e8ca04ac5f837c9db869eefec7bb5 (diff) | |
download | gyp-184447a86e6c01ecb2a0b9bed8d08290d252c989.tar.gz |
Merge tools/gyp from https://chromium.googlesource.com/external/gyp.git at ac2684beed6e8ca04ac5f837c9db869eefec7bb5
This commit was generated by merge_from_chromium.py.
Change-Id: I36616486742ab4c073a2b5e3baf84a21d3150b97
-rw-r--r-- | pylib/gyp/generator/analyzer.py | 39 | ||||
-rw-r--r-- | pylib/gyp/input.py | 38 | ||||
-rw-r--r-- | pylib/gyp/xcodeproj_file.py | 4 | ||||
-rw-r--r-- | test/analyzer/gyptest-analyzer.new.py | 199 | ||||
-rw-r--r-- | test/mac/gyptest-loadable-module-bundle-product-extension.py | 28 | ||||
-rw-r--r-- | test/mac/loadable-module-bundle-product-extension/src.cc | 7 | ||||
-rw-r--r-- | test/mac/loadable-module-bundle-product-extension/test.gyp | 24 |
7 files changed, 314 insertions, 25 deletions
diff --git a/pylib/gyp/generator/analyzer.py b/pylib/gyp/generator/analyzer.py index 6f3b610c..dc55da67 100644 --- a/pylib/gyp/generator/analyzer.py +++ b/pylib/gyp/generator/analyzer.py @@ -9,11 +9,15 @@ and targets to search for. The following keys are supported: files: list of paths (relative) of the files to search for. targets: list of targets to search for. The target names are unqualified. -The following (as JSON) is output: +The following is output: error: only supplied if there is an error. +warning: only supplied if there is a warning. targets: the set of targets passed in via targets that either directly or indirectly depend upon the set of paths supplied in files. status: indicates if any of the supplied files matched at least one target. + +If the generator flag analyzer_output_path is specified, output is written +there. Otherwise output is written to stdout. """ import gyp.common @@ -293,6 +297,20 @@ def _GetTargetsDependingOn(all_targets, possible_targets): found.append(gyp.common.ParseQualifiedTarget(target)[1]) return found +def _WriteOutput(params, **values): + """Writes the output, either to stdout or a file is specified.""" + output_path = params.get('generator_flags', {}).get( + 'analyzer_output_path', None) + if not output_path: + print json.dumps(values) + return + try: + f = open(output_path, 'w') + f.write(json.dumps(values) + '\n') + f.close() + except IOError as e: + print 'Error writing to output file', output_path, str(e) + def CalculateVariables(default_variables, params): """Calculate additional variables for use in the build (called by gyp).""" flavor = gyp.common.GetFlavor(params) @@ -342,6 +360,7 @@ def GenerateOutput(target_list, target_dicts, data, params): print found_dependency_string if matched else no_dependency_string return + warning = None if matched: unqualified_mapping = _GetUnqualifiedToQualifiedMapping( all_targets, config.targets) @@ -350,15 +369,21 @@ def GenerateOutput(target_list, target_dicts, data, params): for target in config.targets: if not target in unqualified_mapping: not_found.append(target) - raise Exception('Unable to find all targets: ' + str(not_found)) - qualified_targets = [unqualified_mapping[x] for x in config.targets] + warning = 'Unable to find all targets: ' + str(not_found) + qualified_targets = [] + for target in config.targets: + if target in unqualified_mapping: + qualified_targets.append(unqualified_mapping[target]) output_targets = _GetTargetsDependingOn(all_targets, qualified_targets) else: output_targets = [] - print json.dumps( - {'targets': output_targets, - 'status': found_dependency_string if matched else no_dependency_string }) + result_dict = { 'targets': output_targets, + 'status': found_dependency_string if matched else + no_dependency_string } + if warning: + result_dict['warning'] = warning + _WriteOutput(params, **result_dict) except Exception as e: - print json.dumps({'error': str(e)}) + _WriteOutput(params, error=str(e)) diff --git a/pylib/gyp/input.py b/pylib/gyp/input.py index e0813f35..bb853a54 100644 --- a/pylib/gyp/input.py +++ b/pylib/gyp/input.py @@ -994,23 +994,29 @@ def ExpandVariables(input, phase, variables, build_file): # Prepare for the next match iteration. input_str = output - # Look for more matches now that we've replaced some, to deal with - # expanding local variables (variables defined in the same - # variables block as this one). - gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output) - if type(output) is list: - if output and type(output[0]) is list: - # Leave output alone if it's a list of lists. - # We don't want such lists to be stringified. - pass - else: - new_output = [] - for item in output: - new_output.append( - ExpandVariables(item, phase, variables, build_file)) - output = new_output + if output == input: + gyp.DebugOutput(gyp.DEBUG_VARIABLES, + "Found only identity matches on %r, avoiding infinite " + "recursion.", + output) else: - output = ExpandVariables(output, phase, variables, build_file) + # Look for more matches now that we've replaced some, to deal with + # expanding local variables (variables defined in the same + # variables block as this one). + gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output) + if type(output) is list: + if output and type(output[0]) is list: + # Leave output alone if it's a list of lists. + # We don't want such lists to be stringified. + pass + else: + new_output = [] + for item in output: + new_output.append( + ExpandVariables(item, phase, variables, build_file)) + output = new_output + else: + output = ExpandVariables(output, phase, variables, build_file) # Convert all strings that are canonically-represented integers into integers. if type(output) is list: diff --git a/pylib/gyp/xcodeproj_file.py b/pylib/gyp/xcodeproj_file.py index 2b91f5fb..7c7f1fbd 100644 --- a/pylib/gyp/xcodeproj_file.py +++ b/pylib/gyp/xcodeproj_file.py @@ -2316,11 +2316,11 @@ class PBXNativeTarget(XCTarget): if force_extension is not None: # If it's a wrapper (bundle), set WRAPPER_EXTENSION. + # Extension override. + suffix = '.' + force_extension if filetype.startswith('wrapper.'): self.SetBuildSetting('WRAPPER_EXTENSION', force_extension) else: - # Extension override. - suffix = '.' + force_extension self.SetBuildSetting('EXECUTABLE_EXTENSION', force_extension) if filetype.startswith('compiled.mach-o.executable'): diff --git a/test/analyzer/gyptest-analyzer.new.py b/test/analyzer/gyptest-analyzer.new.py new file mode 100644 index 00000000..db7e1251 --- /dev/null +++ b/test/analyzer/gyptest-analyzer.new.py @@ -0,0 +1,199 @@ +#!/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. + +"""Tests for analyzer +""" + +import json +import TestGyp + +# TODO(sky): when done migrating recipes rename to gyptest-analyzer and nuke +# existing gyptest-analyzer. + +found = 'Found dependency' +not_found = 'No dependencies' + +def _CreateTestFile(files, targets): + f = open('test_file', 'w') + to_write = {'files': files, 'targets': targets } + json.dump(to_write, f) + f.close() + +def _CreateBogusTestFile(): + f = open('test_file','w') + f.write('bogus') + f.close() + +def _ReadOutputFileContents(): + f = open('analyzer_output', 'r') + result = json.load(f) + f.close() + return result + +# NOTE: this would be clearer if it subclassed TestGypCustom, but that trips +# over a bug in pylint (E1002). +test = TestGyp.TestGypCustom(format='analyzer') + +def run_analyzer(*args, **kw): + """Runs the test specifying a particular config and output path.""" + args += ('-Gconfig_path=test_file', + '-Ganalyzer_output_path=analyzer_output') + test.run_gyp('test.gyp', *args, **kw) + +def EnsureContains(targets=set(), matched=False): + """Verifies output contains |targets| and |direct_targets|.""" + result = _ReadOutputFileContents() + if result.get('error', None): + print 'unexpected error', result.get('error') + test.fail_test() + + if result.get('warning', None): + print 'unexpected warning', result.get('warning') + test.fail_test() + + actual_targets = set(result['targets']) + if actual_targets != targets: + print 'actual targets:', actual_targets, '\nexpected targets:', targets + test.fail_test() + + if matched and result['status'] != found: + print 'expected', found, 'got', result['status'] + test.fail_test() + elif not matched and result['status'] != not_found: + print 'expected', not_found, 'got', result['status'] + test.fail_test() + +def EnsureError(expected_error_string): + """Verifies output contains the error string.""" + result = _ReadOutputFileContents() + if result.get('error', '').find(expected_error_string) == -1: + print 'actual error:', result.get('error', ''), '\nexpected error:', \ + expected_error_string + test.fail_test() + +def EnsureWarning(expected_warning_string): + """Verifies output contains the warning string.""" + result = _ReadOutputFileContents() + if result.get('warning', '').find(expected_warning_string) == -1: + print 'actual warning:', result.get('warning', ''), \ + '\nexpected warning:', expected_warning_string + test.fail_test() + +# Verifies file_path must be specified. +test.run_gyp('test.gyp', + stdout='Must specify files to analyze via file_path generator ' + 'flag\n') + +# Verifies config_path must point to a valid file. +test.run_gyp('test.gyp', '-Gconfig_path=bogus_file', + '-Ganalyzer_output_path=analyzer_output') +EnsureError('Unable to open file bogus_file') + +# Verify get error when bad target is specified. +_CreateTestFile(['exe2.c'], ['bad_target']) +run_analyzer() +EnsureWarning('Unable to find all targets') + +# Verifies config_path must point to a valid json file. +_CreateBogusTestFile() +run_analyzer() +EnsureError('Unable to parse config file test_file') + +# Trivial test of a source. +_CreateTestFile(['foo.c'], []) +run_analyzer() +EnsureContains(matched=True) + +# Conditional source that is excluded. +_CreateTestFile(['conditional_source.c'], []) +run_analyzer() +EnsureContains(matched=False) + +# Conditional source that is included by way of argument. +_CreateTestFile(['conditional_source.c'], []) +run_analyzer('-Dtest_variable=1') +EnsureContains(matched=True) + +# Two unknown files. +_CreateTestFile(['unknown1.c', 'unoknow2.cc'], []) +run_analyzer() +EnsureContains() + +# Two unknown files. +_CreateTestFile(['unknown1.c', 'subdir/subdir_sourcex.c'], []) +run_analyzer() +EnsureContains() + +# Included dependency +_CreateTestFile(['unknown1.c', 'subdir/subdir_source.c'], []) +run_analyzer() +EnsureContains(matched=True) + +# Included inputs to actions. +_CreateTestFile(['action_input.c'], []) +run_analyzer() +EnsureContains(matched=True) + +# Don't consider outputs. +_CreateTestFile(['action_output.c'], []) +run_analyzer() +EnsureContains(matched=False) + +# Rule inputs. +_CreateTestFile(['rule_input.c'], []) +run_analyzer() +EnsureContains(matched=True) + +# Ignore path specified with PRODUCT_DIR. +_CreateTestFile(['product_dir_input.c'], []) +run_analyzer() +EnsureContains(matched=False) + +# Path specified via a variable. +_CreateTestFile(['subdir/subdir_source2.c'], []) +run_analyzer() +EnsureContains(matched=True) + +# Verifies paths with // are fixed up correctly. +_CreateTestFile(['parent_source.c'], []) +run_analyzer() +EnsureContains(matched=True) + +# Verifies relative paths are resolved correctly. +_CreateTestFile(['subdir/subdir_source.h'], []) +run_analyzer() +EnsureContains(matched=True) + +# Various permutations when passing in targets. +_CreateTestFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe', 'exe3']) +run_analyzer() +EnsureContains(matched=True, targets={'exe3'}) + +_CreateTestFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe']) +run_analyzer() +EnsureContains(matched=True) + +# Verifies duplicates are ignored. +_CreateTestFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe', 'exe']) +run_analyzer() +EnsureContains(matched=True) + +_CreateTestFile(['exe2.c'], ['exe']) +run_analyzer() +EnsureContains(matched=True) + +_CreateTestFile(['exe2.c'], []) +run_analyzer() +EnsureContains(matched=True) + +_CreateTestFile(['subdir/subdir2b_source.c', 'exe2.c'], []) +run_analyzer() +EnsureContains(matched=True) + +_CreateTestFile(['exe2.c'], []) +run_analyzer() +EnsureContains(matched=True) + +test.pass_test() diff --git a/test/mac/gyptest-loadable-module-bundle-product-extension.py b/test/mac/gyptest-loadable-module-bundle-product-extension.py new file mode 100644 index 00000000..90c20837 --- /dev/null +++ b/test/mac/gyptest-loadable-module-bundle-product-extension.py @@ -0,0 +1,28 @@ +#!/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. + +""" +Tests that loadable_modules don't collide when using the same name with +different file extensions. +""" + +import TestGyp + +import os +import struct +import sys + +if sys.platform == 'darwin': + test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode']) + + CHDIR = 'loadable-module-bundle-product-extension' + test.run_gyp('test.gyp', chdir=CHDIR) + test.build('test.gyp', test.ALL, chdir=CHDIR) + + test.must_exist(test.built_file_path('Collide.foo', chdir=CHDIR)) + test.must_exist(test.built_file_path('Collide.bar', chdir=CHDIR)) + + test.pass_test() diff --git a/test/mac/loadable-module-bundle-product-extension/src.cc b/test/mac/loadable-module-bundle-product-extension/src.cc new file mode 100644 index 00000000..3d878e96 --- /dev/null +++ b/test/mac/loadable-module-bundle-product-extension/src.cc @@ -0,0 +1,7 @@ +// 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. + +int test() { + return 1337; +} diff --git a/test/mac/loadable-module-bundle-product-extension/test.gyp b/test/mac/loadable-module-bundle-product-extension/test.gyp new file mode 100644 index 00000000..684a2c02 --- /dev/null +++ b/test/mac/loadable-module-bundle-product-extension/test.gyp @@ -0,0 +1,24 @@ +# 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': 'test', + 'type': 'none', + 'dependencies': ['child_one', 'child_two'], + }, { + 'target_name': 'child_one', + 'product_name': 'Collide', + 'product_extension': 'bar', + 'sources': ['src.cc'], + 'type': 'loadable_module', + 'mac_bundle': 1, + }, { + 'target_name': 'child_two', + 'product_name': 'Collide', + 'product_extension': 'foo', + 'sources': ['src.cc'], + 'type': 'loadable_module', + 'mac_bundle': 1, + }], +} |