# 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 module helps emulate Visual Studio 2008 behavior on top of other
build systems, primarily ninja.
"""

import os
import re
import subprocess
import sys

from gyp.common import OrderedSet
import gyp.MSVSVersion

windows_quoter_regex = re.compile(r'(\\*)"')

def QuoteForRspFile(arg):
  """Quote a command line argument so that it appears as one argument when
  processed via cmd.exe and parsed by CommandLineToArgvW (as is typical for
  Windows programs)."""
  # See http://goo.gl/cuFbX and http://goo.gl/dhPnp including the comment
  # threads. This is actually the quoting rules for CommandLineToArgvW, not
  # for the shell, because the shell doesn't do anything in Windows. This
  # works more or less because most programs (including the compiler, etc.)
  # use that function to handle command line arguments.

  # For a literal quote, CommandLineToArgvW requires 2n+1 backslashes
  # preceding it, and results in n backslashes + the quote. So we substitute
  # in 2* what we match, +1 more, plus the quote.
  arg = windows_quoter_regex.sub(lambda mo: 2 * mo.group(1) + '\\"', arg)

  # %'s also need to be doubled otherwise they're interpreted as batch
  # positional arguments. Also make sure to escape the % so that they're
  # passed literally through escaping so they can be singled to just the
  # original %. Otherwise, trying to pass the literal representation that
  # looks like an environment variable to the shell (e.g. %PATH%) would fail.
  arg = arg.replace('%', '%%')

  # These commands are used in rsp files, so no escaping for the shell (via ^)
  # is necessary.

  # Finally, wrap the whole thing in quotes so that the above quote rule
  # applies and whitespace isn't a word break.
  return '"' + arg + '"'


def EncodeRspFileList(args):
  """Process a list of arguments using QuoteCmdExeArgument."""
  # Note that the first argument is assumed to be the command. Don't add
  # quotes around it because then built-ins like 'echo', etc. won't work.
  # Take care to normpath only the path in the case of 'call ../x.bat' because
  # otherwise the whole thing is incorrectly interpreted as a path and not
  # normalized correctly.
  if not args: return ''
  if args[0].startswith('call '):
    call, program = args[0].split(' ', 1)
    program = call + ' ' + os.path.normpath(program)
  else:
    program = os.path.normpath(args[0])
  return program + ' ' + ' '.join(QuoteForRspFile(arg) for arg in args[1:])


def _GenericRetrieve(root, default, path):
  """Given a list of dictionary keys |path| and a tree of dicts |root|, find
  value at path, or return |default| if any of the path doesn't exist."""
  if not root:
    return default
  if not path:
    return root
  return _GenericRetrieve(root.get(path[0]), default, path[1:])


def _AddPrefix(element, prefix):
  """Add |prefix| to |element| or each subelement if element is iterable."""
  if element is None:
    return element
  # Note, not Iterable because we don't want to handle strings like that.
  if isinstance(element, list) or isinstance(element, tuple):
    return [prefix + e for e in element]
  else:
    return prefix + element


def _DoRemapping(element, map):
  """If |element| then remap it through |map|. If |element| is iterable then
  each item will be remapped. Any elements not found will be removed."""
  if map is not None and element is not None:
    if not callable(map):
      map = map.get # Assume it's a dict, otherwise a callable to do the remap.
    if isinstance(element, list) or isinstance(element, tuple):
      element = filter(None, [map(elem) for elem in element])
    else:
      element = map(element)
  return element


def _AppendOrReturn(append, element):
  """If |append| is None, simply return |element|. If |append| is not None,
  then add |element| to it, adding each item in |element| if it's a list or
  tuple."""
  if append is not None and element is not None:
    if isinstance(element, list) or isinstance(element, tuple):
      append.extend(element)
    else:
      append.append(element)
  else:
    return element


def _FindDirectXInstallation():
  """Try to find an installation location for the DirectX SDK. Check for the
  standard environment variable, and if that doesn't exist, try to find
  via the registry. May return None if not found in either location."""
  # Return previously calculated value, if there is one
  if hasattr(_FindDirectXInstallation, 'dxsdk_dir'):
    return _FindDirectXInstallation.dxsdk_dir

  dxsdk_dir = os.environ.get('DXSDK_DIR')
  if not dxsdk_dir:
    # Setup params to pass to and attempt to launch reg.exe.
    cmd = ['reg.exe', 'query', r'HKLM\Software\Microsoft\DirectX', '/s']
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    for line in p.communicate()[0].splitlines():
      if 'InstallPath' in line:
        dxsdk_dir = line.split('    ')[3] + "\\"

  # Cache return value
  _FindDirectXInstallation.dxsdk_dir = dxsdk_dir
  return dxsdk_dir


