#!/usr/bin/python
# Copyright (c) 2012 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""NaCl SDK tool SCons."""

import __builtin__
import re
import os
import shutil
import sys
import SCons.Scanner
import SCons.Script
import subprocess
import tempfile


NACL_TOOL_MAP = {
    'arm': {
        '32': {
            'tooldir': 'arm-nacl',
            'as_flag': '',
            'cc_flag': '',
            'ld_flag': '',
            },
        },
    'x86': {
        '32': {
            'tooldir': 'i686-nacl',
            'other_libdir': 'lib32',
            'as_flag': '--32',
            'cc_flag': '-m32',
            'ld_flag': ' -melf_i386_nacl',
            },
        '64': {
            'tooldir': 'x86_64-nacl',
            'other_libdir': 'lib64',
            'as_flag': '--64',
            'cc_flag': '-m64',
            'ld_flag': ' -melf_x86_64_nacl',
            },
        },
    }

def _StubOutEnvToolsForBuiltElsewhere(env):
  """Stub out all tools so that they point to 'true'.

  Some machines have their code built by another machine, they'll therefore
  run 'true' instead of running the usual build tools.

  Args:
    env: The SCons environment in question.
  """
  assert(env.Bit('built_elsewhere'))
  env.Replace(CC='true', CXX='true', LINK='true', AR='true',
              RANLIB='true', AS='true', ASPP='true', LD='true',
              STRIP='true', PNACLOPT='true', PNACLFINALIZE='true')


