OLD | NEW |
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 |
(...skipping 2470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2481 raise GypError("Target %s has an invalid target type '%s'. " | 2481 raise GypError("Target %s has an invalid target type '%s'. " |
2482 "Must be one of %s." % | 2482 "Must be one of %s." % |
2483 (target, target_type, '/'.join(VALID_TARGET_TYPES))) | 2483 (target, target_type, '/'.join(VALID_TARGET_TYPES))) |
2484 if (target_dict.get('standalone_static_library', 0) and | 2484 if (target_dict.get('standalone_static_library', 0) and |
2485 not target_type == 'static_library'): | 2485 not target_type == 'static_library'): |
2486 raise GypError('Target %s has type %s but standalone_static_library flag is' | 2486 raise GypError('Target %s has type %s but standalone_static_library flag is' |
2487 ' only valid for static_library type.' % (target, | 2487 ' only valid for static_library type.' % (target, |
2488 target_type)) | 2488 target_type)) |
2489 | 2489 |
2490 | 2490 |
| 2491 def ValidateSourcesInTarget(target, target_dict, build_file, |
| 2492 duplicate_basename_check): |
| 2493 if not duplicate_basename_check: |
| 2494 return |
| 2495 if target_dict.get('type', None) != 'static_library': |
| 2496 return |
| 2497 sources = target_dict.get('sources', []) |
| 2498 basenames = {} |
| 2499 for source in sources: |
| 2500 name, ext = os.path.splitext(source) |
| 2501 is_compiled_file = ext in [ |
| 2502 '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S'] |
| 2503 if not is_compiled_file: |
| 2504 continue |
| 2505 basename = os.path.basename(name) # Don't include extension. |
| 2506 basenames.setdefault(basename, []).append(source) |
| 2507 |
| 2508 error = '' |
| 2509 for basename, files in basenames.iteritems(): |
| 2510 if len(files) > 1: |
| 2511 error += ' %s: %s\n' % (basename, ' '.join(files)) |
| 2512 |
| 2513 if error: |
| 2514 print('static library %s has several files with the same basename:\n' % |
| 2515 target + error + 'libtool on Mac cannot handle that. Use ' |
| 2516 '--no-duplicate-basename-check to disable this validation.') |
| 2517 raise GypError('Duplicate basenames in sources section, see list above') |
| 2518 |
| 2519 |
2491 def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): | 2520 def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): |
2492 """Ensures that the rules sections in target_dict are valid and consistent, | 2521 """Ensures that the rules sections in target_dict are valid and consistent, |
2493 and determines which sources they apply to. | 2522 and determines which sources they apply to. |
2494 | 2523 |
2495 Arguments: | 2524 Arguments: |
2496 target: string, name of target. | 2525 target: string, name of target. |
2497 target_dict: dict, target spec containing "rules" and "sources" lists. | 2526 target_dict: dict, target spec containing "rules" and "sources" lists. |
2498 extra_sources_for_rules: a list of keys to scan for rule matches in | 2527 extra_sources_for_rules: a list of keys to scan for rule matches in |
2499 addition to 'sources'. | 2528 addition to 'sources'. |
2500 """ | 2529 """ |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2701 | 2730 |
2702 global multiple_toolsets | 2731 global multiple_toolsets |
2703 multiple_toolsets = generator_input_info[ | 2732 multiple_toolsets = generator_input_info[ |
2704 'generator_supports_multiple_toolsets'] | 2733 'generator_supports_multiple_toolsets'] |
2705 | 2734 |
2706 global generator_filelist_paths | 2735 global generator_filelist_paths |
2707 generator_filelist_paths = generator_input_info['generator_filelist_paths'] | 2736 generator_filelist_paths = generator_input_info['generator_filelist_paths'] |
2708 | 2737 |
2709 | 2738 |
2710 def Load(build_files, variables, includes, depth, generator_input_info, check, | 2739 def Load(build_files, variables, includes, depth, generator_input_info, check, |
2711 circular_check, parallel, root_targets): | 2740 circular_check, duplicate_basename_check, parallel, root_targets): |
2712 SetGeneratorGlobals(generator_input_info) | 2741 SetGeneratorGlobals(generator_input_info) |
2713 # A generator can have other lists (in addition to sources) be processed | 2742 # A generator can have other lists (in addition to sources) be processed |
2714 # for rules. | 2743 # for rules. |
2715 extra_sources_for_rules = generator_input_info['extra_sources_for_rules'] | 2744 extra_sources_for_rules = generator_input_info['extra_sources_for_rules'] |
2716 | 2745 |
2717 # Load build files. This loads every target-containing build file into | 2746 # Load build files. This loads every target-containing build file into |
2718 # the |data| dictionary such that the keys to |data| are build file names, | 2747 # the |data| dictionary such that the keys to |data| are build file names, |
2719 # and the values are the entire build file contents after "early" or "pre" | 2748 # and the values are the entire build file contents after "early" or "pre" |
2720 # processing has been done and includes have been resolved. | 2749 # processing has been done and includes have been resolved. |
2721 # NOTE: data contains both "target" files (.gyp) and "includes" (.gypi), as | 2750 # NOTE: data contains both "target" files (.gyp) and "includes" (.gypi), as |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2833 target_dict, PHASE_LATELATE, variables, build_file) | 2862 target_dict, PHASE_LATELATE, variables, build_file) |
2834 | 2863 |
2835 # Make sure that the rules make sense, and build up rule_sources lists as | 2864 # Make sure that the rules make sense, and build up rule_sources lists as |
2836 # needed. Not all generators will need to use the rule_sources lists, but | 2865 # needed. Not all generators will need to use the rule_sources lists, but |
2837 # some may, and it seems best to build the list in a common spot. | 2866 # some may, and it seems best to build the list in a common spot. |
2838 # Also validate actions and run_as elements in targets. | 2867 # Also validate actions and run_as elements in targets. |
2839 for target in flat_list: | 2868 for target in flat_list: |
2840 target_dict = targets[target] | 2869 target_dict = targets[target] |
2841 build_file = gyp.common.BuildFile(target) | 2870 build_file = gyp.common.BuildFile(target) |
2842 ValidateTargetType(target, target_dict) | 2871 ValidateTargetType(target, target_dict) |
| 2872 ValidateSourcesInTarget(target, target_dict, build_file, |
| 2873 duplicate_basename_check) |
2843 ValidateRulesInTarget(target, target_dict, extra_sources_for_rules) | 2874 ValidateRulesInTarget(target, target_dict, extra_sources_for_rules) |
2844 ValidateRunAsInTarget(target, target_dict, build_file) | 2875 ValidateRunAsInTarget(target, target_dict, build_file) |
2845 ValidateActionsInTarget(target, target_dict, build_file) | 2876 ValidateActionsInTarget(target, target_dict, build_file) |
2846 | 2877 |
2847 # Generators might not expect ints. Turn them into strs. | 2878 # Generators might not expect ints. Turn them into strs. |
2848 TurnIntIntoStrInDict(data) | 2879 TurnIntIntoStrInDict(data) |
2849 | 2880 |
2850 # TODO(mark): Return |data| for now because the generator needs a list of | 2881 # TODO(mark): Return |data| for now because the generator needs a list of |
2851 # build files that came in. In the future, maybe it should just accept | 2882 # build files that came in. In the future, maybe it should just accept |
2852 # a list, and not the whole data dict. | 2883 # a list, and not the whole data dict. |
2853 return [flat_list, targets, data] | 2884 return [flat_list, targets, data] |
OLD | NEW |