def GetGlobalVSMacroEnv(vs_version):
  """Get a dict of variables mapping internal VS macro names to their gyp
  equivalents. Returns all variables that are independent of the target."""
  env = {}
  # '$(VSInstallDir)' and '$(VCInstallDir)' are available when and only when
  # Visual Studio is actually installed.
  if vs_version.Path():
    env['$(VSInstallDir)'] = vs_version.Path()
    env['$(VCInstallDir)'] = os.path.join(vs_version.Path(), 'VC') + '\\'
  # Chromium uses DXSDK_DIR in include/lib paths, but it may or may not be
  # set. This happens when the SDK is sync'd via src-internal, rather than
  # by typical end-user installation of the SDK. If it's not set, we don't
  # want to leave the unexpanded variable in the path, so simply strip it.
  dxsdk_dir = _FindDirectXInstallation()
  env['$(DXSDK_DIR)'] = dxsdk_dir if dxsdk_dir else ''
  # Try to find an installation location for the Windows DDK by checking
  # the WDK_DIR environment variable, may be None.
  env['$(WDK_DIR)'] = os.environ.get('WDK_DIR', '')
  return env

def ExtractSharedMSVSSystemIncludes(configs, generator_flags):
  """Finds msvs_system_include_dirs that are common to all targets, removes
  them from all targets, and returns an OrderedSet containing them."""
  all_system_includes = OrderedSet(
      configs[0].get('msvs_system_include_dirs', []))
  for config in configs[1:]:
    system_includes = config.get('msvs_system_include_dirs', [])
    all_system_includes = all_system_includes & OrderedSet(system_includes)
  if not all_system_includes:
    return None
  # Expand macros in all_system_includes.
  env = GetGlobalVSMacroEnv(GetVSVersion(generator_flags))
  expanded_system_includes = OrderedSet([ExpandMacros(include, env)
                                         for include in all_system_includes])
  if any(['$' in include for include in expanded_system_includes]):
    # Some path relies on target-specific variables, bail.
    return None

  # Remove system includes shared by all targets from the targets.
  for config in configs:
    includes = config.get('msvs_system_include_dirs', [])
    if includes:  # Don't insert a msvs_system_include_dirs key if not needed.
      # This must check the unexpanded includes list:
      new_includes = [i for i in includes if i not in all_system_includes]
      config['msvs_system_include_dirs'] = new_includes
  return expanded_system_includes