def _SetEnvForNativeSdk(env, sdk_path):
  """Initialize environment according to target architecture."""

  bin_path = os.path.join(sdk_path, 'bin')
  # NOTE: attempts to eliminate this PATH setting and use
  #       absolute path have been futile
  env.PrependENVPath('PATH', bin_path)

  tool_prefix = None
  tool_map = NACL_TOOL_MAP[env['TARGET_ARCHITECTURE']]
  subarch_spec = tool_map[env['TARGET_SUBARCH']]
  tooldir = subarch_spec['tooldir']
  # We need to pass it extra options for the subarch we are building.
  as_mode_flag = subarch_spec['as_flag']
  cc_mode_flag = subarch_spec['cc_flag']
  ld_mode_flag = subarch_spec['ld_flag']
  if os.path.exists(os.path.join(sdk_path, tooldir)):
    # The tooldir for the build target exists.
    # The tools there do the right thing without special options.
    tool_prefix = tooldir
    libdir = os.path.join(tooldir, 'lib')
  else:
    # We're building for a target for which there is no matching tooldir.
    # For example, for x86-32 when only <sdk_path>/x86_64-nacl/ exists.
    # Find a tooldir for a different subarch that does exist.
    others_map = tool_map.copy()
    del others_map[env['TARGET_SUBARCH']]
    for subarch, tool_spec in others_map.iteritems():
      tooldir = tool_spec['tooldir']
      if os.path.exists(os.path.join(sdk_path, tooldir)):
        # OK, this is the other subarch to use as tooldir.
        tool_prefix = tooldir
        # The lib directory may have an alternate name, i.e.
        # 'lib32' in the x86_64-nacl tooldir.
        libdir = os.path.join(tooldir, subarch_spec.get('other_libdir', 'lib'))
        break

  if tool_prefix is None:
    raise Exception("Cannot find a toolchain for %s in %s" %
                    (env['TARGET_FULLARCH'], sdk_path))

  env.Replace(# Replace header and lib paths.
              # where to put nacl extra sdk headers
              # TODO(robertm): switch to using the mechanism that
              #                passes arguments to scons
              NACL_SDK_INCLUDE='%s/%s/include' % (sdk_path, tool_prefix),
              # where to find/put nacl generic extra sdk libraries
              NACL_SDK_LIB='%s/%s' % (sdk_path, libdir),
              # Replace the normal unix tools with the NaCl ones.
              CC=os.path.join(bin_path, '%s-gcc' % tool_prefix),
              CXX=os.path.join(bin_path, '%s-g++' % tool_prefix),
              AR=os.path.join(bin_path, '%s-ar' % tool_prefix),
              AS=os.path.join(bin_path, '%s-as' % tool_prefix),
              ASPP=os.path.join(bin_path, '%s-gcc' % tool_prefix),
              GDB=os.path.join(bin_path, '%s-gdb' % tool_prefix),
              # NOTE: use g++ for linking so we can handle C AND C++.
              LINK=os.path.join(bin_path, '%s-g++' % tool_prefix),
              # Grrr... and sometimes we really need ld.
              LD=os.path.join(bin_path, '%s-ld' % tool_prefix) + ld_mode_flag,
              RANLIB=os.path.join(bin_path, '%s-ranlib' % tool_prefix),
              NM=os.path.join(bin_path, '%s-nm' % tool_prefix),
              OBJDUMP=os.path.join(bin_path, '%s-objdump' % tool_prefix),
              STRIP=os.path.join(bin_path, '%s-strip' % tool_prefix),
              ADDR2LINE=os.path.join(bin_path, '%s-addr2line' % tool_prefix),
              BASE_LINKFLAGS=[cc_mode_flag],
              BASE_CFLAGS=[cc_mode_flag],
              BASE_CXXFLAGS=[cc_mode_flag],
              BASE_ASFLAGS=[as_mode_flag],
              BASE_ASPPFLAGS=[cc_mode_flag],
              CFLAGS=['-std=gnu99'],
              CCFLAGS=['-O3',
                       '-Werror',
                       '-Wall',
                       '-Wno-variadic-macros',
                       '-Wswitch-enum',
                       '-g',
                       '-fno-stack-protector',
                       '-fdiagnostics-show-option',
                       '-pedantic',
                       '-D__linux__',
                       ],
              ASFLAGS=[],
              )

  # NaClSdk environment seems to be inherited from the host environment.
  # On Linux host, this probably makes sense. On Windows and Mac, this
  # introduces nothing except problems.
  # For now, simply override the environment settings as in
  # <scons>/engine/SCons/Platform/posix.py
  env.Replace(LIBPREFIX='lib',
              LIBSUFFIX='.a',
              SHLIBPREFIX='$LIBPREFIX',
              SHLIBSUFFIX='.so',
              LIBPREFIXES=['$LIBPREFIX'],
              LIBSUFFIXES=['$LIBSUFFIX', '$SHLIBSUFFIX'],
              )
  # Force -fPIC when compiling for shared libraries.
  env.AppendUnique(SHCCFLAGS=['-fPIC'],
                   )

