Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(904)

Side by Side Diff: pylib/gyp/generator/ninja.py

Issue 9443044: Beginnings of some msvs_... emulation (windows ninja) (Closed) Base URL: https://gyp.googlecode.com/svn/trunk
Patch Set: better place for normpath to remove need for $!-no-escape Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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_includes = []
587 extra_defines = []
Nico 2012/03/13 14:55:27 nit: swap these two lines, they are used in the sw
scottmg 2012/03/14 00:57:56 Done.
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_includes = self.msvs_settings.GetSystemIncludes(config_name)
601 extra_defines = self.msvs_settings.GetComputedDefines(config_name)
Nico 2012/03/13 14:55:27 nit: swap here, too
scottmg 2012/03/14 00:57:56 Done.
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « DEPS ('k') | pylib/gyp/msvs_emulation.py » ('j') | pylib/gyp/msvs_emulation.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698