Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

ninja windows: Support x64 configuration platform

This supports top-level x64 configuration so the entire
project can be built as 64 bit. Previously, we only supported
a 64 bit override for individual targets (via msvs_target_platform).

'asm' files were a bit confused before; the intention was that all .asm
be built on Win32, but they were only being built if the msvs_target_platform
was explicitly set which was very confusing. So, support .asm still, but if
the target overrides asm with a rule, then use that one instead, similar to
.idl files. 

BUG=chromium:8606
Review URL: https://codereview.chromium.org/11363143

git-svn-id: http://gyp.googlecode.com/svn/trunk@1534 78cadc50-ecff-11dd-a971-7dbc132099af
  • Loading branch information...
commit cb7a494ec635b2e8691af06ae557ed637e4e82f5 1 parent 59faf13
scottmg@chromium.org authored
View
11 pylib/gyp/generator/ninja.py
@@ -378,8 +378,8 @@ def WriteSpec(self, spec, config_name, generator_flags,
if self.flavor == 'win':
self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec,
generator_flags)
- target_platform = self.msvs_settings.GetTargetPlatform(config_name)
- self.ninja.variable('arch', self.win_env[target_platform])
+ arch = self.msvs_settings.GetArch(config_name)
+ self.ninja.variable('arch', self.win_env[arch])
# Compute predepends for all rules.
# actions_depends is the dependencies this target depends on before running
@@ -435,7 +435,7 @@ def WriteSpec(self, spec, config_name, generator_flags,
lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))
link_deps = self.WriteSources(
config_name, config, sources, compile_depends_stamp, pch,
- case_sensitive_filesystem)
+ case_sensitive_filesystem, spec)
# Some actions/rules output 'sources' that are already object files.
link_deps += [self.GypPathToNinja(f)
for f in sources if f.endswith(self.obj_ext)]
@@ -721,7 +721,7 @@ def WriteMacInfoPlist(self, bundle_depends):
bundle_depends.append(out)
def WriteSources(self, config_name, config, sources, predepends,
- precompiled_header, case_sensitive_filesystem):
+ precompiled_header, case_sensitive_filesystem, spec):
"""Write build rules to compile all of |sources|."""
if self.toolset == 'host':
self.ninja.variable('ar', '$ar_host')
@@ -798,7 +798,8 @@ def WriteSources(self, config_name, config, sources, predepends,
elif ext == 's' and self.flavor != 'win': # Doesn't generate .o.d files.
command = 'cc_s'
elif (self.flavor == 'win' and ext == 'asm' and
- self.msvs_settings.GetTargetPlatform(config_name) == 'Win32'):
+ self.msvs_settings.GetArch(config_name) == 'x86' and
+ not self.msvs_settings.HasExplicitAsmRules(spec)):
# Asm files only get auto assembled for x86 (not x64).
command = 'asm'
# Add the _asm suffix as msvs is capable of handling .cc and
View
84 pylib/gyp/msvs_emulation.py
@@ -152,6 +152,7 @@ def __init__(self, spec, generator_flags):
('msvs_disabled_warnings', list),
('msvs_precompiled_header', str),
('msvs_precompiled_source', str),
+ ('msvs_configuration_platform', str),
('msvs_target_platform', str),
]
configs = spec['configurations']
@@ -165,8 +166,7 @@ def __init__(self, spec, generator_flags):
def GetVSMacroEnv(self, base_to_build=None, config=None):
"""Get a dict of variables mapping internal VS macro names to their gyp
equivalents."""
- target_platform = self.GetTargetPlatform(config)
- target_platform = {'x86': 'Win32'}.get(target_platform, target_platform)
+ target_platform = 'Win32' if self.GetArch(config) == 'x86' else 'x64'
replacements = {
'$(VSInstallDir)': self.vs_version.Path(),
'$(VCInstallDir)': os.path.join(self.vs_version.Path(), 'VC') + '\\',
@@ -215,29 +215,40 @@ def __call__(self, name, map=None, prefix='', default=None):
return self.parent._GetAndMunge(self.field, self.base_path + [name],
default=default, prefix=prefix, append=self.append, map=map)
- def GetTargetPlatform(self, config):
- target_platform = self.msvs_target_platform.get(config, '')
- if not target_platform:
- target_platform = 'Win32'
- return {'Win32': 'x86'}.get(target_platform, target_platform)
-
- def _RealConfig(self, config):
- target_platform = self.GetTargetPlatform(config)
- if target_platform == 'x64' and not config.endswith('_x64'):
+ def GetArch(self, config):
+ """Get architecture based on msvs_configuration_platform and
+ msvs_target_platform. Returns either 'x86' or 'x64'."""
+ configuration_platform = self.msvs_configuration_platform.get(config, '')
+ platform = self.msvs_target_platform.get(config, '')
+ if not platform: # If no specific override, use the configuration's.
+ platform = configuration_platform
+ # Map from platform to architecture.
+ return {'Win32': 'x86', 'x64': 'x64'}.get(platform, 'x86')
+
+ def _TargetConfig(self, config):
+ """Returns the target-specific configuration."""
+ # There's two levels of architecture/platform specification in VS. The
+ # first level is globally for the configuration (this is what we consider
+ # "the" config at the gyp level, which will be something like 'Debug' or
+ # 'Release_x64'), and a second target-specific configuration, which is an
+ # override for the global one. |config| is remapped here to take into
+ # account the local target-specific overrides to the global configuration.
+ arch = self.GetArch(config)
+ if arch == 'x64' and not config.endswith('_x64'):
config += '_x64'
+ if arch == 'x86' and config.endswith('_x64'):
+ config = config.rsplit('_', 1)[0]
return config
def _Setting(self, path, config,
default=None, prefix='', append=None, map=None):
"""_GetAndMunge for msvs_settings."""
- config = self._RealConfig(config)
return self._GetAndMunge(
self.msvs_settings[config], path, default, prefix, append, map)
def _ConfigAttrib(self, path, config,
default=None, prefix='', append=None, map=None):
"""_GetAndMunge for msvs_configuration_attributes."""
- config = self._RealConfig(config)
return self._GetAndMunge(
self.msvs_configuration_attributes[config],
path, default, prefix, append, map)
@@ -245,7 +256,7 @@ def _ConfigAttrib(self, path, config,
def AdjustIncludeDirs(self, include_dirs, config):
"""Updates include_dirs to expand VS specific paths, and adds the system
include dirs used for platform SDK and similar."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
includes = include_dirs + self.msvs_system_include_dirs[config]
includes.extend(self._Setting(
('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[]))
@@ -254,7 +265,7 @@ def AdjustIncludeDirs(self, include_dirs, config):
def GetComputedDefines(self, config):
"""Returns the set of defines that are injected to the defines list based
on other VS settings."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
defines = []
if self._ConfigAttrib(['CharacterSet'], config) == '1':
defines.extend(('_UNICODE', 'UNICODE'))
@@ -267,7 +278,7 @@ def GetComputedDefines(self, config):
def GetOutputName(self, config, expand_special):
"""Gets the explicitly overridden output name for a target or returns None
if it's not overridden."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
type = self.spec['type']
root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool'
# TODO(scottmg): Handle OutputDirectory without OutputFile.
@@ -280,7 +291,7 @@ def GetOutputName(self, config, expand_special):
def GetPDBName(self, config, expand_special):
"""Gets the explicitly overridden pdb name for a target or returns None
if it's not overridden."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config)
if output_file:
output_file = expand_special(self.ConvertVSMacros(
@@ -289,7 +300,7 @@ def GetPDBName(self, config, expand_special):
def GetCflags(self, config):
"""Returns the flags that need to be added to .c and .cc compilations."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
cflags = []
cflags.extend(['/wd' + w for w in self.msvs_disabled_warnings[config]])
cl = self._GetWrapper(self, self.msvs_settings[config],
@@ -321,13 +332,13 @@ def GetCflags(self, config):
def GetPrecompiledHeader(self, config, gyp_to_build_path):
"""Returns an object that handles the generation of precompiled header
build steps."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
return _PchHelper(self, config, gyp_to_build_path)
def _GetPchFlags(self, config, extension):
"""Get the flags to be added to the cflags for precompiled header support.
"""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
# The PCH is only built once by a particular source file. Usage of PCH must
# only be for the same language (i.e. C vs. C++), so only include the pch
# flags when the language matches.
@@ -340,18 +351,18 @@ def _GetPchFlags(self, config, extension):
def GetCflagsC(self, config):
"""Returns the flags that need to be added to .c compilations."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
return self._GetPchFlags(config, '.c')
def GetCflagsCC(self, config):
"""Returns the flags that need to be added to .cc compilations."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
return ['/TP'] + self._GetPchFlags(config, '.cc')
def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path):
"""Get and normalize the list of paths in AdditionalLibraryDirectories
setting."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
libpaths = self._Setting((root, 'AdditionalLibraryDirectories'),
config, default=[])
libpaths = [os.path.normpath(
@@ -361,7 +372,7 @@ def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path):
def GetLibFlags(self, config, gyp_to_build_path):
"""Returns the flags that need to be added to lib commands."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
libflags = []
lib = self._GetWrapper(self, self.msvs_settings[config],
'VCLibrarianTool', append=libflags)
@@ -385,7 +396,7 @@ def GetLdflags(self, config, gyp_to_build_path, expand_special,
manifest_base_name, is_executable):
"""Returns the flags that need to be added to link commands, and the
manifest files."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
ldflags = []
ld = self._GetWrapper(self, self.msvs_settings[config],
'VCLinkerTool', append=ldflags)
@@ -481,14 +492,14 @@ def _GetAdditionalManifestFiles(self, config, gyp_to_build_path):
def IsUseLibraryDependencyInputs(self, config):
"""Returns whether the target should be linked via Use Library Dependency
Inputs (using component .objs of a given .lib)."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
uldi = self._Setting(('VCLinkerTool', 'UseLibraryDependencyInputs'), config)
return uldi == 'true'
def GetRcflags(self, config, gyp_to_ninja_path):
"""Returns the flags that need to be added to invocations of the resource
compiler."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
rcflags = []
rc = self._GetWrapper(self, self.msvs_settings[config],
'VCResourceCompilerTool', append=rcflags)
@@ -525,18 +536,27 @@ def IsRuleRunUnderCygwin(self, rule):
return int(rule.get('msvs_cygwin_shell',
self.spec.get('msvs_cygwin_shell', 1))) != 0
- def HasExplicitIdlRules(self, spec):
- """Determine if there's an explicit rule for idl files. When there isn't we
- need to generate implicit rules to build MIDL .idl files."""
+ def _HasExplicitRuleForExtension(self, spec, extension):
+ """Determine if there's an explicit rule for a particular extension."""
for rule in spec.get('rules', []):
- if rule['extension'] == 'idl' and int(rule.get('msvs_external_rule', 0)):
+ if rule['extension'] == extension:
return True
return False
+ def HasExplicitIdlRules(self, spec):
+ """Determine if there's an explicit rule for idl files. When there isn't we
+ need to generate implicit rules to build MIDL .idl files."""
+ return self._HasExplicitRuleForExtension(spec, 'idl')
+
+ def HasExplicitAsmRules(self, spec):
+ """Determine if there's an explicit rule for asm files. When there isn't we
+ need to generate implicit rules to assemble .asm files."""
+ return self._HasExplicitRuleForExtension(spec, 'asm')
+
def GetIdlBuildData(self, source, config):
"""Determine the implicit outputs for an idl file. Returns output
directory, outputs, and variables and flags that are required."""
- config = self._RealConfig(config)
+ config = self._TargetConfig(config)
midl_get = self._GetWrapper(self, self.msvs_settings[config], 'VCMIDLTool')
def midl(name, default=None):
return self.ConvertVSMacros(midl_get(name, default=default),
View
24 test/assembly/gyptest-override.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Make sure that manual rules on Windows override the built in ones.
+"""
+
+import sys
+import TestGyp
+
+if sys.platform == 'win32':
+ test = TestGyp.TestGyp(formats=['msvs', 'ninja'])
+ CHDIR = 'src'
+ test.run_gyp('override.gyp', chdir=CHDIR)
+ test.build('override.gyp', test.ALL, chdir=CHDIR)
+ expect = """\
+Hello from program.c
+Got 42.
+"""
+ test.run_built_executable('program', chdir=CHDIR, stdout=expect)
+ test.pass_test()
View
34 test/assembly/src/override.gyp
@@ -0,0 +1,34 @@
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'program',
+ 'type': 'executable',
+ 'sources': [
+ 'program.c',
+ 'override_asm.asm',
+ ],
+ 'rules': [
+ {
+ # Test that if there's a specific .asm rule, it overrides the
+ # built in one on Windows.
+ 'rule_name': 'assembler',
+ 'msvs_cygwin_shell': 0,
+ 'extension': 'asm',
+ 'inputs': [
+ 'as.bat',
+ ],
+ 'outputs': [
+ 'output.obj',
+ ],
+ 'action': ['as.bat', 'lib1.c', '<(_outputs)'],
+ 'message': 'Building assembly file <(RULE_INPUT_PATH)',
+ 'process_outputs_as_sources': 1,
+ },
+ ],
+ },
+ ],
+}
View
8 test/assembly/src/override_asm.asm
@@ -0,0 +1,8 @@
+; Copyright (c) 2012 Google Inc. All rights reserved.
+; Use of this source code is governed by a BSD-style license that can be
+; found in the LICENSE file.
+
+; This is a placeholder. It should not be referenced if overrides work
+; correctly.
+
+Bad stuff that shouldn't assemble.
View
0  test/rules/src/subdir4/asm-function.asm → test/rules/src/subdir4/asm-function.assem
File renamed without changes
View
6 test/rules/src/subdir4/build-asm.gyp
@@ -23,15 +23,15 @@
'target_name': 'program4',
'type': 'executable',
'sources': [
- 'asm-function.asm',
+ 'asm-function.assem',
'program.c',
],
'conditions': [
['OS=="linux" or OS=="mac"', {
'rules': [
{
- 'rule_name': 'convert_asm',
- 'extension': 'asm',
+ 'rule_name': 'convert_assem',
+ 'extension': 'assem',
'inputs': [],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).S',
Please sign in to comment.
Something went wrong with that request. Please try again.