def _SetEnvForPnacl(env, root):
  # All the PNaCl tools require Python to be in the PATH.
  arch = env['TARGET_FULLARCH']
  assert arch in ['arm', 'mips32', 'x86-32', 'x86-64']

  if env.Bit('pnacl_unsandboxed'):
    if env.Bit('host_linux'):
      arch = '%s-linux' % arch
    elif env.Bit('host_mac'):
      arch = '%s-mac' % arch
  if env.Bit('nonsfi_nacl'):
    arch += '-nonsfi'
  arch_flag = ' -arch %s' % arch
  if env.Bit('pnacl_generate_pexe'):
    ld_arch_flag = ''
  else:
    ld_arch_flag = arch_flag

  llc_mtriple_flag = ''
  if env.Bit('minsfi'):
    llc_cpu = ''
    if env.Bit('build_x86_32'):
      llc_cpu = 'i686'
    elif env.Bit('build_x86_64'):
      llc_cpu = 'x86_64'

    if env.Bit('host_linux'):
      llc_mtriple_flag = ' -mtriple=%s-linux-gnu' % llc_cpu
    elif env.Bit('host_mac'):
      llc_mtriple_flag = ' -mtriple=%s-apple-darwin' % llc_cpu

  translator_root = os.path.join(os.path.dirname(root), 'pnacl_translator')

  binprefix = os.path.join(root, 'bin', 'pnacl-')
  binext = ''
  if env.Bit('host_windows'):
    binext = '.bat'

  pnacl_ar = binprefix + 'ar' + binext
  pnacl_as = binprefix + 'as' + binext
  pnacl_nm = binprefix + 'nm' + binext
  pnacl_ranlib = binprefix + 'ranlib' + binext
  # Use the standalone sandboxed translator in sbtc mode
  if env.Bit('use_sandboxed_translator'):
    pnacl_translate = os.path.join(translator_root, 'bin',
                                   'pnacl-translate' + binext)
  else:
    pnacl_translate = binprefix + 'translate' + binext

  pnacl_cc = binprefix + 'clang' + binext
  pnacl_cxx = binprefix + 'clang++' + binext

  pnacl_ld = binprefix + 'ld' + binext
  pnacl_disass = binprefix + 'dis' + binext
  pnacl_finalize = binprefix + 'finalize' + binext
  pnacl_opt = binprefix + 'opt' + binext
  pnacl_strip = binprefix + 'strip' + binext
  pnacl_llc = binprefix + 'llc' + binext

  # NOTE: XXX_flags start with space for easy concatenation
  # The flags generated here get baked into the commands (CC, CXX, LINK)
  # instead of CFLAGS etc to keep them from getting blown away by some
  # tests. Don't add flags here unless they always need to be preserved.
  pnacl_cxx_flags = ''
  pnacl_cc_flags = ' -std=gnu99'
  pnacl_ld_flags = ' ' + ' '.join(env['PNACL_BCLDFLAGS'])
  pnacl_translate_flags = ''
  pnacl_llc_flags = ''

  if env.Bit('nacl_pic'):
    pnacl_cc_flags += ' -fPIC'
    pnacl_cxx_flags += ' -fPIC'
    # NOTE: this is a special hack for the pnacl backend which
    #       does more than linking
    pnacl_ld_flags += ' -fPIC'
    pnacl_translate_flags += ' -fPIC'

  if env.Bit('minsfi'):
    pnacl_llc_flags += ' -relocation-model=pic -filetype=obj'
    pnacl_ld_flags += ' -nostdlib -Wl,-r -L' + os.path.join(root, 'usr', 'lib')

  if env.Bit('use_sandboxed_translator'):
    sb_flags = ' --pnacl-sb'
    pnacl_ld_flags += sb_flags
    pnacl_translate_flags += sb_flags

  if env.Bit('x86_64_zero_based_sandbox'):
    pnacl_translate_flags += ' -sfi-zero-based-sandbox'

  env.Replace(# Replace header and lib paths.
              NACL_SDK_INCLUDE=os.path.join(root, 'le32-nacl', 'include'),
              NACL_SDK_LIB=os.path.join(root, 'le32-nacl', 'lib'),
              # Remove arch-specific flags (if any)
              BASE_LINKFLAGS='',
              BASE_CFLAGS='',
              BASE_CXXFLAGS='',
              BASE_ASFLAGS='',
              BASE_ASPPFLAGS='',
              # Replace the normal unix tools with the PNaCl ones.
              CC=pnacl_cc + pnacl_cc_flags,
              CXX=pnacl_cxx + pnacl_cxx_flags,
              ASPP=pnacl_cc + pnacl_cc_flags,
              LIBPREFIX="lib",
              SHLIBPREFIX="lib",
              SHLIBSUFFIX=".so",
              OBJSUFFIX=".bc",
              LINK=pnacl_cxx + ld_arch_flag + pnacl_ld_flags,
              # Although we are currently forced to produce native output
              # for LINK, we are free to produce bitcode for SHLINK
              # (SharedLibrary linking) because scons doesn't do anything
              # with shared libraries except use them with the toolchain.
              SHLINK=pnacl_cxx + ld_arch_flag + pnacl_ld_flags,
              LD=pnacl_ld,
              AR=pnacl_ar,
              AS=pnacl_as + ld_arch_flag,
              RANLIB=pnacl_ranlib,
              DISASS=pnacl_disass,
              OBJDUMP=pnacl_disass,
              STRIP=pnacl_strip,
              TRANSLATE=pnacl_translate + arch_flag + pnacl_translate_flags,
              PNACLFINALIZE=pnacl_finalize,
              PNACLOPT=pnacl_opt,
              LLC=pnacl_llc + llc_mtriple_flag + pnacl_llc_flags,
              )

  if env.Bit('built_elsewhere'):
    def FakeInstall(dest, source, env):
      print 'Not installing', dest
    _StubOutEnvToolsForBuiltElsewhere(env)
    env.Replace(INSTALL=FakeInstall)
    if env.Bit('translate_in_build_step'):
      env.Replace(TRANSLATE='true')
    env.Replace(PNACLFINALIZE='true')


