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 """ | 5 """ |
6 This module helps emulate Visual Studio 2008 behavior on top of other | 6 This module helps emulate Visual Studio 2008 behavior on top of other |
7 build systems, primarily ninja. | 7 build systems, primarily ninja. |
8 """ | 8 """ |
9 | 9 |
10 import os | 10 import os |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 # the WDK_DIR environment variable, may be None. | 145 # the WDK_DIR environment variable, may be None. |
146 self.wdk_dir = os.environ.get('WDK_DIR') | 146 self.wdk_dir = os.environ.get('WDK_DIR') |
147 | 147 |
148 supported_fields = [ | 148 supported_fields = [ |
149 ('msvs_configuration_attributes', dict), | 149 ('msvs_configuration_attributes', dict), |
150 ('msvs_settings', dict), | 150 ('msvs_settings', dict), |
151 ('msvs_system_include_dirs', list), | 151 ('msvs_system_include_dirs', list), |
152 ('msvs_disabled_warnings', list), | 152 ('msvs_disabled_warnings', list), |
153 ('msvs_precompiled_header', str), | 153 ('msvs_precompiled_header', str), |
154 ('msvs_precompiled_source', str), | 154 ('msvs_precompiled_source', str), |
| 155 ('msvs_configuration_platform', str), |
155 ('msvs_target_platform', str), | 156 ('msvs_target_platform', str), |
156 ] | 157 ] |
157 configs = spec['configurations'] | 158 configs = spec['configurations'] |
158 for field, default in supported_fields: | 159 for field, default in supported_fields: |
159 setattr(self, field, {}) | 160 setattr(self, field, {}) |
160 for configname, config in configs.iteritems(): | 161 for configname, config in configs.iteritems(): |
161 getattr(self, field)[configname] = config.get(field, default()) | 162 getattr(self, field)[configname] = config.get(field, default()) |
162 | 163 |
163 self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.']) | 164 self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.']) |
164 | 165 |
165 def GetVSMacroEnv(self, base_to_build=None, config=None): | 166 def GetVSMacroEnv(self, base_to_build=None, config=None): |
166 """Get a dict of variables mapping internal VS macro names to their gyp | 167 """Get a dict of variables mapping internal VS macro names to their gyp |
167 equivalents.""" | 168 equivalents.""" |
168 target_platform = self.GetTargetPlatform(config) | 169 target_platform = 'Win32' if self.GetArch(config) == 'x86' else 'x64' |
169 target_platform = {'x86': 'Win32'}.get(target_platform, target_platform) | |
170 replacements = { | 170 replacements = { |
171 '$(VSInstallDir)': self.vs_version.Path(), | 171 '$(VSInstallDir)': self.vs_version.Path(), |
172 '$(VCInstallDir)': os.path.join(self.vs_version.Path(), 'VC') + '\\', | 172 '$(VCInstallDir)': os.path.join(self.vs_version.Path(), 'VC') + '\\', |
173 '$(OutDir)\\': base_to_build + '\\' if base_to_build else '', | 173 '$(OutDir)\\': base_to_build + '\\' if base_to_build else '', |
174 '$(IntDir)': '$!INTERMEDIATE_DIR', | 174 '$(IntDir)': '$!INTERMEDIATE_DIR', |
175 '$(InputPath)': '${source}', | 175 '$(InputPath)': '${source}', |
176 '$(InputName)': '${root}', | 176 '$(InputName)': '${root}', |
177 '$(ProjectName)': self.spec['target_name'], | 177 '$(ProjectName)': self.spec['target_name'], |
178 '$(PlatformName)': target_platform, | 178 '$(PlatformName)': target_platform, |
179 '$(ProjectDir)\\': '', | 179 '$(ProjectDir)\\': '', |
(...skipping 28 matching lines...) Expand all Loading... |
208 class _GetWrapper(object): | 208 class _GetWrapper(object): |
209 def __init__(self, parent, field, base_path, append=None): | 209 def __init__(self, parent, field, base_path, append=None): |
210 self.parent = parent | 210 self.parent = parent |
211 self.field = field | 211 self.field = field |
212 self.base_path = [base_path] | 212 self.base_path = [base_path] |
213 self.append = append | 213 self.append = append |
214 def __call__(self, name, map=None, prefix='', default=None): | 214 def __call__(self, name, map=None, prefix='', default=None): |
215 return self.parent._GetAndMunge(self.field, self.base_path + [name], | 215 return self.parent._GetAndMunge(self.field, self.base_path + [name], |
216 default=default, prefix=prefix, append=self.append, map=map) | 216 default=default, prefix=prefix, append=self.append, map=map) |
217 | 217 |
218 def GetTargetPlatform(self, config): | 218 def GetArch(self, config): |
219 target_platform = self.msvs_target_platform.get(config, '') | 219 """Get architecture based on msvs_configuration_platform and |
220 if not target_platform: | 220 msvs_target_platform. Returns either 'x86' or 'x64'.""" |
221 target_platform = 'Win32' | 221 configuration_platform = self.msvs_configuration_platform.get(config, '') |
222 return {'Win32': 'x86'}.get(target_platform, target_platform) | 222 platform = self.msvs_target_platform.get(config, '') |
| 223 if not platform: # If no specific override, use the configuration's. |
| 224 platform = configuration_platform |
| 225 # Map from platform to architecture. |
| 226 return {'Win32': 'x86', 'x64': 'x64'}.get(platform, 'x86') |
223 | 227 |
224 def _RealConfig(self, config): | 228 def _TargetConfig(self, config): |
225 target_platform = self.GetTargetPlatform(config) | 229 """Returns the target-specific configuration.""" |
226 if target_platform == 'x64' and not config.endswith('_x64'): | 230 # There's two levels of architecture/platform specification in VS. The |
| 231 # first level is globally for the configuration (this is what we consider |
| 232 # "the" config at the gyp level, which will be something like 'Debug' or |
| 233 # 'Release_x64'), and a second target-specific configuration, which is an |
| 234 # override for the global one. |config| is remapped here to take into |
| 235 # account the local target-specific overrides to the global configuration. |
| 236 arch = self.GetArch(config) |
| 237 if arch == 'x64' and not config.endswith('_x64'): |
227 config += '_x64' | 238 config += '_x64' |
| 239 if arch == 'x86' and config.endswith('_x64'): |
| 240 config = config.rsplit('_', 1)[0] |
228 return config | 241 return config |
229 | 242 |
230 def _Setting(self, path, config, | 243 def _Setting(self, path, config, |
231 default=None, prefix='', append=None, map=None): | 244 default=None, prefix='', append=None, map=None): |
232 """_GetAndMunge for msvs_settings.""" | 245 """_GetAndMunge for msvs_settings.""" |
233 config = self._RealConfig(config) | |
234 return self._GetAndMunge( | 246 return self._GetAndMunge( |
235 self.msvs_settings[config], path, default, prefix, append, map) | 247 self.msvs_settings[config], path, default, prefix, append, map) |
236 | 248 |
237 def _ConfigAttrib(self, path, config, | 249 def _ConfigAttrib(self, path, config, |
238 default=None, prefix='', append=None, map=None): | 250 default=None, prefix='', append=None, map=None): |
239 """_GetAndMunge for msvs_configuration_attributes.""" | 251 """_GetAndMunge for msvs_configuration_attributes.""" |
240 config = self._RealConfig(config) | |
241 return self._GetAndMunge( | 252 return self._GetAndMunge( |
242 self.msvs_configuration_attributes[config], | 253 self.msvs_configuration_attributes[config], |
243 path, default, prefix, append, map) | 254 path, default, prefix, append, map) |
244 | 255 |
245 def AdjustIncludeDirs(self, include_dirs, config): | 256 def AdjustIncludeDirs(self, include_dirs, config): |
246 """Updates include_dirs to expand VS specific paths, and adds the system | 257 """Updates include_dirs to expand VS specific paths, and adds the system |
247 include dirs used for platform SDK and similar.""" | 258 include dirs used for platform SDK and similar.""" |
248 config = self._RealConfig(config) | 259 config = self._TargetConfig(config) |
249 includes = include_dirs + self.msvs_system_include_dirs[config] | 260 includes = include_dirs + self.msvs_system_include_dirs[config] |
250 includes.extend(self._Setting( | 261 includes.extend(self._Setting( |
251 ('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[])) | 262 ('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[])) |
252 return [self.ConvertVSMacros(p, config=config) for p in includes] | 263 return [self.ConvertVSMacros(p, config=config) for p in includes] |
253 | 264 |
254 def GetComputedDefines(self, config): | 265 def GetComputedDefines(self, config): |
255 """Returns the set of defines that are injected to the defines list based | 266 """Returns the set of defines that are injected to the defines list based |
256 on other VS settings.""" | 267 on other VS settings.""" |
257 config = self._RealConfig(config) | 268 config = self._TargetConfig(config) |
258 defines = [] | 269 defines = [] |
259 if self._ConfigAttrib(['CharacterSet'], config) == '1': | 270 if self._ConfigAttrib(['CharacterSet'], config) == '1': |
260 defines.extend(('_UNICODE', 'UNICODE')) | 271 defines.extend(('_UNICODE', 'UNICODE')) |
261 if self._ConfigAttrib(['CharacterSet'], config) == '2': | 272 if self._ConfigAttrib(['CharacterSet'], config) == '2': |
262 defines.append('_MBCS') | 273 defines.append('_MBCS') |
263 defines.extend(self._Setting( | 274 defines.extend(self._Setting( |
264 ('VCCLCompilerTool', 'PreprocessorDefinitions'), config, default=[])) | 275 ('VCCLCompilerTool', 'PreprocessorDefinitions'), config, default=[])) |
265 return defines | 276 return defines |
266 | 277 |
267 def GetOutputName(self, config, expand_special): | 278 def GetOutputName(self, config, expand_special): |
268 """Gets the explicitly overridden output name for a target or returns None | 279 """Gets the explicitly overridden output name for a target or returns None |
269 if it's not overridden.""" | 280 if it's not overridden.""" |
270 config = self._RealConfig(config) | 281 config = self._TargetConfig(config) |
271 type = self.spec['type'] | 282 type = self.spec['type'] |
272 root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool' | 283 root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool' |
273 # TODO(scottmg): Handle OutputDirectory without OutputFile. | 284 # TODO(scottmg): Handle OutputDirectory without OutputFile. |
274 output_file = self._Setting((root, 'OutputFile'), config) | 285 output_file = self._Setting((root, 'OutputFile'), config) |
275 if output_file: | 286 if output_file: |
276 output_file = expand_special(self.ConvertVSMacros( | 287 output_file = expand_special(self.ConvertVSMacros( |
277 output_file, config=config)) | 288 output_file, config=config)) |
278 return output_file | 289 return output_file |
279 | 290 |
280 def GetPDBName(self, config, expand_special): | 291 def GetPDBName(self, config, expand_special): |
281 """Gets the explicitly overridden pdb name for a target or returns None | 292 """Gets the explicitly overridden pdb name for a target or returns None |
282 if it's not overridden.""" | 293 if it's not overridden.""" |
283 config = self._RealConfig(config) | 294 config = self._TargetConfig(config) |
284 output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config) | 295 output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config) |
285 if output_file: | 296 if output_file: |
286 output_file = expand_special(self.ConvertVSMacros( | 297 output_file = expand_special(self.ConvertVSMacros( |
287 output_file, config=config)) | 298 output_file, config=config)) |
288 return output_file | 299 return output_file |
289 | 300 |
290 def GetCflags(self, config): | 301 def GetCflags(self, config): |
291 """Returns the flags that need to be added to .c and .cc compilations.""" | 302 """Returns the flags that need to be added to .c and .cc compilations.""" |
292 config = self._RealConfig(config) | 303 config = self._TargetConfig(config) |
293 cflags = [] | 304 cflags = [] |
294 cflags.extend(['/wd' + w for w in self.msvs_disabled_warnings[config]]) | 305 cflags.extend(['/wd' + w for w in self.msvs_disabled_warnings[config]]) |
295 cl = self._GetWrapper(self, self.msvs_settings[config], | 306 cl = self._GetWrapper(self, self.msvs_settings[config], |
296 'VCCLCompilerTool', append=cflags) | 307 'VCCLCompilerTool', append=cflags) |
297 cl('Optimization', | 308 cl('Optimization', |
298 map={'0': 'd', '1': '1', '2': '2', '3': 'x'}, prefix='/O') | 309 map={'0': 'd', '1': '1', '2': '2', '3': 'x'}, prefix='/O') |
299 cl('InlineFunctionExpansion', prefix='/Ob') | 310 cl('InlineFunctionExpansion', prefix='/Ob') |
300 cl('OmitFramePointers', map={'false': '-', 'true': ''}, prefix='/Oy') | 311 cl('OmitFramePointers', map={'false': '-', 'true': ''}, prefix='/Oy') |
301 cl('FavorSizeOrSpeed', map={'1': 't', '2': 's'}, prefix='/O') | 312 cl('FavorSizeOrSpeed', map={'1': 't', '2': 's'}, prefix='/O') |
302 cl('WholeProgramOptimization', map={'true': '/GL'}) | 313 cl('WholeProgramOptimization', map={'true': '/GL'}) |
(...skipping 11 matching lines...) Expand all Loading... |
314 cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH') | 325 cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH') |
315 cl('EnablePREfast', map={'true': '/analyze'}) | 326 cl('EnablePREfast', map={'true': '/analyze'}) |
316 cl('AdditionalOptions', prefix='') | 327 cl('AdditionalOptions', prefix='') |
317 # ninja handles parallelism by itself, don't have the compiler do it too. | 328 # ninja handles parallelism by itself, don't have the compiler do it too. |
318 cflags = filter(lambda x: not x.startswith('/MP'), cflags) | 329 cflags = filter(lambda x: not x.startswith('/MP'), cflags) |
319 return cflags | 330 return cflags |
320 | 331 |
321 def GetPrecompiledHeader(self, config, gyp_to_build_path): | 332 def GetPrecompiledHeader(self, config, gyp_to_build_path): |
322 """Returns an object that handles the generation of precompiled header | 333 """Returns an object that handles the generation of precompiled header |
323 build steps.""" | 334 build steps.""" |
324 config = self._RealConfig(config) | 335 config = self._TargetConfig(config) |
325 return _PchHelper(self, config, gyp_to_build_path) | 336 return _PchHelper(self, config, gyp_to_build_path) |
326 | 337 |
327 def _GetPchFlags(self, config, extension): | 338 def _GetPchFlags(self, config, extension): |
328 """Get the flags to be added to the cflags for precompiled header support. | 339 """Get the flags to be added to the cflags for precompiled header support. |
329 """ | 340 """ |
330 config = self._RealConfig(config) | 341 config = self._TargetConfig(config) |
331 # The PCH is only built once by a particular source file. Usage of PCH must | 342 # The PCH is only built once by a particular source file. Usage of PCH must |
332 # only be for the same language (i.e. C vs. C++), so only include the pch | 343 # only be for the same language (i.e. C vs. C++), so only include the pch |
333 # flags when the language matches. | 344 # flags when the language matches. |
334 if self.msvs_precompiled_header[config]: | 345 if self.msvs_precompiled_header[config]: |
335 source_ext = os.path.splitext(self.msvs_precompiled_source[config])[1] | 346 source_ext = os.path.splitext(self.msvs_precompiled_source[config])[1] |
336 if _LanguageMatchesForPch(source_ext, extension): | 347 if _LanguageMatchesForPch(source_ext, extension): |
337 pch = os.path.split(self.msvs_precompiled_header[config])[1] | 348 pch = os.path.split(self.msvs_precompiled_header[config])[1] |
338 return ['/Yu' + pch, '/FI' + pch, '/Fp${pchprefix}.' + pch + '.pch'] | 349 return ['/Yu' + pch, '/FI' + pch, '/Fp${pchprefix}.' + pch + '.pch'] |
339 return [] | 350 return [] |
340 | 351 |
341 def GetCflagsC(self, config): | 352 def GetCflagsC(self, config): |
342 """Returns the flags that need to be added to .c compilations.""" | 353 """Returns the flags that need to be added to .c compilations.""" |
343 config = self._RealConfig(config) | 354 config = self._TargetConfig(config) |
344 return self._GetPchFlags(config, '.c') | 355 return self._GetPchFlags(config, '.c') |
345 | 356 |
346 def GetCflagsCC(self, config): | 357 def GetCflagsCC(self, config): |
347 """Returns the flags that need to be added to .cc compilations.""" | 358 """Returns the flags that need to be added to .cc compilations.""" |
348 config = self._RealConfig(config) | 359 config = self._TargetConfig(config) |
349 return ['/TP'] + self._GetPchFlags(config, '.cc') | 360 return ['/TP'] + self._GetPchFlags(config, '.cc') |
350 | 361 |
351 def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path): | 362 def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path): |
352 """Get and normalize the list of paths in AdditionalLibraryDirectories | 363 """Get and normalize the list of paths in AdditionalLibraryDirectories |
353 setting.""" | 364 setting.""" |
354 config = self._RealConfig(config) | 365 config = self._TargetConfig(config) |
355 libpaths = self._Setting((root, 'AdditionalLibraryDirectories'), | 366 libpaths = self._Setting((root, 'AdditionalLibraryDirectories'), |
356 config, default=[]) | 367 config, default=[]) |
357 libpaths = [os.path.normpath( | 368 libpaths = [os.path.normpath( |
358 gyp_to_build_path(self.ConvertVSMacros(p, config=config))) | 369 gyp_to_build_path(self.ConvertVSMacros(p, config=config))) |
359 for p in libpaths] | 370 for p in libpaths] |
360 return ['/LIBPATH:"' + p + '"' for p in libpaths] | 371 return ['/LIBPATH:"' + p + '"' for p in libpaths] |
361 | 372 |
362 def GetLibFlags(self, config, gyp_to_build_path): | 373 def GetLibFlags(self, config, gyp_to_build_path): |
363 """Returns the flags that need to be added to lib commands.""" | 374 """Returns the flags that need to be added to lib commands.""" |
364 config = self._RealConfig(config) | 375 config = self._TargetConfig(config) |
365 libflags = [] | 376 libflags = [] |
366 lib = self._GetWrapper(self, self.msvs_settings[config], | 377 lib = self._GetWrapper(self, self.msvs_settings[config], |
367 'VCLibrarianTool', append=libflags) | 378 'VCLibrarianTool', append=libflags) |
368 libflags.extend(self._GetAdditionalLibraryDirectories( | 379 libflags.extend(self._GetAdditionalLibraryDirectories( |
369 'VCLibrarianTool', config, gyp_to_build_path)) | 380 'VCLibrarianTool', config, gyp_to_build_path)) |
370 lib('AdditionalOptions') | 381 lib('AdditionalOptions') |
371 return libflags | 382 return libflags |
372 | 383 |
373 def _GetDefFileAsLdflags(self, spec, ldflags, gyp_to_build_path): | 384 def _GetDefFileAsLdflags(self, spec, ldflags, gyp_to_build_path): |
374 """.def files get implicitly converted to a ModuleDefinitionFile for the | 385 """.def files get implicitly converted to a ModuleDefinitionFile for the |
375 linker in the VS generator. Emulate that behaviour here.""" | 386 linker in the VS generator. Emulate that behaviour here.""" |
376 def_file = '' | 387 def_file = '' |
377 if spec['type'] in ('shared_library', 'loadable_module', 'executable'): | 388 if spec['type'] in ('shared_library', 'loadable_module', 'executable'): |
378 def_files = [s for s in spec.get('sources', []) if s.endswith('.def')] | 389 def_files = [s for s in spec.get('sources', []) if s.endswith('.def')] |
379 if len(def_files) == 1: | 390 if len(def_files) == 1: |
380 ldflags.append('/DEF:"%s"' % gyp_to_build_path(def_files[0])) | 391 ldflags.append('/DEF:"%s"' % gyp_to_build_path(def_files[0])) |
381 elif len(def_files) > 1: | 392 elif len(def_files) > 1: |
382 raise Exception("Multiple .def files") | 393 raise Exception("Multiple .def files") |
383 | 394 |
384 def GetLdflags(self, config, gyp_to_build_path, expand_special, | 395 def GetLdflags(self, config, gyp_to_build_path, expand_special, |
385 manifest_base_name, is_executable): | 396 manifest_base_name, is_executable): |
386 """Returns the flags that need to be added to link commands, and the | 397 """Returns the flags that need to be added to link commands, and the |
387 manifest files.""" | 398 manifest files.""" |
388 config = self._RealConfig(config) | 399 config = self._TargetConfig(config) |
389 ldflags = [] | 400 ldflags = [] |
390 ld = self._GetWrapper(self, self.msvs_settings[config], | 401 ld = self._GetWrapper(self, self.msvs_settings[config], |
391 'VCLinkerTool', append=ldflags) | 402 'VCLinkerTool', append=ldflags) |
392 self._GetDefFileAsLdflags(self.spec, ldflags, gyp_to_build_path) | 403 self._GetDefFileAsLdflags(self.spec, ldflags, gyp_to_build_path) |
393 ld('GenerateDebugInformation', map={'true': '/DEBUG'}) | 404 ld('GenerateDebugInformation', map={'true': '/DEBUG'}) |
394 ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:') | 405 ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:') |
395 ldflags.extend(self._GetAdditionalLibraryDirectories( | 406 ldflags.extend(self._GetAdditionalLibraryDirectories( |
396 'VCLinkerTool', config, gyp_to_build_path)) | 407 'VCLinkerTool', config, gyp_to_build_path)) |
397 ld('DelayLoadDLLs', prefix='/DELAYLOAD:') | 408 ld('DelayLoadDLLs', prefix='/DELAYLOAD:') |
398 out = self.GetOutputName(config, expand_special) | 409 out = self.GetOutputName(config, expand_special) |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 print 'gyp/msvs_emulation.py: "EmbedManifest: true" not yet supported.' | 485 print 'gyp/msvs_emulation.py: "EmbedManifest: true" not yet supported.' |
475 if isinstance(files, str): | 486 if isinstance(files, str): |
476 files = files.split(';') | 487 files = files.split(';') |
477 return [os.path.normpath( | 488 return [os.path.normpath( |
478 gyp_to_build_path(self.ConvertVSMacros(f, config=config))) | 489 gyp_to_build_path(self.ConvertVSMacros(f, config=config))) |
479 for f in files] | 490 for f in files] |
480 | 491 |
481 def IsUseLibraryDependencyInputs(self, config): | 492 def IsUseLibraryDependencyInputs(self, config): |
482 """Returns whether the target should be linked via Use Library Dependency | 493 """Returns whether the target should be linked via Use Library Dependency |
483 Inputs (using component .objs of a given .lib).""" | 494 Inputs (using component .objs of a given .lib).""" |
484 config = self._RealConfig(config) | 495 config = self._TargetConfig(config) |
485 uldi = self._Setting(('VCLinkerTool', 'UseLibraryDependencyInputs'), config) | 496 uldi = self._Setting(('VCLinkerTool', 'UseLibraryDependencyInputs'), config) |
486 return uldi == 'true' | 497 return uldi == 'true' |
487 | 498 |
488 def GetRcflags(self, config, gyp_to_ninja_path): | 499 def GetRcflags(self, config, gyp_to_ninja_path): |
489 """Returns the flags that need to be added to invocations of the resource | 500 """Returns the flags that need to be added to invocations of the resource |
490 compiler.""" | 501 compiler.""" |
491 config = self._RealConfig(config) | 502 config = self._TargetConfig(config) |
492 rcflags = [] | 503 rcflags = [] |
493 rc = self._GetWrapper(self, self.msvs_settings[config], | 504 rc = self._GetWrapper(self, self.msvs_settings[config], |
494 'VCResourceCompilerTool', append=rcflags) | 505 'VCResourceCompilerTool', append=rcflags) |
495 rc('AdditionalIncludeDirectories', map=gyp_to_ninja_path, prefix='/I') | 506 rc('AdditionalIncludeDirectories', map=gyp_to_ninja_path, prefix='/I') |
496 rcflags.append('/I' + gyp_to_ninja_path('.')) | 507 rcflags.append('/I' + gyp_to_ninja_path('.')) |
497 rc('PreprocessorDefinitions', prefix='/d') | 508 rc('PreprocessorDefinitions', prefix='/d') |
498 # /l arg must be in hex without leading '0x' | 509 # /l arg must be in hex without leading '0x' |
499 rc('Culture', prefix='/l', map=lambda x: hex(int(x))[2:]) | 510 rc('Culture', prefix='/l', map=lambda x: hex(int(x))[2:]) |
500 return rcflags | 511 return rcflags |
501 | 512 |
(...skipping 16 matching lines...) Expand all Loading... |
518 'call "%s\\setup_env.bat" && set CYGWIN=nontsec && ' % cygwin_dir + | 529 'call "%s\\setup_env.bat" && set CYGWIN=nontsec && ' % cygwin_dir + |
519 'bash -c "%s ; %s"' % (cd, bash_cmd)) | 530 'bash -c "%s ; %s"' % (cd, bash_cmd)) |
520 return cmd | 531 return cmd |
521 | 532 |
522 def IsRuleRunUnderCygwin(self, rule): | 533 def IsRuleRunUnderCygwin(self, rule): |
523 """Determine if an action should be run under cygwin. If the variable is | 534 """Determine if an action should be run under cygwin. If the variable is |
524 unset, or set to 1 we use cygwin.""" | 535 unset, or set to 1 we use cygwin.""" |
525 return int(rule.get('msvs_cygwin_shell', | 536 return int(rule.get('msvs_cygwin_shell', |
526 self.spec.get('msvs_cygwin_shell', 1))) != 0 | 537 self.spec.get('msvs_cygwin_shell', 1))) != 0 |
527 | 538 |
| 539 def _HasExplicitRuleForExtension(self, spec, extension): |
| 540 """Determine if there's an explicit rule for a particular extension.""" |
| 541 for rule in spec.get('rules', []): |
| 542 if rule['extension'] == extension: |
| 543 return True |
| 544 return False |
| 545 |
528 def HasExplicitIdlRules(self, spec): | 546 def HasExplicitIdlRules(self, spec): |
529 """Determine if there's an explicit rule for idl files. When there isn't we | 547 """Determine if there's an explicit rule for idl files. When there isn't we |
530 need to generate implicit rules to build MIDL .idl files.""" | 548 need to generate implicit rules to build MIDL .idl files.""" |
531 for rule in spec.get('rules', []): | 549 return self._HasExplicitRuleForExtension(spec, 'idl') |
532 if rule['extension'] == 'idl' and int(rule.get('msvs_external_rule', 0)): | 550 |
533 return True | 551 def HasExplicitAsmRules(self, spec): |
534 return False | 552 """Determine if there's an explicit rule for asm files. When there isn't we |
| 553 need to generate implicit rules to assemble .asm files.""" |
| 554 return self._HasExplicitRuleForExtension(spec, 'asm') |
535 | 555 |
536 def GetIdlBuildData(self, source, config): | 556 def GetIdlBuildData(self, source, config): |
537 """Determine the implicit outputs for an idl file. Returns output | 557 """Determine the implicit outputs for an idl file. Returns output |
538 directory, outputs, and variables and flags that are required.""" | 558 directory, outputs, and variables and flags that are required.""" |
539 config = self._RealConfig(config) | 559 config = self._TargetConfig(config) |
540 midl_get = self._GetWrapper(self, self.msvs_settings[config], 'VCMIDLTool') | 560 midl_get = self._GetWrapper(self, self.msvs_settings[config], 'VCMIDLTool') |
541 def midl(name, default=None): | 561 def midl(name, default=None): |
542 return self.ConvertVSMacros(midl_get(name, default=default), | 562 return self.ConvertVSMacros(midl_get(name, default=default), |
543 config=config) | 563 config=config) |
544 tlb = midl('TypeLibraryName', default='${root}.tlb') | 564 tlb = midl('TypeLibraryName', default='${root}.tlb') |
545 header = midl('HeaderFileName', default='${root}.h') | 565 header = midl('HeaderFileName', default='${root}.h') |
546 dlldata = midl('DLLDataFileName', default='dlldata.c') | 566 dlldata = midl('DLLDataFileName', default='dlldata.c') |
547 iid = midl('InterfaceIdentifierFileName', default='${root}_i.c') | 567 iid = midl('InterfaceIdentifierFileName', default='${root}_i.c') |
548 proxy = midl('ProxyFileName', default='${root}_p.c') | 568 proxy = midl('ProxyFileName', default='${root}_p.c') |
549 # Note that .tlb is not included in the outputs as it is not always | 569 # Note that .tlb is not included in the outputs as it is not always |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 so they're not surprised when the VS build fails.""" | 733 so they're not surprised when the VS build fails.""" |
714 if int(generator_flags.get('msvs_error_on_missing_sources', 0)): | 734 if int(generator_flags.get('msvs_error_on_missing_sources', 0)): |
715 no_specials = filter(lambda x: '$' not in x, sources) | 735 no_specials = filter(lambda x: '$' not in x, sources) |
716 relative = [os.path.join(build_dir, gyp_to_ninja(s)) for s in no_specials] | 736 relative = [os.path.join(build_dir, gyp_to_ninja(s)) for s in no_specials] |
717 missing = filter(lambda x: not os.path.exists(x), relative) | 737 missing = filter(lambda x: not os.path.exists(x), relative) |
718 if missing: | 738 if missing: |
719 # They'll look like out\Release\..\..\stuff\things.cc, so normalize the | 739 # They'll look like out\Release\..\..\stuff\things.cc, so normalize the |
720 # path for a slightly less crazy looking output. | 740 # path for a slightly less crazy looking output. |
721 cleaned_up = [os.path.normpath(x) for x in missing] | 741 cleaned_up = [os.path.normpath(x) for x in missing] |
722 raise Exception('Missing input files:\n%s' % '\n'.join(cleaned_up)) | 742 raise Exception('Missing input files:\n%s' % '\n'.join(cleaned_up)) |
OLD | NEW |