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 import copy | 5 import copy |
6 import ntpath | 6 import ntpath |
7 import os | 7 import os |
8 import posixpath | 8 import posixpath |
9 import re | 9 import re |
10 import subprocess | 10 import subprocess |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 'msvs_cygwin_dirs', | 59 'msvs_cygwin_dirs', |
60 'msvs_props', | 60 'msvs_props', |
61 ] | 61 ] |
62 | 62 |
63 | 63 |
64 generator_additional_non_configuration_keys = [ | 64 generator_additional_non_configuration_keys = [ |
65 'msvs_cygwin_dirs', | 65 'msvs_cygwin_dirs', |
66 'msvs_cygwin_shell', | 66 'msvs_cygwin_shell', |
67 'msvs_large_pdb', | 67 'msvs_large_pdb', |
68 'msvs_shard', | 68 'msvs_shard', |
| 69 'msvs_external_builder', |
| 70 'msvs_external_builder_out_dir', |
| 71 'msvs_external_builder_build_cmd', |
| 72 'msvs_external_builder_clean_cmd', |
69 ] | 73 ] |
70 | 74 |
71 | 75 |
72 # List of precompiled header related keys. | 76 # List of precompiled header related keys. |
73 precomp_keys = [ | 77 precomp_keys = [ |
74 'msvs_precompiled_header', | 78 'msvs_precompiled_header', |
75 'msvs_precompiled_source', | 79 'msvs_precompiled_source', |
76 ] | 80 ] |
77 | 81 |
78 | 82 |
(...skipping 1609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1688 guid=guid, | 1692 guid=guid, |
1689 spec=spec, | 1693 spec=spec, |
1690 build_file=build_file, | 1694 build_file=build_file, |
1691 config_platform_overrides=overrides, | 1695 config_platform_overrides=overrides, |
1692 fixpath_prefix=fixpath_prefix) | 1696 fixpath_prefix=fixpath_prefix) |
1693 # Set project toolset if any (MS build only) | 1697 # Set project toolset if any (MS build only) |
1694 if msvs_version.UsesVcxproj(): | 1698 if msvs_version.UsesVcxproj(): |
1695 obj.set_msbuild_toolset( | 1699 obj.set_msbuild_toolset( |
1696 _GetMsbuildToolsetOfProject(proj_path, spec, msvs_version)) | 1700 _GetMsbuildToolsetOfProject(proj_path, spec, msvs_version)) |
1697 projects[qualified_target] = obj | 1701 projects[qualified_target] = obj |
1698 # Set all the dependencies | 1702 # Set all the dependencies, but not if we are using an external builder like |
| 1703 # ninja |
1699 for project in projects.values(): | 1704 for project in projects.values(): |
1700 deps = project.spec.get('dependencies', []) | 1705 if not project.spec.get('msvs_external_builder'): |
1701 deps = [projects[d] for d in deps] | 1706 deps = project.spec.get('dependencies', []) |
1702 project.set_dependencies(deps) | 1707 deps = [projects[d] for d in deps] |
| 1708 project.set_dependencies(deps) |
1703 return projects | 1709 return projects |
1704 | 1710 |
1705 | 1711 |
| 1712 def _InitNinjaFlavor(options, target_list, target_dicts): |
| 1713 """Initialize targets for the ninja flavor. |
| 1714 |
| 1715 This sets up the necessary variables in the targets to generate msvs projects |
| 1716 that use ninja as an external builder. The variables in the spec are only set |
| 1717 if they have not been set. This allows individual specs to override the |
| 1718 default values initialized here. |
| 1719 Arguments: |
| 1720 options: Options provided to the generator. |
| 1721 target_list: List of target pairs: 'base/base.gyp:base'. |
| 1722 target_dicts: Dict of target properties keyed on target pair. |
| 1723 """ |
| 1724 for qualified_target in target_list: |
| 1725 spec = target_dicts[qualified_target] |
| 1726 if spec.get('msvs_external_builder'): |
| 1727 # The spec explicitly defined an external builder, so don't change it. |
| 1728 continue |
| 1729 |
| 1730 path_to_ninja = spec.get('msvs_path_to_ninja', 'ninja.exe') |
| 1731 |
| 1732 spec['msvs_external_builder'] = 'ninja' |
| 1733 if not spec.get('msvs_external_builder_out_dir'): |
| 1734 spec['msvs_external_builder_out_dir'] = \ |
| 1735 options.depth + '/out/$(Configuration)' |
| 1736 if not spec.get('msvs_external_builder_build_cmd'): |
| 1737 spec['msvs_external_builder_build_cmd'] = [ |
| 1738 path_to_ninja, |
| 1739 '-C', |
| 1740 '$(OutDir)', |
| 1741 '$(ProjectName)', |
| 1742 ] |
| 1743 if not spec.get('msvs_external_builder_clean_cmd'): |
| 1744 spec['msvs_external_builder_clean_cmd'] = [ |
| 1745 path_to_ninja, |
| 1746 '-C', |
| 1747 '$(OutDir)', |
| 1748 '-t', |
| 1749 'clean', |
| 1750 '$(ProjectName)', |
| 1751 ] |
| 1752 |
| 1753 |
1706 def CalculateVariables(default_variables, params): | 1754 def CalculateVariables(default_variables, params): |
1707 """Generated variables that require params to be known.""" | 1755 """Generated variables that require params to be known.""" |
1708 | 1756 |
1709 generator_flags = params.get('generator_flags', {}) | 1757 generator_flags = params.get('generator_flags', {}) |
1710 | 1758 |
1711 # Select project file format version (if unset, default to auto detecting). | 1759 # Select project file format version (if unset, default to auto detecting). |
1712 msvs_version = MSVSVersion.SelectVisualStudioVersion( | 1760 msvs_version = MSVSVersion.SelectVisualStudioVersion( |
1713 generator_flags.get('msvs_version', 'auto')) | 1761 generator_flags.get('msvs_version', 'auto')) |
1714 # Stash msvs_version for later (so we don't have to probe the system twice). | 1762 # Stash msvs_version for later (so we don't have to probe the system twice). |
1715 params['msvs_version'] = msvs_version | 1763 params['msvs_version'] = msvs_version |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 generator_flags = params.get('generator_flags', {}) | 1815 generator_flags = params.get('generator_flags', {}) |
1768 | 1816 |
1769 # Optionally shard targets marked with 'msvs_shard': SHARD_COUNT. | 1817 # Optionally shard targets marked with 'msvs_shard': SHARD_COUNT. |
1770 (target_list, target_dicts) = MSVSUtil.ShardTargets(target_list, target_dicts) | 1818 (target_list, target_dicts) = MSVSUtil.ShardTargets(target_list, target_dicts) |
1771 | 1819 |
1772 # Optionally use the large PDB workaround for targets marked with | 1820 # Optionally use the large PDB workaround for targets marked with |
1773 # 'msvs_large_pdb': 1. | 1821 # 'msvs_large_pdb': 1. |
1774 (target_list, target_dicts) = MSVSUtil.InsertLargePdbShims( | 1822 (target_list, target_dicts) = MSVSUtil.InsertLargePdbShims( |
1775 target_list, target_dicts, generator_default_variables) | 1823 target_list, target_dicts, generator_default_variables) |
1776 | 1824 |
| 1825 # Optionally configure each spec to use ninja as the external builder. |
| 1826 if params.get('flavor') == 'ninja': |
| 1827 _InitNinjaFlavor(options, target_list, target_dicts) |
| 1828 |
1777 # Prepare the set of configurations. | 1829 # Prepare the set of configurations. |
1778 configs = set() | 1830 configs = set() |
1779 for qualified_target in target_list: | 1831 for qualified_target in target_list: |
1780 spec = target_dicts[qualified_target] | 1832 spec = target_dicts[qualified_target] |
1781 for config_name, config in spec['configurations'].iteritems(): | 1833 for config_name, config in spec['configurations'].iteritems(): |
1782 configs.add(_ConfigFullName(config_name, config)) | 1834 configs.add(_ConfigFullName(config_name, config)) |
1783 configs = list(configs) | 1835 configs = list(configs) |
1784 | 1836 |
1785 # Figure out all the projects that will be generated and their guids | 1837 # Figure out all the projects that will be generated and their guids |
1786 project_objects = _CreateProjectObjects(target_list, target_dicts, options, | 1838 project_objects = _CreateProjectObjects(target_list, target_dicts, options, |
(...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2553 msbuild_attributes['IntermediateDirectory'] = intermediate | 2605 msbuild_attributes['IntermediateDirectory'] = intermediate |
2554 if 'CharacterSet' in msbuild_attributes: | 2606 if 'CharacterSet' in msbuild_attributes: |
2555 msbuild_attributes['CharacterSet'] = _ConvertMSVSCharacterSet( | 2607 msbuild_attributes['CharacterSet'] = _ConvertMSVSCharacterSet( |
2556 msbuild_attributes['CharacterSet']) | 2608 msbuild_attributes['CharacterSet']) |
2557 if 'TargetName' not in msbuild_attributes: | 2609 if 'TargetName' not in msbuild_attributes: |
2558 prefix = spec.get('product_prefix', '') | 2610 prefix = spec.get('product_prefix', '') |
2559 product_name = spec.get('product_name', '$(ProjectName)') | 2611 product_name = spec.get('product_name', '$(ProjectName)') |
2560 target_name = prefix + product_name | 2612 target_name = prefix + product_name |
2561 msbuild_attributes['TargetName'] = target_name | 2613 msbuild_attributes['TargetName'] = target_name |
2562 | 2614 |
| 2615 if spec.get('msvs_external_builder'): |
| 2616 external_out_dir = spec.get('msvs_external_builder_out_dir', '.') |
| 2617 msbuild_attributes['OutputDirectory'] = _FixPath(external_out_dir) + '\\' |
| 2618 |
2563 # Make sure that 'TargetPath' matches 'Lib.OutputFile' or 'Link.OutputFile' | 2619 # Make sure that 'TargetPath' matches 'Lib.OutputFile' or 'Link.OutputFile' |
2564 # (depending on the tool used) to avoid MSB8012 warning. | 2620 # (depending on the tool used) to avoid MSB8012 warning. |
2565 msbuild_tool_map = { | 2621 msbuild_tool_map = { |
2566 'executable': 'Link', | 2622 'executable': 'Link', |
2567 'shared_library': 'Link', | 2623 'shared_library': 'Link', |
2568 'loadable_module': 'Link', | 2624 'loadable_module': 'Link', |
2569 'static_library': 'Lib', | 2625 'static_library': 'Lib', |
2570 } | 2626 } |
2571 msbuild_tool = msbuild_tool_map.get(spec['type']) | 2627 msbuild_tool = msbuild_tool_map.get(spec['type']) |
2572 if msbuild_tool: | 2628 if msbuild_tool: |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2951 | 3007 |
2952 gyp_file = os.path.split(project.build_file)[1] | 3008 gyp_file = os.path.split(project.build_file)[1] |
2953 sources, excluded_sources = _PrepareListOfSources(spec, generator_flags, | 3009 sources, excluded_sources = _PrepareListOfSources(spec, generator_flags, |
2954 gyp_file) | 3010 gyp_file) |
2955 # Add rules. | 3011 # Add rules. |
2956 actions_to_add = {} | 3012 actions_to_add = {} |
2957 props_files_of_rules = set() | 3013 props_files_of_rules = set() |
2958 targets_files_of_rules = set() | 3014 targets_files_of_rules = set() |
2959 extension_to_rule_name = {} | 3015 extension_to_rule_name = {} |
2960 list_excluded = generator_flags.get('msvs_list_excluded_files', True) | 3016 list_excluded = generator_flags.get('msvs_list_excluded_files', True) |
2961 _GenerateRulesForMSBuild(project_dir, options, spec, | 3017 |
2962 sources, excluded_sources, | 3018 # Don't generate rules if we are using an external builder like ninja. |
2963 props_files_of_rules, targets_files_of_rules, | 3019 if not spec.get('msvs_external_builder'): |
2964 actions_to_add, extension_to_rule_name) | 3020 _GenerateRulesForMSBuild(project_dir, options, spec, |
| 3021 sources, excluded_sources, |
| 3022 props_files_of_rules, targets_files_of_rules, |
| 3023 actions_to_add, extension_to_rule_name) |
| 3024 |
2965 sources, excluded_sources, excluded_idl = ( | 3025 sources, excluded_sources, excluded_idl = ( |
2966 _AdjustSourcesAndConvertToFilterHierarchy(spec, options, | 3026 _AdjustSourcesAndConvertToFilterHierarchy(spec, options, |
2967 project_dir, sources, | 3027 project_dir, sources, |
2968 excluded_sources, | 3028 excluded_sources, |
2969 list_excluded)) | 3029 list_excluded)) |
2970 _AddActions(actions_to_add, spec, project.build_file) | |
2971 _AddCopies(actions_to_add, spec) | |
2972 | 3030 |
2973 # NOTE: this stanza must appear after all actions have been decided. | 3031 # Don't add actions if we are using an external builder like ninja. |
2974 # Don't excluded sources with actions attached, or they won't run. | 3032 if not spec.get('msvs_external_builder'): |
2975 excluded_sources = _FilterActionsFromExcluded( | 3033 _AddActions(actions_to_add, spec, project.build_file) |
2976 excluded_sources, actions_to_add) | 3034 _AddCopies(actions_to_add, spec) |
| 3035 |
| 3036 # NOTE: this stanza must appear after all actions have been decided. |
| 3037 # Don't excluded sources with actions attached, or they won't run. |
| 3038 excluded_sources = _FilterActionsFromExcluded( |
| 3039 excluded_sources, actions_to_add) |
2977 | 3040 |
2978 exclusions = _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl) | 3041 exclusions = _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl) |
2979 actions_spec, sources_handled_by_action = _GenerateActionsForMSBuild( | 3042 actions_spec, sources_handled_by_action = _GenerateActionsForMSBuild( |
2980 spec, actions_to_add) | 3043 spec, actions_to_add) |
2981 | 3044 |
2982 _GenerateMSBuildFiltersFile(project.path + '.filters', sources, | 3045 _GenerateMSBuildFiltersFile(project.path + '.filters', sources, |
2983 extension_to_rule_name) | 3046 extension_to_rule_name) |
2984 missing_sources = _VerifySourcesExist(sources, project_dir) | 3047 missing_sources = _VerifySourcesExist(sources, project_dir) |
2985 | 3048 |
2986 for configuration in configurations.itervalues(): | 3049 for configuration in configurations.itervalues(): |
(...skipping 28 matching lines...) Expand all Loading... |
3015 content += _GetMSBuildConfigurationGlobalProperties(spec, configurations, | 3078 content += _GetMSBuildConfigurationGlobalProperties(spec, configurations, |
3016 project.build_file) | 3079 project.build_file) |
3017 content += _GetMSBuildToolSettingsSections(spec, configurations) | 3080 content += _GetMSBuildToolSettingsSections(spec, configurations) |
3018 content += _GetMSBuildSources( | 3081 content += _GetMSBuildSources( |
3019 spec, sources, exclusions, extension_to_rule_name, actions_spec, | 3082 spec, sources, exclusions, extension_to_rule_name, actions_spec, |
3020 sources_handled_by_action, list_excluded) | 3083 sources_handled_by_action, list_excluded) |
3021 content += _GetMSBuildProjectReferences(project) | 3084 content += _GetMSBuildProjectReferences(project) |
3022 content += import_cpp_targets_section | 3085 content += import_cpp_targets_section |
3023 content += _GetMSBuildExtensionTargets(targets_files_of_rules) | 3086 content += _GetMSBuildExtensionTargets(targets_files_of_rules) |
3024 | 3087 |
| 3088 if spec.get('msvs_external_builder'): |
| 3089 content += _GetMSBuildExternalBuilderTargets(spec) |
| 3090 |
3025 # TODO(jeanluc) File a bug to get rid of runas. We had in MSVS: | 3091 # TODO(jeanluc) File a bug to get rid of runas. We had in MSVS: |
3026 # has_run_as = _WriteMSVSUserFile(project.path, version, spec) | 3092 # has_run_as = _WriteMSVSUserFile(project.path, version, spec) |
3027 | 3093 |
3028 easy_xml.WriteXmlIfChanged(content, project.path, pretty=True, win32=True) | 3094 easy_xml.WriteXmlIfChanged(content, project.path, pretty=True, win32=True) |
3029 | 3095 |
3030 return missing_sources | 3096 return missing_sources |
3031 | 3097 |
3032 | 3098 |
| 3099 def _GetMSBuildExternalBuilderTargets(spec): |
| 3100 """Return a list of MSBuild targets for external builders. |
| 3101 |
| 3102 Right now, only "Build" and "Clean" targets are generated. |
| 3103 |
| 3104 Arguments: |
| 3105 spec: The gyp target spec. |
| 3106 Returns: |
| 3107 List of MSBuild 'Target' specs. |
| 3108 """ |
| 3109 build_cmd = _BuildCommandLineForRuleRaw( |
| 3110 spec, spec['msvs_external_builder_build_cmd'], |
| 3111 False, False, False, False) |
| 3112 build_target = ['Target', {'Name': 'Build'}] |
| 3113 build_target.append(['Exec', {'Command': build_cmd}]) |
| 3114 |
| 3115 clean_cmd = _BuildCommandLineForRuleRaw( |
| 3116 spec, spec['msvs_external_builder_clean_cmd'], |
| 3117 False, False, False, False) |
| 3118 clean_target = ['Target', {'Name': 'Clean'}] |
| 3119 clean_target.append(['Exec', {'Command': clean_cmd}]) |
| 3120 |
| 3121 return [build_target, clean_target] |
| 3122 |
| 3123 |
3033 def _GetMSBuildExtensions(props_files_of_rules): | 3124 def _GetMSBuildExtensions(props_files_of_rules): |
3034 extensions = ['ImportGroup', {'Label': 'ExtensionSettings'}] | 3125 extensions = ['ImportGroup', {'Label': 'ExtensionSettings'}] |
3035 for props_file in props_files_of_rules: | 3126 for props_file in props_files_of_rules: |
3036 extensions.append(['Import', {'Project': props_file}]) | 3127 extensions.append(['Import', {'Project': props_file}]) |
3037 return [extensions] | 3128 return [extensions] |
3038 | 3129 |
3039 | 3130 |
3040 def _GetMSBuildExtensionTargets(targets_files_of_rules): | 3131 def _GetMSBuildExtensionTargets(targets_files_of_rules): |
3041 targets_node = ['ImportGroup', {'Label': 'ExtensionTargets'}] | 3132 targets_node = ['ImportGroup', {'Label': 'ExtensionTargets'}] |
3042 for targets_file in sorted(targets_files_of_rules): | 3133 for targets_file in sorted(targets_files_of_rules): |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3108 action_spec.extend( | 3199 action_spec.extend( |
3109 # TODO(jeanluc) 'Document' for all or just if as_sources? | 3200 # TODO(jeanluc) 'Document' for all or just if as_sources? |
3110 [['FileType', 'Document'], | 3201 [['FileType', 'Document'], |
3111 ['Command', command], | 3202 ['Command', command], |
3112 ['Message', description], | 3203 ['Message', description], |
3113 ['Outputs', outputs] | 3204 ['Outputs', outputs] |
3114 ]) | 3205 ]) |
3115 if additional_inputs: | 3206 if additional_inputs: |
3116 action_spec.append(['AdditionalInputs', additional_inputs]) | 3207 action_spec.append(['AdditionalInputs', additional_inputs]) |
3117 actions_spec.append(action_spec) | 3208 actions_spec.append(action_spec) |
OLD | NEW |