def PNaClForceNative(env):
  assert(env.Bit('bitcode'))
  if env.Bit('pnacl_generate_pexe'):
    env.Replace(CC='NO-NATIVE-CC-INVOCATION-ALLOWED',
                CXX='NO-NATIVE-CXX-INVOCATION-ALLOWED')
    return

  env.Replace(OBJSUFFIX='.o',
              SHLIBSUFFIX='.so')
  arch_flag = ' -arch ${TARGET_FULLARCH}'
  cc_flags = ' --pnacl-allow-native --pnacl-allow-translate'
  env.Append(CC=arch_flag + cc_flags,
             CXX=arch_flag + cc_flags,
             ASPP=arch_flag + cc_flags,
             LINK=cc_flags) # Already has -arch
  env['LD'] = 'NO-NATIVE-LD-INVOCATION-ALLOWED'
  env['SHLINK'] = '${LINK}'
  if env.Bit('built_elsewhere'):
    _StubOutEnvToolsForBuiltElsewhere(env)

# Get an environment for nacl-gcc when in PNaCl mode.
def PNaClGetNNaClEnv(env):
  assert(env.Bit('bitcode'))
  assert(not env.Bit('target_mips32'))

  # This is kind of a hack. We clone the environment,
  # clear the bitcode bit, and then reload naclsdk.py
  native_env = env.Clone()
  native_env.ClearBits('bitcode')
  if env.Bit('built_elsewhere'):
    _StubOutEnvToolsForBuiltElsewhere(env)
  else:
    native_env = native_env.Clone(tools=['naclsdk'])
    if native_env.Bit('pnacl_generate_pexe'):
      native_env.Replace(CC='NO-NATIVE-CC-INVOCATION-ALLOWED',
                         CXX='NO-NATIVE-CXX-INVOCATION-ALLOWED')
    else:
      # These are unfortunately clobbered by running Tool.
      native_env.Replace(EXTRA_CFLAGS=env['EXTRA_CFLAGS'],
                         EXTRA_CXXFLAGS=env['EXTRA_CXXFLAGS'],
                         CCFLAGS=env['CCFLAGS'],
                         CFLAGS=env['CFLAGS'],
                         CXXFLAGS=env['CXXFLAGS'])
  return native_env