class MsvsSettings(object):
  """A class that understands the gyp 'msvs_...' values (especially the
  msvs_settings field). They largely correpond to the VS2008 IDE DOM. This
  class helps map those settings to command line options."""

  def __init__(self, spec, generator_flags):
    self.spec = spec
    self.vs_version = GetVSVersion(generator_flags)

    supported_fields = [
        ('msvs_configuration_attributes', dict),
        ('msvs_settings', dict),
        ('msvs_system_include_dirs', list),
        ('msvs_disabled_warnings', list),
        ('msvs_precompiled_header', str),
        ('msvs_precompiled_source', str),
        ('msvs_configuration_platform', str),
        ('msvs_target_platform', str),
        ]
    configs = spec['configurations']
    for field, default in supported_fields:
      setattr(self, field, {})
      for configname, config in configs.iteritems():
        getattr(self, field)[configname] = config.get(field, default())

    self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.'])

    unsupported_fields = [
        'msvs_prebuild',
        'msvs_postbuild',
    ]
    unsupported = []
    for field in unsupported_fields:
      for config in configs.values():
        if field in config:
          unsupported += ["%s not supported (target %s)." %
                          (field, spec['target_name'])]
    if unsupported:
      raise Exception('\n'.join(unsupported))

  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 = 'Win32' if self.GetArch(config) == 'x86' else 'x64'
    target_name = self.spec.get('product_prefix', '') + \
        self.spec.get('product_name', self.spec['target_name'])
    target_dir = base_to_build + '\\' if base_to_build else ''
    replacements = {
        '$(OutDir)\\': target_dir,
        '$(TargetDir)\\': target_dir,
        '$(IntDir)': '$!INTERMEDIATE_DIR',
        '$(InputPath)': '${source}',
        '$(InputName)': '${root}',
        '$(ProjectName)': self.spec['target_name'],
        '$(TargetName)': target_name,
        '$(PlatformName)': target_platform,
        '$(ProjectDir)\\': '',
    }
    replacements.update(GetGlobalVSMacroEnv(self.vs_version))
    return replacements

  def ConvertVSMacros(self, s, base_to_build=None, config=None):
    """Convert from VS macro names to something equivalent."""
    env = self.GetVSMacroEnv(base_to_build, config=config)
    return ExpandMacros(s, env)

  def AdjustLibraries(self, libraries):
    """Strip -l from library if it's specified with that."""
    libs = [lib[2:] if lib.startswith('-l') else lib for lib in libraries]
    return [lib + '.lib' if not lib.endswith('.lib') else lib for lib in libs]

  def _GetAndMunge(self, field, path, default, prefix, append, map):
    """Retrieve a value from |field| at |path| or return |default|. If
    |append| is specified, and the item is found, it will be appended to that
    object instead of returned. If |map| is specified, results will be
    remapped through |map| before being returned or appended."""
    result = _GenericRetrieve(field, default, path)
    result = _DoRemapping(result, map)
    result = _AddPrefix(result, prefix)
    return _AppendOrReturn(append, result)

  class _GetWrapper(object):
    def __init__(self, parent, field, base_path, append=None):
      self.parent = parent
      self.field = field
      self.base_path = [base_path]
      self.append = append
    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 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."""
    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."""
    return self._GetAndMunge(
        self.msvs_configuration_attributes[config],
        path, default, prefix, append, map)

  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._TargetConfig(config)
    includes = include_dirs + self.msvs_system_include_dirs[config]
    includes.extend(self._Setting(
      ('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[]))
    return [self.ConvertVSMacros(p, config=config) for p in includes]

  def GetComputedDefines(self, config):
    """Returns the set of defines that are injected to the defines list based
    on other VS settings."""
    config = self._TargetConfig(config)
    defines = []
    if self._ConfigAttrib(['CharacterSet'], config) == '1':
      defines.extend(('_UNICODE', 'UNICODE'))
    if self._ConfigAttrib(['CharacterSet'], config) == '2':
      defines.append('_MBCS')
    defines.extend(self._Setting(
        ('VCCLCompilerTool', 'PreprocessorDefinitions'), config, default=[]))
    return defines

  def GetCompilerPdbName(self, config, expand_special):
    """Get the pdb file name that should be used for compiler invocations, or
    None if there's no explicit name specified."""
    config = self._TargetConfig(config)
    pdbname = self._Setting(
        ('VCCLCompilerTool', 'ProgramDataBaseFileName'), config)
    if pdbname:
      pdbname = expand_special(self.ConvertVSMacros(pdbname))
    return pdbname

  def GetMapFileName(self, config, expand_special):
    """Gets the explicitly overriden map file name for a target or returns None
    if it's not set."""
    config = self._TargetConfig(config)
    map_file = self._Setting(('VCLinkerTool', 'MapFileName'), config)
    if map_file:
      map_file = expand_special(self.ConvertVSMacros(map_file, config=config))
    return map_file

  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._TargetConfig(config)
    type = self.spec['type']
    root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool'
    # TODO(scottmg): Handle OutputDirectory without OutputFile.
    output_file = self._Setting((root, 'OutputFile'), config)
    if output_file:
      output_file = expand_special(self.ConvertVSMacros(
          output_file, config=config))
    return output_file

  def GetPDBName(self, config, expand_special, default):
    """Gets the explicitly overridden pdb name for a target or returns
    default if it's not overridden, or if no pdb will be generated."""
    config = self._TargetConfig(config)
    output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config)
    generate_debug_info = self._Setting(
        ('VCLinkerTool', 'GenerateDebugInformation'), config)
    if generate_debug_info:
      if output_file:
        return expand_special(self.ConvertVSMacros(output_file, config=config))
      else:
        return default
    else:
      return None

  def GetAsmflags(self, config):
    """Returns the flags that need to be added to ml invocations."""
    config = self._TargetConfig(config)
    asmflags = []
    safeseh = self._Setting(('MASM', 'UseSafeExceptionHandlers'), config)
    if safeseh == 'true':
      asmflags.append('/safeseh')
    return asmflags

  def GetCflags(self, config):
    """Returns the flags that need to be added to .c and .cc compilations."""
    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],
                          'VCCLCompilerTool', append=cflags)
    cl('Optimization',
       map={'0': 'd', '1': '1', '2': '2', '3': 'x'}, prefix='/O', default='2')
    cl('InlineFunctionExpansion', prefix='/Ob')
    cl('DisableSpecificWarnings', prefix='/wd')
    cl('StringPooling', map={'true': '/GF'})
    cl('EnableFiberSafeOptimizations', map={'true': '/GT'})
    cl('OmitFramePointers', map={'false': '-', 'true': ''}, prefix='/Oy')
    cl('EnableIntrinsicFunctions', map={'false': '-', 'true': ''}, prefix='/Oi')
    cl('FavorSizeOrSpeed', map={'1': 't', '2': 's'}, prefix='/O')
    cl('WholeProgramOptimization', map={'true': '/GL'})
    cl('WarningLevel', prefix='/W')
    cl('WarnAsError', map={'true': '/WX'})
    cl('DebugInformationFormat',
        map={'1': '7', '3': 'i', '4': 'I'}, prefix='/Z')
    cl('RuntimeTypeInfo', map={'true': '/GR', 'false': '/GR-'})
    cl('EnableFunctionLevelLinking', map={'true': '/Gy', 'false': '/Gy-'})
    cl('MinimalRebuild', map={'true': '/Gm'})
    cl('BufferSecurityCheck', map={'true': '/GS', 'false': '/GS-'})
    cl('BasicRuntimeChecks', map={'1': 's', '2': 'u', '3': '1'}, prefix='/RTC')
    cl('RuntimeLibrary',
        map={'0': 'T', '1': 'Td', '2': 'D', '3': 'Dd'}, prefix='/M')
    cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH')
    cl('DefaultCharIsUnsigned', map={'true': '/J'})
    cl('TreatWChar_tAsBuiltInType',
        map={'false': '-', 'true': ''}, prefix='/Zc:wchar_t')
    cl('EnablePREfast', map={'true': '/analyze'})
    cl('AdditionalOptions', prefix='')
    cl('EnableEnhancedInstructionSet',
       map={'1': 'SSE', '2': 'SSE2', '3': 'AVX', '4': 'IA32'}, prefix='/arch:')
    cflags.extend(['/FI' + f for f in self._Setting(
        ('VCCLCompilerTool', 'ForcedIncludeFiles'), config, default=[])])
    if self.vs_version.short_name in ('2013', '2013e'):
      # New flag required in 2013 to maintain previous PDB behavior.
      cflags.append('/FS')
    # ninja handles parallelism by itself, don't have the compiler do it too.
    cflags = filter(lambda x: not x.startswith('/MP'), cflags)
    return cflags

  def _GetPchFlags(self, config, extension):
    """Get the flags to be added to the cflags for precompiled header support.
    """
    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.
    if self.msvs_precompiled_header[config]:
      source_ext = os.path.splitext(self.msvs_precompiled_source[config])[1]
      if _LanguageMatchesForPch(source_ext, extension):
        pch = os.path.split(self.msvs_precompiled_header[config])[1]
        return ['/Yu' + pch, '/FI' + pch, '/Fp${pchprefix}.' + pch + '.pch']
    return  []

  def GetCflagsC(self, config):
    """Returns the flags that need to be added to .c compilations."""
    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._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._TargetConfig(config)
    libpaths = self._Setting((root, 'AdditionalLibraryDirectories'),
                             config, default=[])
    libpaths = [os.path.normpath(
                    gyp_to_build_path(self.ConvertVSMacros(p, config=config)))
                for p in libpaths]
    return ['/LIBPATH:"' + p + '"' for p in libpaths]

  def GetLibFlags(self, config, gyp_to_build_path):
    """Returns the flags that need to be added to lib commands."""
    config = self._TargetConfig(config)
    libflags = []
    lib = self._GetWrapper(self, self.msvs_settings[config],
                          'VCLibrarianTool', append=libflags)
    libflags.extend(self._GetAdditionalLibraryDirectories(
        'VCLibrarianTool', config, gyp_to_build_path))
    lib('LinkTimeCodeGeneration', map={'true': '/LTCG'})
    lib('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:')
    lib('AdditionalOptions')
    return libflags

  def GetDefFile(self, gyp_to_build_path):
    """Returns the .def file from sources, if any.  Otherwise returns None."""
    spec = self.spec
    if spec['type'] in ('shared_library', 'loadable_module', 'executable'):
      def_files = [s for s in spec.get('sources', []) if s.endswith('.def')]
      if len(def_files) == 1:
        return gyp_to_build_path(def_files[0])
      elif len(def_files) > 1:
        raise Exception("Multiple .def files")
    return None

  def _GetDefFileAsLdflags(self, ldflags, gyp_to_build_path):
    """.def files get implicitly converted to a ModuleDefinitionFile for the
    linker in the VS generator. Emulate that behaviour here."""
    def_file = self.GetDefFile(gyp_to_build_path)
    if def_file:
      ldflags.append('/DEF:"%s"' % def_file)

  def GetPGDName(self, config, expand_special):
    """Gets the explicitly overridden pgd name for a target or returns None
    if it's not overridden."""
    config = self._TargetConfig(config)
    output_file = self._Setting(
        ('VCLinkerTool', 'ProfileGuidedDatabase'), config)
    if output_file:
      output_file = expand_special(self.ConvertVSMacros(
          output_file, config=config))
    return output_file

  def GetLdflags(self, config, gyp_to_build_path, expand_special,
                 manifest_base_name, output_name, is_executable, build_dir):
    """Returns the flags that need to be added to link commands, and the
    manifest files."""
    config = self._TargetConfig(config)
    ldflags = []
    ld = self._GetWrapper(self, self.msvs_settings[config],
                          'VCLinkerTool', append=ldflags)
    self._GetDefFileAsLdflags(ldflags, gyp_to_build_path)
    ld('GenerateDebugInformation', map={'true': '/DEBUG'})
    ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:')
    ldflags.extend(self._GetAdditionalLibraryDirectories(
        'VCLinkerTool', config, gyp_to_build_path))
    ld('DelayLoadDLLs', prefix='/DELAYLOAD:')
    ld('TreatLinkerWarningAsErrors', prefix='/WX',
       map={'true': '', 'false': ':NO'})
    out = self.GetOutputName(config, expand_special)
    if out:
      ldflags.append('/OUT:' + out)
    pdb = self.GetPDBName(config, expand_special, output_name + '.pdb')
    if pdb:
      ldflags.append('/PDB:' + pdb)
    pgd = self.GetPGDName(config, expand_special)
    if pgd:
      ldflags.append('/PGD:' + pgd)
    map_file = self.GetMapFileName(config, expand_special)
    ld('GenerateMapFile', map={'true': '/MAP:' + map_file if map_file
        else '/MAP'})
    ld('MapExports', map={'true': '/MAPINFO:EXPORTS'})
    ld('AdditionalOptions', prefix='')

    minimum_required_version = self._Setting(
        ('VCLinkerTool', 'MinimumRequiredVersion'), config, default='')
    if minimum_required_version:
      minimum_required_version = ',' + minimum_required_version
    ld('SubSystem',
       map={'1': 'CONSOLE%s' % minimum_required_version,
            '2': 'WINDOWS%s' % minimum_required_version},
       prefix='/SUBSYSTEM:')

    ld('TerminalServerAware', map={'1': ':NO', '2': ''}, prefix='/TSAWARE')
    ld('LinkIncremental', map={'1': ':NO', '2': ''}, prefix='/INCREMENTAL')
    ld('BaseAddress', prefix='/BASE:')
    ld('FixedBaseAddress', map={'1': ':NO', '2': ''}, prefix='/FIXED')
    ld('RandomizedBaseAddress',
        map={'1': ':NO', '2': ''}, prefix='/DYNAMICBASE')
    ld('DataExecutionPrevention',
        map={'1': ':NO', '2': ''}, prefix='/NXCOMPAT')
    ld('OptimizeReferences', map={'1': 'NOREF', '2': 'REF'}, prefix='/OPT:')
    ld('ForceSymbolReferences', prefix='/INCLUDE:')
    ld('EnableCOMDATFolding', map={'1': 'NOICF', '2': 'ICF'}, prefix='/OPT:')
    ld('LinkTimeCodeGeneration',
        map={'1': '', '2': ':PGINSTRUMENT', '3': ':PGOPTIMIZE',
             '4': ':PGUPDATE'},
        prefix='/LTCG')
    ld('IgnoreDefaultLibraryNames', prefix='/NODEFAULTLIB:')
    ld('ResourceOnlyDLL', map={'true': '/NOENTRY'})
    ld('EntryPointSymbol', prefix='/ENTRY:')
    ld('Profile', map={'true': '/PROFILE'})
    ld('LargeAddressAware',
        map={'1': ':NO', '2': ''}, prefix='/LARGEADDRESSAWARE')
    ld('ImageHasSafeExceptionHandlers', map={'true': '/SAFESEH'})
    # TODO(scottmg): This should sort of be somewhere else (not really a flag).
    ld('AdditionalDependencies', prefix='')

    # If the base address is not specifically controlled, DYNAMICBASE should
    # be on by default.
    base_flags = filter(lambda x: 'DYNAMICBASE' in x or x == '/FIXED',
                        ldflags)
    if not base_flags:
      ldflags.append('/DYNAMICBASE')

    # If the NXCOMPAT flag has not been specified, default to on. Despite the
    # documentation that says this only defaults to on when the subsystem is
    # Vista or greater (which applies to the linker), the IDE defaults it on
    # unless it's explicitly off.
    if not filter(lambda x: 'NXCOMPAT' in x, ldflags):
      ldflags.append('/NXCOMPAT')

    have_def_file = filter(lambda x: x.startswith('/DEF:'), ldflags)
    manifest_flags, intermediate_manifest, manifest_files = \
        self._GetLdManifestFlags(config, manifest_base_name, gyp_to_build_path,
                                 is_executable and not have_def_file, build_dir)
    ldflags.extend(manifest_flags)
    return ldflags, intermediate_manifest, manifest_files

  def _GetLdManifestFlags(self, config, name, gyp_to_build_path,
                          allow_isolation, build_dir):
    """Returns a 3-tuple:
    - the set of flags that need to be added to the link to generate
      a default manifest
    - the intermediate manifest that the linker will generate that should be
      used to assert it doesn't add anything to the merged one.
    - the list of all the manifest files to be merged by the manifest tool and
      included into the link."""
    generate_manifest = self._Setting(('VCLinkerTool', 'GenerateManifest'),
                                      config,
                                      default='true')
    if generate_manifest != 'true':
      # This means not only that the linker should not generate the intermediate
      # manifest but also that the manifest tool should do nothing even when
      # additional manifests are specified.
      return ['/MANIFEST:NO'], [], []

    output_name = name + '.intermediate.manifest'
    flags = [
      '/MANIFEST',
      '/ManifestFile:' + output_name,
    ]

    # Instead of using the MANIFESTUAC flags, we generate a .manifest to
    # include into the list of manifests. This allows us to avoid the need to
    # do two passes during linking. The /MANIFEST flag and /ManifestFile are
    # still used, and the intermediate manifest is used to assert that the
    # final manifest we get from merging all the additional manifest files
    # (plus the one we generate here) isn't modified by merging the
    # intermediate into it.

    # Always NO, because we generate a manifest file that has what we want.
    flags.append('/MANIFESTUAC:NO')

    config = self._TargetConfig(config)
    enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config,
                               default='true')
    manifest_files = []
    generated_manifest_outer = \
