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 gyp | 6 import gyp |
7 import gyp.common | 7 import gyp.common |
8 import gyp.msvs_emulation | 8 import gyp.msvs_emulation |
| 9 import gyp.MSVSVersion |
9 import gyp.system_test | 10 import gyp.system_test |
10 import gyp.xcode_emulation | 11 import gyp.xcode_emulation |
11 import os.path | 12 import os.path |
12 import re | 13 import re |
13 import subprocess | 14 import subprocess |
14 import sys | 15 import sys |
15 | 16 |
16 import gyp.ninja_syntax as ninja_syntax | 17 import gyp.ninja_syntax as ninja_syntax |
17 | 18 |
18 generator_default_variables = { | 19 generator_default_variables = { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 path = path.replace(PRODUCT_DIR + '\\', '') | 207 path = path.replace(PRODUCT_DIR + '\\', '') |
207 path = path.replace(PRODUCT_DIR, '.') | 208 path = path.replace(PRODUCT_DIR, '.') |
208 | 209 |
209 INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR' | 210 INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR' |
210 if INTERMEDIATE_DIR in path: | 211 if INTERMEDIATE_DIR in path: |
211 int_dir = self.GypPathToUniqueOutput('gen') | 212 int_dir = self.GypPathToUniqueOutput('gen') |
212 # GypPathToUniqueOutput generates a path relative to the product dir, | 213 # GypPathToUniqueOutput generates a path relative to the product dir, |
213 # so insert product_dir in front if it is provided. | 214 # so insert product_dir in front if it is provided. |
214 path = path.replace(INTERMEDIATE_DIR, | 215 path = path.replace(INTERMEDIATE_DIR, |
215 os.path.join(product_dir or '', int_dir)) | 216 os.path.join(product_dir or '', int_dir)) |
216 | |
217 if self.flavor == 'win': | |
218 # Don't use os.path.normpath here. Callers pass in './foo' and expect | |
219 # the result to be runnable, but normpath removes the prefix. | |
220 return path.replace('/', '\\') | |
221 return path | 217 return path |
222 | 218 |
223 def ExpandRuleVariables(self, path, root, dirname, source, ext, name): | 219 def ExpandRuleVariables(self, path, root, dirname, source, ext, name): |
224 path = path.replace(generator_default_variables['RULE_INPUT_ROOT'], root) | 220 path = path.replace(generator_default_variables['RULE_INPUT_ROOT'], root) |
225 path = path.replace(generator_default_variables['RULE_INPUT_DIRNAME'], | 221 path = path.replace(generator_default_variables['RULE_INPUT_DIRNAME'], |
226 dirname) | 222 dirname) |
227 path = path.replace(generator_default_variables['RULE_INPUT_PATH'], source) | 223 path = path.replace(generator_default_variables['RULE_INPUT_PATH'], source) |
228 path = path.replace(generator_default_variables['RULE_INPUT_EXT'], ext) | 224 path = path.replace(generator_default_variables['RULE_INPUT_EXT'], ext) |
229 path = path.replace(generator_default_variables['RULE_INPUT_NAME'], name) | 225 path = path.replace(generator_default_variables['RULE_INPUT_NAME'], name) |
230 return path | 226 return path |
231 | 227 |
232 def GypPathToNinja(self, path, env=None): | 228 def GypPathToNinja(self, path, env=None): |
233 """Translate a gyp path to a ninja path, optionally expanding environment | 229 """Translate a gyp path to a ninja path, optionally expanding environment |
234 variable references in |path| with |env|. | 230 variable references in |path| with |env|. |
235 | 231 |
236 See the above discourse on path conversions.""" | 232 See the above discourse on path conversions.""" |
237 if env: | 233 if env: |
238 path = gyp.xcode_emulation.ExpandEnvVars(path, env) | 234 path = gyp.xcode_emulation.ExpandEnvVars(path, env) |
239 if path.startswith('$!'): | 235 if path.startswith('$!'): |
240 return self.ExpandSpecial(path) | 236 expanded = self.ExpandSpecial(path) |
| 237 if self.flavor == 'win': |
| 238 expanded = os.path.normpath(expanded) |
| 239 return expanded |
241 assert '$' not in path, path | 240 assert '$' not in path, path |
242 return os.path.normpath(os.path.join(self.build_to_base, path)) | 241 return os.path.normpath(os.path.join(self.build_to_base, path)) |
243 | 242 |
244 def GypPathToUniqueOutput(self, path, qualified=True): | 243 def GypPathToUniqueOutput(self, path, qualified=True): |
245 """Translate a gyp path to a ninja path for writing output. | 244 """Translate a gyp path to a ninja path for writing output. |
246 | 245 |
247 If qualified is True, qualify the resulting filename with the name | 246 If qualified is True, qualify the resulting filename with the name |
248 of the target. This is necessary when e.g. compiling the same | 247 of the target. This is necessary when e.g. compiling the same |
249 path twice for two separate output targets. | 248 path twice for two separate output targets. |
250 | 249 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 Returns None if there are no outputs (e.g. a settings-only 'none' type | 295 Returns None if there are no outputs (e.g. a settings-only 'none' type |
297 target).""" | 296 target).""" |
298 | 297 |
299 self.config_name = config_name | 298 self.config_name = config_name |
300 self.name = spec['target_name'] | 299 self.name = spec['target_name'] |
301 self.toolset = spec['toolset'] | 300 self.toolset = spec['toolset'] |
302 config = spec['configurations'][config_name] | 301 config = spec['configurations'][config_name] |
303 self.target = Target(spec['type']) | 302 self.target = Target(spec['type']) |
304 | 303 |
305 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) | 304 self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) |
| 305 self.xcode_settings = self.msvs_settings = None |
306 if self.flavor == 'mac': | 306 if self.flavor == 'mac': |
307 self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) | 307 self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) |
308 else: | 308 if self.flavor == 'win': |
309 self.xcode_settings = None | 309 self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec) |
310 | 310 |
311 # Compute predepends for all rules. | 311 # Compute predepends for all rules. |
312 # actions_depends is the dependencies this target depends on before running | 312 # actions_depends is the dependencies this target depends on before running |
313 # any of its action/rule/copy steps. | 313 # any of its action/rule/copy steps. |
314 # compile_depends is the dependencies this target depends on before running | 314 # compile_depends is the dependencies this target depends on before running |
315 # any of its compile steps. | 315 # any of its compile steps. |
316 actions_depends = [] | 316 actions_depends = [] |
317 compile_depends = [] | 317 compile_depends = [] |
318 # TODO(evan): it is rather confusing which things are lists and which | 318 # TODO(evan): it is rather confusing which things are lists and which |
319 # are strings. Fix these. | 319 # are strings. Fix these. |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 | 576 |
577 def WriteSources(self, config_name, config, sources, predepends, | 577 def WriteSources(self, config_name, config, sources, predepends, |
578 precompiled_header): | 578 precompiled_header): |
579 """Write build rules to compile all of |sources|.""" | 579 """Write build rules to compile all of |sources|.""" |
580 if self.toolset == 'target': | 580 if self.toolset == 'target': |
581 self.ninja.variable('ar', '$ar_target') | 581 self.ninja.variable('ar', '$ar_target') |
582 self.ninja.variable('cc', '$cc_target') | 582 self.ninja.variable('cc', '$cc_target') |
583 self.ninja.variable('cxx', '$cxx_target') | 583 self.ninja.variable('cxx', '$cxx_target') |
584 self.ninja.variable('ld', '$ld_target') | 584 self.ninja.variable('ld', '$ld_target') |
585 | 585 |
| 586 extra_defines = [] |
| 587 extra_includes = [] |
586 if self.flavor == 'mac': | 588 if self.flavor == 'mac': |
587 cflags = self.xcode_settings.GetCflags(config_name) | 589 cflags = self.xcode_settings.GetCflags(config_name) |
588 cflags_c = self.xcode_settings.GetCflagsC(config_name) | 590 cflags_c = self.xcode_settings.GetCflagsC(config_name) |
589 cflags_cc = self.xcode_settings.GetCflagsCC(config_name) | 591 cflags_cc = self.xcode_settings.GetCflagsCC(config_name) |
590 cflags_objc = ['$cflags_c'] + \ | 592 cflags_objc = ['$cflags_c'] + \ |
591 self.xcode_settings.GetCflagsObjC(config_name) | 593 self.xcode_settings.GetCflagsObjC(config_name) |
592 cflags_objcc = ['$cflags_cc'] + \ | 594 cflags_objcc = ['$cflags_cc'] + \ |
593 self.xcode_settings.GetCflagsObjCC(config_name) | 595 self.xcode_settings.GetCflagsObjCC(config_name) |
| 596 elif self.flavor == 'win': |
| 597 cflags = self.msvs_settings.GetCflags(config_name) |
| 598 cflags_c = self.msvs_settings.GetCflagsC(config_name) |
| 599 cflags_cc = self.msvs_settings.GetCflagsCC(config_name) |
| 600 extra_defines = self.msvs_settings.GetComputedDefines(config_name) |
| 601 extra_includes = self.msvs_settings.GetSystemIncludes(config_name) |
594 else: | 602 else: |
595 cflags = config.get('cflags', []) | 603 cflags = config.get('cflags', []) |
596 cflags_c = config.get('cflags_c', []) | 604 cflags_c = config.get('cflags_c', []) |
597 cflags_cc = config.get('cflags_cc', []) | 605 cflags_cc = config.get('cflags_cc', []) |
598 | 606 |
| 607 defines = config.get('defines', []) + extra_defines |
599 self.WriteVariableList('defines', | 608 self.WriteVariableList('defines', |
600 [QuoteShellArgument(ninja_syntax.escape('-D' + d), self.flavor) | 609 [QuoteShellArgument(ninja_syntax.escape('-D' + d), self.flavor) |
601 for d in config.get('defines', [])]) | 610 for d in defines]) |
| 611 include_dirs = config.get('include_dirs', []) + extra_includes |
602 self.WriteVariableList('includes', | 612 self.WriteVariableList('includes', |
603 ['-I' + self.GypPathToNinja(i) | 613 [QuoteShellArgument('-I' + self.GypPathToNinja(i), self.flavor) |
604 for i in config.get('include_dirs', [])]) | 614 for i in include_dirs]) |
605 | 615 |
606 pch_commands = precompiled_header.GetGchBuildCommands() | 616 pch_commands = precompiled_header.GetGchBuildCommands() |
607 if self.flavor == 'mac': | 617 if self.flavor == 'mac': |
608 self.WriteVariableList('cflags_pch_c', | 618 self.WriteVariableList('cflags_pch_c', |
609 [precompiled_header.GetInclude('c')]) | 619 [precompiled_header.GetInclude('c')]) |
610 self.WriteVariableList('cflags_pch_cc', | 620 self.WriteVariableList('cflags_pch_cc', |
611 [precompiled_header.GetInclude('cc')]) | 621 [precompiled_header.GetInclude('cc')]) |
612 self.WriteVariableList('cflags_pch_objc', | 622 self.WriteVariableList('cflags_pch_objc', |
613 [precompiled_header.GetInclude('m')]) | 623 [precompiled_header.GetInclude('m')]) |
614 self.WriteVariableList('cflags_pch_objcc', | 624 self.WriteVariableList('cflags_pch_objcc', |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 output = self.ComputeMacBundleBinaryOutput() | 714 output = self.ComputeMacBundleBinaryOutput() |
705 else: | 715 else: |
706 output = self.ComputeOutput(spec) | 716 output = self.ComputeOutput(spec) |
707 extra_bindings.append(('postbuilds', | 717 extra_bindings.append(('postbuilds', |
708 self.GetPostbuildCommand(spec, output, output))) | 718 self.GetPostbuildCommand(spec, output, output))) |
709 | 719 |
710 if self.flavor == 'mac': | 720 if self.flavor == 'mac': |
711 ldflags = self.xcode_settings.GetLdflags(config_name, | 721 ldflags = self.xcode_settings.GetLdflags(config_name, |
712 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), | 722 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), |
713 self.GypPathToNinja) | 723 self.GypPathToNinja) |
| 724 elif self.flavor == 'win': |
| 725 ldflags = self.msvs_settings.GetLdflags(config_name, |
| 726 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), |
| 727 self.GypPathToNinja) |
714 else: | 728 else: |
715 ldflags = config.get('ldflags', []) | 729 ldflags = config.get('ldflags', []) |
716 self.WriteVariableList('ldflags', | 730 self.WriteVariableList('ldflags', |
717 gyp.common.uniquer(map(self.ExpandSpecial, | 731 gyp.common.uniquer(map(self.ExpandSpecial, |
718 ldflags))) | 732 ldflags))) |
719 | 733 |
720 libraries = gyp.common.uniquer(map(self.ExpandSpecial, | 734 libraries = gyp.common.uniquer(map(self.ExpandSpecial, |
721 spec.get('libraries', []))) | 735 spec.get('libraries', []))) |
722 if self.flavor == 'mac': | 736 if self.flavor == 'mac': |
723 libraries = self.xcode_settings.AdjustLibraries(libraries) | 737 libraries = self.xcode_settings.AdjustLibraries(libraries) |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 global generator_extra_sources_for_rules | 1018 global generator_extra_sources_for_rules |
1005 generator_extra_sources_for_rules = getattr(xcode_generator, | 1019 generator_extra_sources_for_rules = getattr(xcode_generator, |
1006 'generator_extra_sources_for_rules', []) | 1020 'generator_extra_sources_for_rules', []) |
1007 elif flavor == 'win': | 1021 elif flavor == 'win': |
1008 default_variables.setdefault('OS', 'win') | 1022 default_variables.setdefault('OS', 'win') |
1009 default_variables['EXECUTABLE_SUFFIX'] = '.exe' | 1023 default_variables['EXECUTABLE_SUFFIX'] = '.exe' |
1010 default_variables['STATIC_LIB_PREFIX'] = '' | 1024 default_variables['STATIC_LIB_PREFIX'] = '' |
1011 default_variables['STATIC_LIB_SUFFIX'] = '.lib' | 1025 default_variables['STATIC_LIB_SUFFIX'] = '.lib' |
1012 default_variables['SHARED_LIB_PREFIX'] = '' | 1026 default_variables['SHARED_LIB_PREFIX'] = '' |
1013 default_variables['SHARED_LIB_SUFFIX'] = '.dll' | 1027 default_variables['SHARED_LIB_SUFFIX'] = '.dll' |
| 1028 generator_flags = params.get('generator_flags', {}) |
| 1029 msvs_version = gyp.MSVSVersion.SelectVisualStudioVersion( |
| 1030 generator_flags.get('msvs_version', 'auto')) |
| 1031 # Stash msvs_version for later (so we don't have to probe the system twice). |
| 1032 params['msvs_version'] = msvs_version |
| 1033 |
| 1034 # Set a variable so conditions can be based on msvs_version. |
| 1035 default_variables['MSVS_VERSION'] = msvs_version.ShortName() |
| 1036 |
| 1037 # To determine processor word size on Windows, in addition to checking |
| 1038 # PROCESSOR_ARCHITECTURE (which reflects the word size of the current |
| 1039 # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which |
| 1040 # contains the actual word size of the system when running thru WOW64). |
| 1041 if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or |
| 1042 '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')): |
| 1043 default_variables['MSVS_OS_BITS'] = 64 |
| 1044 else: |
| 1045 default_variables['MSVS_OS_BITS'] = 32 |
1014 else: | 1046 else: |
1015 operating_system = flavor | 1047 operating_system = flavor |
1016 if flavor == 'android': | 1048 if flavor == 'android': |
1017 operating_system = 'linux' # Keep this legacy behavior for now. | 1049 operating_system = 'linux' # Keep this legacy behavior for now. |
1018 default_variables.setdefault('OS', operating_system) | 1050 default_variables.setdefault('OS', operating_system) |
1019 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') | 1051 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') |
1020 default_variables.setdefault('SHARED_LIB_DIR', | 1052 default_variables.setdefault('SHARED_LIB_DIR', |
1021 os.path.join('$!PRODUCT_DIR', 'lib')) | 1053 os.path.join('$!PRODUCT_DIR', 'lib')) |
1022 default_variables.setdefault('LIB_DIR', '') | 1054 default_variables.setdefault('LIB_DIR', '') |
1023 | 1055 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 depfile='$out.d') | 1131 depfile='$out.d') |
1100 else: | 1132 else: |
1101 # TODO(scottmg): Requires deplist branch of ninja for now (for | 1133 # TODO(scottmg): Requires deplist branch of ninja for now (for |
1102 # /showIncludes handling). | 1134 # /showIncludes handling). |
1103 master_ninja.rule( | 1135 master_ninja.rule( |
1104 'cc', | 1136 'cc', |
1105 description='CC $out', | 1137 description='CC $out', |
1106 command=('cmd /c $cc /nologo /showIncludes ' | 1138 command=('cmd /c $cc /nologo /showIncludes ' |
1107 '$defines $includes $cflags $cflags_c ' | 1139 '$defines $includes $cflags $cflags_c ' |
1108 '$cflags_pch_c /c $in /Fo$out ' | 1140 '$cflags_pch_c /c $in /Fo$out ' |
1109 '| ninja-deplist-helper -f cl -o $out.dl'), | 1141 '| ninja-deplist-helper -q -f cl -o $out.dl'), |
1110 deplist='$out.dl') | 1142 deplist='$out.dl') |
1111 master_ninja.rule( | 1143 master_ninja.rule( |
1112 'cxx', | 1144 'cxx', |
1113 description='CXX $out', | 1145 description='CXX $out', |
1114 command=('cmd /c $cxx /nologo /showIncludes ' | 1146 command=('cmd /c $cxx /nologo /showIncludes ' |
1115 '$defines $includes $cflags $cflags_cc ' | 1147 '$defines $includes $cflags $cflags_cc ' |
1116 '$cflags_pch_cc /c $in /Fo$out ' | 1148 '$cflags_pch_cc /c $in /Fo$out ' |
1117 '| ninja-deplist-helper -f cl -o $out.dl'), | 1149 '| ninja-deplist-helper -q -f cl -o $out.dl'), |
1118 deplist='$out.dl') | 1150 deplist='$out.dl') |
1119 | 1151 |
1120 if flavor != 'mac' and flavor != 'win': | 1152 if flavor != 'mac' and flavor != 'win': |
1121 master_ninja.rule( | 1153 master_ninja.rule( |
1122 'alink', | 1154 'alink', |
1123 description='AR $out', | 1155 description='AR $out', |
1124 command='rm -f $out && $ar rcsT $out $in') | 1156 command='rm -f $out && $ar rcsT $out $in') |
1125 master_ninja.rule( | 1157 master_ninja.rule( |
1126 'solink', | 1158 'solink', |
1127 description='SOLINK $out', | 1159 description='SOLINK $out', |
(...skipping 10 matching lines...) Expand all Loading... |
1138 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' | 1170 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' |
1139 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1171 '-Wl,--start-group $in -Wl,--end-group $libs')) |
1140 elif flavor == 'win': | 1172 elif flavor == 'win': |
1141 master_ninja.rule( | 1173 master_ninja.rule( |
1142 'alink', | 1174 'alink', |
1143 description='LIB $out', | 1175 description='LIB $out', |
1144 command='lib /nologo /OUT:$out $in') | 1176 command='lib /nologo /OUT:$out $in') |
1145 master_ninja.rule( | 1177 master_ninja.rule( |
1146 'solink', | 1178 'solink', |
1147 description='LINK(DLL) $dll', | 1179 description='LINK(DLL) $dll', |
1148 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) | 1180 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll ' |
| 1181 '/PDB:$dll.pdb $in $libs')) |
1149 master_ninja.rule( | 1182 master_ninja.rule( |
1150 'solink_module', | 1183 'solink_module', |
1151 description='LINK(DLL) $dll', | 1184 description='LINK(DLL) $dll', |
1152 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) | 1185 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll ' |
| 1186 '/PDB:$dll.pdb $in $libs')) |
1153 master_ninja.rule( | 1187 master_ninja.rule( |
1154 'link', | 1188 'link', |
1155 description='LINK $out', | 1189 description='LINK $out', |
1156 command=('$ld /nologo $ldflags /OUT:$out $in $libs')) | 1190 command=('$ld /nologo $ldflags /OUT:$out /PDB:$out.pdb $in $libs')) |
1157 else: | 1191 else: |
1158 master_ninja.rule( | 1192 master_ninja.rule( |
1159 'objc', | 1193 'objc', |
1160 description='OBJC $out', | 1194 description='OBJC $out', |
1161 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' | 1195 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' |
1162 '$cflags_pch_objc -c $in -o $out'), | 1196 '$cflags_pch_objc -c $in -o $out'), |
1163 depfile='$out.d') | 1197 depfile='$out.d') |
1164 master_ninja.rule( | 1198 master_ninja.rule( |
1165 'objcxx', | 1199 'objcxx', |
1166 description='OBJCXX $out', | 1200 description='OBJCXX $out', |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 | 1314 |
1281 user_config = params.get('generator_flags', {}).get('config', None) | 1315 user_config = params.get('generator_flags', {}).get('config', None) |
1282 if user_config: | 1316 if user_config: |
1283 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1317 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1284 user_config) | 1318 user_config) |
1285 else: | 1319 else: |
1286 config_names = target_dicts[target_list[0]]['configurations'].keys() | 1320 config_names = target_dicts[target_list[0]]['configurations'].keys() |
1287 for config_name in config_names: | 1321 for config_name in config_names: |
1288 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1322 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1289 config_name) | 1323 config_name) |
OLD | NEW |