# This adds architecture specific defines for the target architecture.
# These are normally omitted by PNaCl.
# For example: __i686__, __arm__, __mips__, __x86_64__
def AddBiasForPNaCl(env, temporarily_allow=True):
  assert(env.Bit('bitcode'))
  # re: the temporarily_allow flag -- that is for:
  # BUG= http://code.google.com/p/nativeclient/issues/detail?id=1248
  if env.Bit('pnacl_generate_pexe') and not temporarily_allow:
    env.Replace(CC='NO-NATIVE-CC-INVOCATION-ALLOWED',
                CXX='NO-NATIVE-CXX-INVOCATION-ALLOWED')
    return

  if env.Bit('target_arm'):
    env.AppendUnique(CCFLAGS=['--pnacl-arm-bias'],
                     ASPPFLAGS=['--pnacl-arm-bias'])
  elif env.Bit('target_x86_32'):
    env.AppendUnique(CCFLAGS=['--pnacl-i686-bias'],
                     ASPPFLAGS=['--pnacl-i686-bias'])
  elif env.Bit('target_x86_64'):
    env.AppendUnique(CCFLAGS=['--pnacl-x86_64-bias'],
                     ASPPFLAGS=['--pnacl-x86_64-bias'])
  elif env.Bit('target_mips32'):
    env.AppendUnique(CCFLAGS=['--pnacl-mips-bias'],
                     ASPPFLAGS=['--pnacl-mips-bias'])
  else:
    raise Exception("Unknown architecture!")


def ValidateSdk(env):
  checkables = ['${NACL_SDK_INCLUDE}/stdio.h']
  for c in checkables:
    if os.path.exists(env.subst(c)):
      continue
    # Windows build does not use cygwin and so can not see nacl subdirectory
    # if it's cygwin's symlink - check for /include instead...
    if os.path.exists(re.sub(r'(nacl64|nacl)/include/([^/]*)$',
                             r'include/\2',
                             env.subst(c))):
      continue
    # TODO(pasko): remove the legacy header presence test below.
    if os.path.exists(re.sub(r'nacl/include/([^/]*)$',
                             r'nacl64/include/\1',
                             env.subst(c))):
      continue
    message = env.subst('''
ERROR: NativeClient toolchain does not seem present!,
       Missing: %s

Configuration is:
  NACL_SDK_INCLUDE=${NACL_SDK_INCLUDE}
  NACL_SDK_LIB=${NACL_SDK_LIB}
  CC=${CC}
  CXX=${CXX}
  AR=${AR}
  AS=${AS}
  ASPP=${ASPP}
  LINK=${LINK}
  RANLIB=${RANLIB}

Run: gclient runhooks --force or build the SDK yourself.
''' % c)
    sys.stderr.write(message + "\n\n")
    sys.exit(-1)


def ScanLinkerScript(node, env, libpath):
  """SCons scanner for linker script files.
This handles trivial linker scripts like those used for libc.so and libppapi.a.
These scripts just indicate more input files to be linked in, so we want
to produce dependencies on them.

A typical such linker script looks like:

        /* Some comments.  */
        INPUT ( foo.a libbar.a libbaz.a )

or:

        /* GNU ld script
           Use the shared library, but some functions are only in
           the static library, so try that secondarily.  */
        OUTPUT_FORMAT(elf64-x86-64)
        GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a
                AS_NEEDED ( /lib/ld-linux-x86-64.so.2 ) )
"""
  contents = node.get_text_contents()
  if contents.startswith('!<arch>\n') or contents.startswith('\177ELF'):
    # An archive or ELF file is not a linker script.
    return []

  comment_pattern = re.compile(r'/\*.*?\*/', re.DOTALL | re.MULTILINE)
  def remove_comments(text):
    return re.sub(comment_pattern, '', text)

  tokens = remove_comments(contents).split()
  libs = []
  while tokens:
    token = tokens.pop()
    if token.startswith('OUTPUT_FORMAT('):
      pass
    elif token == 'OUTPUT_FORMAT':
      # Swallow the next three tokens: '(', 'xyz', ')'
      del tokens[0:2]
    elif token in ['(', ')', 'INPUT', 'GROUP', 'AS_NEEDED']:
      pass
    else:
      libs.append(token)

  # Find those items in the library path, ignoring ones we fail to find.
  found = [SCons.Node.FS.find_file(lib, libpath) for lib in libs]
  return [lib for lib in found if lib is not None]