"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" \
"<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>%s" \
"</assembly>"
    if enable_uac == 'true':
      execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'),
                                      config, default='0')
      execution_level_map = {
        '0': 'asInvoker',
        '1': 'highestAvailable',
        '2': 'requireAdministrator'
      }

      ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config,
                                default='false')

      inner = '''
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level='%s' uiAccess='%s' />
    </requestedPrivileges>
  </security>
</trustInfo>''' % (execution_level_map[execution_level], ui_access)
    else:
      inner = ''

    generated_manifest_contents = generated_manifest_outer % inner
    generated_name = name + '.generated.manifest'
    # Need to join with the build_dir here as we're writing it during
    # generation time, but we return the un-joined version because the build
    # will occur in that directory. We only write the file if the contents
    # have changed so that simply regenerating the project files doesn't
    # cause a relink.
    build_dir_generated_name = os.path.join(build_dir, generated_name)
    gyp.common.EnsureDirExists(build_dir_generated_name)
    f = gyp.common.WriteOnDiff(build_dir_generated_name)
    f.write(generated_manifest_contents)
    f.close()
    manifest_files = [generated_name]

    if allow_isolation:
      flags.append('/ALLOWISOLATION')

    manifest_files += self._GetAdditionalManifestFiles(config,
                                                       gyp_to_build_path)
    return flags, output_name, manifest_files

  def _GetAdditionalManifestFiles(self, config, gyp_to_build_path):
    """Gets additional manifest files that are added to the default one
    generated by the linker."""
    files = self._Setting(('VCManifestTool', 'AdditionalManifestFiles'), config,
                          default=[])
    if isinstance(files, str):
      files = files.split(';')
    return [os.path.normpath(
                gyp_to_build_path(self.ConvertVSMacros(f, config=config)))
            for f in files]

  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._TargetConfig(config)
    uldi = self._Setting(('VCLinkerTool', 'UseLibraryDependencyInputs'), config)
    return uldi == 'true'

  def IsEmbedManifest(self, config):
    """Returns whether manifest should be linked into binary."""
    config = self._TargetConfig(config)
    embed = self._Setting(('VCManifestTool', 'EmbedManifest'), config,
                          default='true')
    return embed == 'true'

  def IsLinkIncremental(self, config):
    """Returns whether the target should be linked incrementally."""
    config = self._TargetConfig(config)
    link_inc = self._Setting(('VCLinkerTool', 'LinkIncremental'), config)
    return link_inc != '1'

  def GetRcflags(self, config, gyp_to_ninja_path):
    """Returns the flags that need to be added to invocations of the resource
    compiler."""
    config = self._TargetConfig(config)
    rcflags = []
    rc = self._GetWrapper(self, self.msvs_settings[config],
        'VCResourceCompilerTool', append=rcflags)
    rc('AdditionalIncludeDirectories', map=gyp_to_ninja_path, prefix='/I')
    rcflags.append('/I' + gyp_to_ninja_path('.'))
    rc('PreprocessorDefinitions', prefix='/d')
    # /l arg must be in hex without leading '0x'
    rc('Culture', prefix='/l', map=lambda x: hex(int(x))[2:])
    return rcflags

  def BuildCygwinBashCommandLine(self, args, path_to_base):
    """Build a command line that runs args via cygwin bash. We assume that all
    incoming paths are in Windows normpath'd form, so they need to be
    converted to posix style for the part of the command line that's passed to
    bash. We also have to do some Visual Studio macro emulation here because
    various rules use magic VS names for things. Also note that rules that
    contain ninja variables cannot be fixed here (for example ${source}), so
    the outer generator needs to make sure that the paths that are written out
    are in posix style, if the command line will be used here."""
    cygwin_dir = os.path.normpath(
        os.path.join(path_to_base, self.msvs_cygwin_dirs[0]))
    cd = ('cd %s' % path_to_base).replace('\\', '/')
    args = [a.replace('\\', '/').replace('"', '\\"') for a in args]
    args = ["'%s'" % a.replace("'", "'\\''") for a in args]
    bash_cmd = ' '.join(args)
    cmd = (
        'call "%s\\setup_env.bat" && set CYGWIN=nontsec && ' % cygwin_dir +
        'bash -c "%s ; %s"' % (cd, bash_cmd))
    return cmd

  def IsRuleRunUnderCygwin(self, rule):
    """Determine if an action should be run under cygwin. If the variable is
    unset, or set to 1 we use cygwin."""
    return int(rule.get('msvs_cygwin_shell',
                        self.spec.get('msvs_cygwin_shell', 1))) != 0

  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'] == 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._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),
                                  config=config)
    tlb = midl('TypeLibraryName', default='${root}.tlb')
    header = midl('HeaderFileName', default='${root}.h')
    dlldata = midl('DLLDataFileName', default='dlldata.c')
    iid = midl('InterfaceIdentifierFileName', default='${root}_i.c')
    proxy = midl('ProxyFileName', default='${root}_p.c')
    # Note that .tlb is not included in the outputs as it is not always
    # generated depending on the content of the input idl file.
    outdir = midl('OutputDirectory', default='')
    output = [header, dlldata, iid, proxy]
    variables = [('tlb', tlb),
                 ('h', header),
                 ('dlldata', dlldata),
                 ('iid', iid),
                 ('proxy', proxy)]
    # TODO(scottmg): Are there configuration settings to set these flags?
    target_platform = 'win32' if self.GetArch(config) == 'x86' else 'x64'
    flags = ['/char', 'signed', '/env', target_platform, '/Oicf']
    return outdir, output, variables, flags


def _LanguageMatchesForPch(source_ext, pch_source_ext):
  c_exts = ('.c',)
  cc_exts = ('.cc', '.cxx', '.cpp')
  return ((source_ext in c_exts and pch_source_ext in c_exts) or
          (source_ext in cc_exts and pch_source_ext in cc_exts))


class PrecompiledHeader(object):
  """Helper to generate dependencies and build rules to handle generation of
  precompiled headers. Interface matches the GCH handler in xcode_emulation.py.
  """
  def __init__(
      self, settings, config, gyp_to_build_path, gyp_to_unique_output, obj_ext):
    self.settings = settings
    self.config = config
    pch_source = self.settings.msvs_precompiled_source[self.config]
    self.pch_source = gyp_to_build_path(pch_source)
    filename, _ = os.path.splitext(pch_source)
    self.output_obj = gyp_to_unique_output(filename + obj_ext).lower()

  def _PchHeader(self):
    """Get the header that will appear in an #include line for all source
    files."""
    return os.path.split(self.settings.msvs_precompiled_header[self.config])[1]

  def GetObjDependencies(self, sources, objs, arch):
    """Given a list of sources files and the corresponding object files,
    returns a list of the pch files that should be depended upon. The
    additional wrapping in the return value is for interface compatibility
    with make.py on Mac, and xcode_emulation.py."""
    assert arch is None
    if not self._PchHeader():
      return []
    pch_ext = os.path.splitext(self.pch_source)[1]
    for source in sources:
      if _LanguageMatchesForPch(os.path.splitext(source)[1], pch_ext):
        return [(None, None, self.output_obj)]
    return []

  def GetPchBuildCommands(self, arch):
    """Not used on Windows as there are no additional build steps required
    (instead, existing steps are modified in GetFlagsModifications below)."""
    return []

  def GetFlagsModifications(self, input, output, implicit, command,
                            cflags_c, cflags_cc, expand_special):
    """Get the modified cflags and implicit dependencies that should be used
    for the pch compilation step."""
    if input == self.pch_source:
      pch_output = ['/Yc' + self._PchHeader()]
      if command == 'cxx':
        return ([('cflags_cc', map(expand_special, cflags_cc + pch_output))],
                self.output_obj, [])
      elif command == 'cc':
        return ([('cflags_c', map(expand_special, cflags_c + pch_output))],
                self.output_obj, [])
    return [], output, implicit