# This is a modified copy of the class TempFileMunge in
# third_party/scons-2.0.1/engine/SCons/Platform/__init__.py.
# It differs in using quote_for_at_file (below) in place of
# SCons.Subst.quote_spaces.
class NaClTempFileMunge(object):
  """A callable class.  You can set an Environment variable to this,
  then call it with a string argument, then it will perform temporary
  file substitution on it.  This is used to circumvent the long command
  line limitation.

  Example usage:
  env["TEMPFILE"] = TempFileMunge
  env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES')}"

  By default, the name of the temporary file used begins with a
  prefix of '@'.  This may be configred for other tool chains by
  setting '$TEMPFILEPREFIX'.

  env["TEMPFILEPREFIX"] = '-@'        # diab compiler
  env["TEMPFILEPREFIX"] = '-via'      # arm tool chain
  """
  def __init__(self, cmd):
    self.cmd = cmd

  def __call__(self, target, source, env, for_signature):
    if for_signature:
      # If we're being called for signature calculation, it's
      # because we're being called by the string expansion in
      # Subst.py, which has the logic to strip any $( $) that
      # may be in the command line we squirreled away.  So we
      # just return the raw command line and let the upper
      # string substitution layers do their thing.
      return self.cmd

    # Now we're actually being called because someone is actually
    # going to try to execute the command, so we have to do our
    # own expansion.
    cmd = env.subst_list(self.cmd, SCons.Subst.SUBST_CMD, target, source)[0]
    try:
      maxline = int(env.subst('$MAXLINELENGTH'))
    except ValueError:
      maxline = 2048

    length = 0
    for c in cmd:
      length += len(c)
    if length <= maxline:
      return self.cmd

    # We do a normpath because mktemp() has what appears to be
    # a bug in Windows that will use a forward slash as a path
    # delimiter.  Windows's link mistakes that for a command line
    # switch and barfs.
    #
    # We use the .lnk suffix for the benefit of the Phar Lap
    # linkloc linker, which likes to append an .lnk suffix if
    # none is given.
    (fd, tmp) = tempfile.mkstemp('.lnk', text=True)
    native_tmp = SCons.Util.get_native_path(os.path.normpath(tmp))

    if env['SHELL'] and env['SHELL'] == 'sh':
      # The sh shell will try to escape the backslashes in the
      # path, so unescape them.
      native_tmp = native_tmp.replace('\\', r'\\\\')
      # In Cygwin, we want to use rm to delete the temporary
      # file, because del does not exist in the sh shell.
      rm = env.Detect('rm') or 'del'
    else:
      # Don't use 'rm' if the shell is not sh, because rm won't
      # work with the Windows shells (cmd.exe or command.com) or
      # Windows path names.
      rm = 'del'

    prefix = env.subst('$TEMPFILEPREFIX')
    if not prefix:
      prefix = '@'

    # The @file is sometimes handled by a GNU tool itself, using
    # the libiberty/argv.c code, and sometimes handled implicitly
    # by Cygwin before the tool's own main even sees it.  These
    # two treat the contents differently, so there is no single
    # perfect way to quote.  The libiberty @file code uses a very
    # regular scheme: a \ in any context is always swallowed and
    # quotes the next character, whatever it is; '...' or "..."
    # quote whitespace in ... and the outer quotes are swallowed.
    # The Cygwin @file code uses a vaguely similar scheme, but its
    # treatment of \ is much less consistent: a \ outside a quoted
    # string is never stripped, and a \ inside a quoted string is
    # only stripped when it quoted something (Cygwin's definition
    # of "something" here is nontrivial).  In our uses the only
    # appearances of \ we expect are in Windows-style file names.
    # Fortunately, an extra doubling of \\ that doesn't get
    # stripped is harmless in the middle of a file name.
    def quote_for_at_file(s):
      s = str(s)
      if ' ' in s or '\t' in s:
        return '"' + re.sub('([ \t"])', r'\\\1', s) + '"'
      return s.replace('\\', '\\\\')

    args = list(map(quote_for_at_file, cmd[1:]))
    os.write(fd, " ".join(args) + "\n")
    os.close(fd)
    # XXX Using the SCons.Action.print_actions value directly
    # like this is bogus, but expedient.  This class should
    # really be rewritten as an Action that defines the
    # __call__() and strfunction() methods and lets the
    # normal action-execution logic handle whether or not to
    # print/execute the action.  The problem, though, is all
    # of that is decided before we execute this method as
    # part of expanding the $TEMPFILE construction variable.
    # Consequently, refactoring this will have to wait until
    # we get more flexible with allowing Actions to exist
    # independently and get strung together arbitrarily like
    # Ant tasks.  In the meantime, it's going to be more
    # user-friendly to not let obsession with architectural
    # purity get in the way of just being helpful, so we'll
    # reach into SCons.Action directly.
    if SCons.Action.print_actions:
      print("Using tempfile "+native_tmp+" for command line:\n"+
            str(cmd[0]) + " " + " ".join(args))
    return [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ]