vs_version = None
def GetVSVersion(generator_flags):
  global vs_version
  if not vs_version:
    vs_version = gyp.MSVSVersion.SelectVisualStudioVersion(
        generator_flags.get('msvs_version', 'auto'))
  return vs_version

def _GetVsvarsSetupArgs(generator_flags, arch):
  vs = GetVSVersion(generator_flags)
  return vs.SetupScript()

def ExpandMacros(string, expansions):
  """Expand $(Variable) per expansions dict. See MsvsSettings.GetVSMacroEnv
  for the canonical way to retrieve a suitable dict."""
  if '$' in string:
    for old, new in expansions.iteritems():
      assert '$(' not in new, new
      string = string.replace(old, new)
  return string

def _ExtractImportantEnvironment(output_of_set):
  """Extracts environment variables required for the toolchain to run from
  a textual dump output by the cmd.exe 'set' command."""
  envvars_to_save = (
      'goma_.*', # TODO(scottmg): This is ugly, but needed for goma.
      'include',
      'lib',
      'libpath',
      'path',
      'pathext',
      'systemroot',
      'temp',
      'tmp',
      )
  env = {}
  for line in output_of_set.splitlines():
    for envvar in envvars_to_save:
      if re.match(envvar + '=', line.lower()):
        var, setting = line.split('=', 1)
        if envvar == 'path':
          # Our own rules (for running gyp-win-tool) and other actions in
          # Chromium rely on python being in the path. Add the path to this
          # python here so that if it's not in the path when ninja is run
          # later, python will still be found.
          setting = os.path.dirname(sys.executable) + os.pathsep + setting
        env[var.upper()] = setting
        break
  for required in ('SYSTEMROOT', 'TEMP', 'TMP'):
    if required not in env:
      raise Exception('Environment variable "%s" '
                      'required to be set to valid path' % required)
  return env

def _FormatAsEnvironmentBlock(envvar_dict):
  """Format as an 'environment block' directly suitable for CreateProcess.
  Briefly this is a list of key=value\0, terminated by an additional \0. See
  CreateProcess documentation for more details."""
  block = ''
  nul = '\0'
  for key, value in envvar_dict.iteritems():
    block += key + '=' + value + nul
  block += nul
  return block

def _ExtractCLPath(output_of_where):
  """Gets the path to cl.exe based on the output of calling the environment
  setup batch file, followed by the equivalent of `where`."""
  # Take the first line, as that's the first found in the PATH.
  for line in output_of_where.strip().splitlines():
    if line.startswith('LOC:'):
      return line[len('LOC:'):].strip()

def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags,
                             system_includes, open_out):
  """It's not sufficient to have the absolute path to the compiler, linker,
  etc. on Windows, as those tools rely on .dlls being in the PATH. We also
  need to support both x86 and x64 compilers within the same build (to support
  msvs_target_platform hackery). Different architectures require a different
  compiler binary, and different supporting environment variables (INCLUDE,
  LIB, LIBPATH). So, we extract the environment here, wrap all invocations
  of compiler tools (cl, link, lib, rc, midl, etc.) via win_tool.py which
  sets up the environment, and then we do not prefix the compiler with
  an absolute path, instead preferring something like "cl.exe" in the rule
  which will then run whichever the environment setup has put in the path.
  When the following procedure to generate environment files does not
  meet your requirement (e.g. for custom toolchains), you can pass
  "-G ninja_use_custom_environment_files" to the gyp to suppress file
  generation and use custom environment files prepared by yourself."""
  archs = ('x86', 'x64')
  if generator_flags.get('ninja_use_custom_environment_files', 0):
    cl_paths = {}
    for arch in archs:
      cl_paths[arch] = 'cl.exe'
    return cl_paths
  vs = GetVSVersion(generator_flags)
  cl_paths = {}
  for arch in archs:
    # Extract environment variables for subprocesses.
    args = vs.SetupScript(arch)
    args.extend(('&&', 'set'))
    popen = subprocess.Popen(
        args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    variables, _ = popen.communicate()
    env = _ExtractImportantEnvironment(variables)

    # Inject system includes from gyp files into INCLUDE.
    if system_includes:
      system_includes = system_includes | OrderedSet(
                                              env.get('INCLUDE', '').split(';'))
      env['INCLUDE'] = ';'.join(system_includes)

    env_block = _FormatAsEnvironmentBlock(env)
    f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb')
    f.write(env_block)
    f.close()

    # Find cl.exe location for this architecture.
    args = vs.SetupScript(arch)
    args.extend(('&&',
      'for', '%i', 'in', '(cl.exe)', 'do', '@echo', 'LOC:%~$PATH:i'))
    popen = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE)
    output, _ = popen.communicate()
    cl_paths[arch] = _ExtractCLPath(output)
  return cl_paths