def generate(env):
  """SCons entry point for this tool.

  Args:
    env: The SCons environment in question.

  NOTE: SCons requires the use of this name, which fails lint.
  """

  # make these methods to the top level scons file
  env.AddMethod(ValidateSdk)
  env.AddMethod(AddBiasForPNaCl)
  env.AddMethod(PNaClForceNative)
  env.AddMethod(PNaClGetNNaClEnv)

  # Invoke the various unix tools that the NativeClient SDK resembles.
  env.Tool('g++')
  env.Tool('gcc')
  env.Tool('gnulink')
  env.Tool('ar')
  env.Tool('as')

  if env.Bit('pnacl_generate_pexe'):
    suffix = '.nonfinal.pexe'
  else:
    suffix = '.nexe'

  env.Replace(
      COMPONENT_LINKFLAGS=[''],
      COMPONENT_LIBRARY_LINK_SUFFIXES=['.pso', '.so', '.a'],
      _RPATH='',
      COMPONENT_LIBRARY_DEBUG_SUFFIXES=[],
      PROGSUFFIX=suffix,
      # adding BASE_ AND EXTRA_ flags to common command lines
      # The suggested usage pattern is:
      # BASE_XXXFLAGS can only be set in this file
      # EXTRA_XXXFLAGS can only be set in a ComponentXXX call
      # NOTE: we also have EXTRA_LIBS which is handles separately in
      # site_scons/site_tools/component_builders.py
      # NOTE: the command lines were gleaned from:
      # * ../third_party/scons-2.0.1/engine/SCons/Tool/cc.py
      # * ../third_party/scons-2.0.1/engine/SCons/Tool/c++.py
      # * etc.
      CCCOM='$CC $BASE_CFLAGS $CFLAGS $EXTRA_CFLAGS ' +
            '$CCFLAGS $_CCCOMCOM -c -o $TARGET $SOURCES',
      SHCCCOM='$SHCC $BASE_CFLAGS $SHCFLAGS $EXTRA_CFLAGS ' +
              '$SHCCFLAGS $_CCCOMCOM -c -o $TARGET $SOURCES',

      CXXCOM='$CXX $BASE_CXXFLAGS $CXXFLAGS $EXTRA_CXXFLAGS ' +
             '$CCFLAGS $_CCCOMCOM -c -o $TARGET $SOURCES',
      SHCXXCOM='$SHCXX $BASE_CXXFLAGS $SHCXXFLAGS $EXTRA_CXXFLAGS ' +
               '$SHCCFLAGS $_CCCOMCOM -c -o $TARGET $SOURCES',

      LINKCOM='$LINK $BASE_LINKFLAGS $LINKFLAGS $EXTRA_LINKFLAGS ' +
              '$SOURCES $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET',
      SHLINKCOM='$SHLINK $BASE_LINKFLAGS $SHLINKFLAGS $EXTRA_LINKFLAGS ' +
                '$SOURCES $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET',

      ASCOM='$AS $BASE_ASFLAGS $ASFLAGS $EXTRA_ASFLAGS -o $TARGET $SOURCES',
      ASPPCOM='$ASPP $BASE_ASPPFLAGS $ASPPFLAGS $EXTRA_ASPPFLAGS ' +
              '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES',

      # Strip doesn't seem to be a first-class citizen in SCons country,
      # so we have to add these *COM, *COMSTR manually.
      # Note: it appears we cannot add this in component_setup.py
      STRIPFLAGS=['--strip-all'],
      STRIPCOM='${STRIP} ${STRIPFLAGS}',
      TRANSLATECOM='${TRANSLATE} ${TRANSLATEFLAGS} ${SOURCES} -o ${TARGET}',
      PNACLFINALIZEFLAGS=[],
      PNACLFINALIZECOM='${PNACLFINALIZE} ${PNACLFINALIZEFLAGS} ' +
                       '${SOURCES} -o ${TARGET}',
  )

  # Windows has a small limit on the command line size.  The linking and AR
  # commands can get quite large.  So bring in the SCons machinery to put
  # most of a command line into a temporary file and pass it with
  # @filename, which works with gcc.
  if env['PLATFORM'] in ['win32', 'cygwin']:
    env['TEMPFILE'] = NaClTempFileMunge
    for com in ['LINKCOM', 'SHLINKCOM', 'ARCOM']:
      env[com] = "${TEMPFILE('%s')}" % env[com]

  # Get root of the SDK.
  root = env.GetToolchainDir()

  # if bitcode=1 use pnacl toolchain
  if env.Bit('bitcode'):
    _SetEnvForPnacl(env, root)

    # Get GDB from the nacl-gcc toolchain even when using PNaCl.
    # TODO(mseaborn): We really want the nacl-gdb binary to be in a
    # separate tarball from the nacl-gcc toolchain, then this step
    # will not be necessary.
    # See http://code.google.com/p/nativeclient/issues/detail?id=2773
    if env.Bit('target_x86'):
      temp_env = env.Clone()
      temp_env.ClearBits('bitcode')
      temp_root = temp_env.GetToolchainDir()
      _SetEnvForNativeSdk(temp_env, temp_root)
      env.Replace(GDB=temp_env['GDB'])
  elif env.Bit('built_elsewhere'):
    _StubOutEnvToolsForBuiltElsewhere(env)
  else:
    _SetEnvForNativeSdk(env, root)

  env.Prepend(LIBPATH='${NACL_SDK_LIB}')

  # Install our scanner for (potential) linker scripts.
  # It applies to "source" files ending in .a or .so.
  # Dependency files it produces are to be found in ${LIBPATH}.
  # It is applied recursively to those dependencies in case
  # some of them are linker scripts too.
  ldscript_scanner = SCons.Scanner.Base(
      function=ScanLinkerScript,
      skeys=['.a', '.so', '.pso'],
      path_function=SCons.Scanner.FindPathDirs('LIBPATH'),
      recursive=True
      )
  env.Append(SCANNERS=ldscript_scanner)

  # Scons tests can check this version number to decide whether to
  # enable tests for toolchain bug fixes or new features.  See
  # description in pnacl/build.sh.
  if 'toolchain_feature_version' in SCons.Script.ARGUMENTS:
    version = int(SCons.Script.ARGUMENTS['toolchain_feature_version'])
  else:
    version_file = os.path.join(root, 'FEATURE_VERSION')
    # There is no pnacl_newlib toolchain on ARM, only a pnacl_translator, so
    # use that if necessary. Otherwise use it if we are doing sandboxed
    # translation.
    if not os.path.exists(version_file) or env.Bit('use_sandboxed_translator'):
      version_file = os.path.join(os.path.dirname(root), 'pnacl_translator',
                                  'FEATURE_VERSION')
    if os.path.exists(version_file):
      with open(version_file, 'r') as fh:
        version = int(fh.read())
    else:
      version = 0
  env.Replace(TOOLCHAIN_FEATURE_VERSION=version)