def VerifyMissingSources(sources, build_dir, generator_flags, gyp_to_ninja):
  """Emulate behavior of msvs_error_on_missing_sources present in the msvs
  generator: Check that all regular source files, i.e. not created at run time,
  exist on disk. Missing files cause needless recompilation when building via
  VS, and we want this check to match for people/bots that build using ninja,
  so they're not surprised when the VS build fails."""
  if int(generator_flags.get('msvs_error_on_missing_sources', 0)):
    no_specials = filter(lambda x: '$' not in x, sources)
    relative = [os.path.join(build_dir, gyp_to_ninja(s)) for s in no_specials]
    missing = filter(lambda x: not os.path.exists(x), relative)
    if missing:
      # They'll look like out\Release\..\..\stuff\things.cc, so normalize the
      # path for a slightly less crazy looking output.
      cleaned_up = [os.path.normpath(x) for x in missing]
      raise Exception('Missing input files:\n%s' % '\n'.join(cleaned_up))

# Sets some values in default_variables, which are required for many
# generators, run on Windows.
def CalculateCommonVariables(default_variables, params):
  generator_flags = params.get('generator_flags', {})

  # Set a variable so conditions can be based on msvs_version.
  msvs_version = gyp.msvs_emulation.GetVSVersion(generator_flags)
  default_variables['MSVS_VERSION'] = msvs_version.ShortName()

  # To determine processor word size on Windows, in addition to checking
  # PROCESSOR_ARCHITECTURE (which reflects the word size of the current
  # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which
  # contains the actual word size of the system when running thru WOW64).
  if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or
      '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')):
    default_variables['MSVS_OS_BITS'] = 64
  else:
    default_variables['MSVS_OS_BITS'] = 32
