#!/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.

"""Recipes for NativeClient toolchain packages.

The real entry plumbing is in toolchain_main.py.
"""

import argparse
import fnmatch
import os
import process
import stat
import shutil
import StringIO
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import pynacl.gsd_storage
import pynacl.hashing_tools
import pynacl.log_tools
import pynacl.platform
import pynacl.repo_tools

BUILD_SCRIPT = os.path.abspath(__file__)
TOOLCHAIN_BUILD = os.path.dirname(BUILD_SCRIPT)
NATIVE_CLIENT = os.path.dirname(TOOLCHAIN_BUILD)
PKG_VERSION = os.path.join(NATIVE_CLIENT, 'build', 'package_version')
sys.path.append(PKG_VERSION)
import archive_info
import package_info

import toolchain_build
import toolchain_main

from file_update import Mkdir, Rmdir, Symlink
from file_update import NeedsUpdate, UpdateFromTo, UpdateText


BIONIC_VERSION = 'ad898e29b1e4fae5c6c65a873ca4828af90be46c'
ARCHES = ['arm']
TOOLCHAIN_BUILD_SRC = os.path.join(TOOLCHAIN_BUILD, 'src')
TOOLCHAIN_BUILD_OUT = os.path.join(TOOLCHAIN_BUILD, 'out')

BIONIC_SRC = os.path.join(TOOLCHAIN_BUILD_SRC, 'bionic')
TOOLCHAIN = os.path.join(NATIVE_CLIENT, 'toolchain')


def GetToolchainPath(target_arch, libc, *extra_paths):
  os_name = pynacl.platform.GetOS()
  host_arch = pynacl.platform.GetArch()
  return os.path.join(TOOLCHAIN,
                      '%s_%s' % (os_name, host_arch),
                      'nacl_%s_%s' % (target_arch, libc),
                      *extra_paths)


def GetBionicBuildPath(target_arch, *extra_paths):
  os_name = pynacl.platform.GetOS()
  return os.path.join(TOOLCHAIN_BUILD_OUT,
                      "%s_%s_bionic" % (os_name, target_arch),
                      *extra_paths)


def ReplaceText(text, maplist):
  for m in maplist:
    for key in m:
      text = text.replace(key, m[key])
  return text


def ReplaceArch(text, arch, subarch=None):
  NACL_ARCHES = {
    'arm': 'arm',
    'x86': 'x86_64',
    'pnacl': 'pnacl'
  }
  GCC_ARCHES = {
    'arm': 'arm',
    'x86': 'i686',
    'pnacl': 'pnacl'
  }
  CPU_ARCHES = {
    'arm': 'arm',
    'x86': 'amd64',
    'pnacl': 'pnacl'
  }
  VERSION_MAP = {
    'arm': '4.8.3',
    'x86': '4.4.3',
  }
  REPLACE_MAP = {
    '$NACL': NACL_ARCHES[arch],
    '$GCC': GCC_ARCHES[arch],
    '$CPU': CPU_ARCHES[arch],
    '$SUB': subarch or '',
    '$ARCH': arch,
    '$VER': VERSION_MAP[arch]
  }
  return ReplaceText(text, [REPLACE_MAP])


def Clobber(fast=False):
  if not fast:
    Rmdir(os.path.join(TOOLCHAIN_BUILD, 'cache'))
    Rmdir(os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_arm_work'))

  BUILD_DIRS = [
    'linux_%s_bionic',
    'bionic_%s_work',
  ]

  for arch in ARCHES:
    Rmdir(GetToolchainPath(arch, 'bionic'))
    for workdir in BUILD_DIRS:
      Rmdir(os.path.join(TOOLCHAIN_BUILD_OUT, workdir % arch))


def FetchAndBuild_gcc_libs():
  tc_args = ['-y', '--no-use-cached-results', '--no-use-remote-cache',
             'gcc_libs_arm']
  # Call toolchain_build to build the gcc libs. We do not need to fill in
  # any package targets since we are using toolchain_build as an
  # intermediate step.
  toolchain_main.PackageBuilder(toolchain_build.PACKAGES, {}, tc_args).Main()


def FetchBionicSources():
  project = 'bionic'
  url = '%s/nacl-%s.git' % (toolchain_build.GIT_BASE_URL, project)
  pynacl.repo_tools.SyncGitRepo(url,
                                os.path.join(TOOLCHAIN_BUILD_SRC, project),
                                BIONIC_VERSION)


def MungeIRT(src, dst):
  replace_map = {
    'off_t': 'int64_t',
    'native_client/src/untrusted/irt/' : '',
  }

  with open(src, 'r') as srcf:
    text = srcf.read()
    text = ReplaceText(text, [replace_map])
    with open(dst, 'w') as dstf:
      dstf.write(text)


def CreateBasicToolchain():
  # Create a toolchain directory containing only the toolchain binaries and
  # basic files line nacl_arm_macros.s.
  arch = 'arm'
  install_dirs = [
    'gcc_arm_x86_64_linux_install',
    'binutils_arm_x86_64_linux_install'
  ]
  for ins_path in install_dirs:
    UpdateFromTo(os.path.join(TOOLCHAIN_BUILD_OUT, ins_path),
                 GetBionicBuildPath(arch),
                 filters=['*arm-nacl/include*', '*arm-nacl/lib*','*.a', '*.o'])
    UpdateFromTo(os.path.join(TOOLCHAIN_BUILD_OUT, ins_path),
                 GetBionicBuildPath(arch),
                 paterns=['*.s'])

  #  Static build uses:
  #     crt1.o crti.o 4.8.2/crtbeginT.o ... 4.8.2/crtend.o crtn.o
  # -shared build uses:
  #     crti.o 4.8.2/crtbeginS.o ... 4.8.2/crtendS.o crtn.o crtn.o
  # However we only provide a crtbegin(S) and crtend(S)
  EMPTY = """/*
 * This is a dummy linker script.
 * libnacl.a, libcrt_common.a, crt0.o crt1.o crti.o and crtn.o are all
 * empty.  Instead all the work is done by crtbegin(S).o and crtend(S).o and
 * the bionic libc.  These are provided for compatability with the newlib
 * toolchain binaries.
 */"""
  EMPTY_FILES = ['crt0.o', 'crt1.o', 'crti.o', 'crtn.o',
                 'libnacl.a', 'libcrt_common.a', 'libpthread.a']

  # Bionic uses the following include paths
  BIONIC_PAIRS = [
    ('bionic/libc/arch-nacl/syscalls/irt_poll.h',
        '$NACL-nacl/include/irt_poll.h'),
    ('bionic/libc/arch-nacl/syscalls/irt_socket.h',
        '$NACL-nacl/include/irt_socket.h'),
    ('bionic/libc/include', '$NACL-nacl/include'),
    ('bionic/libc/arch-nacl/syscalls/nacl_socket.h',
        '$NACL-nacl/include/nacl_socket.h'),
    ('bionic/libc/arch-nacl/syscalls/nacl_stat.h',
        '$NACL-nacl/include/nacl_stat.h'),
    ('bionic/libc/arch-$ARCH/include/machine',
        '$NACL-nacl/include/machine'),
    ('bionic/libc/kernel/common', '$NACL-nacl/include'),
    ('bionic/libc/kernel/arch-$ARCH/asm', '$NACL-nacl/include/asm'),
    ('bionic/libm/include', '$NACL-nacl/include'),
    ('bionic/libm/$CPU', '$NACL-nacl/include'),
    ('bionic/safe-iop/include', '$NACL-nacl/include'),
    ('bionic/libstdc++/nacl',
        '$NACL-nacl/include/c++/$VER/$NACL-nacl'),
    ('bionic/nacl/$ARCH', '.'),
  ]


  for arch in ARCHES:
    for name in ['irt.h', 'irt_dev.h']:
      src = os.path.join(NATIVE_CLIENT, 'src', 'untrusted', 'irt', name)
      dst = GetBionicBuildPath(arch, '$NACL-nacl', 'include')
      dst = ReplaceArch(dst, arch)
      Mkdir(dst)
      MungeIRT(src, os.path.join(dst, name))

    inspath = GetBionicBuildPath(arch)

    # Create empty objects and libraries
    libpath = ReplaceArch(os.path.join(inspath, '$NACL-nacl', 'lib'), arch)
    for name in EMPTY_FILES:
      UpdateText(os.path.join(libpath, name), EMPTY)

    # Copy BIONIC files to toolchain
    for src, dst in BIONIC_PAIRS:
      srcpath = ReplaceArch(os.path.join(TOOLCHAIN_BUILD_SRC, src), arch)
      dstpath = ReplaceArch(os.path.join(inspath, dst), arch)
      UpdateFromTo(srcpath, dstpath)

    # Build specs file
    gcc = ReplaceArch(os.path.join(inspath, 'bin', '$NACL-nacl-gcc'), arch)
    lib = ReplaceArch(os.path.join(inspath, 'lib/gcc/$NACL-nacl/$VER'), arch)
    specs = os.path.join(lib, 'specs')
    with open(specs, 'w') as specfile:
      process.Run([gcc, '-dumpspecs'], cwd=None, shell=False,
                  outfile=specfile, verbose=False)
    text = open(specs, 'r').read()

    # Replace items in the spec file
    text = ReplaceText(text, [{
      '-lgcc': '-lgcc --as-needed %{!static: -lgcc_s} --no-as-needed %{!shared: -lgcc_eh}',
      '--hash-style=gnu': '--hash-style=sysv %{!static: %{!shared: -Ttext-segment=0x100000}} ',
    }])
    open(specs, 'w').write(text)


def ConfigureGCCProject(arch, project, cfg, workpath):
  # configure does not always have +x
  filepath = os.path.abspath(os.path.join(workpath, cfg[0]))
  st_info  = os.stat(filepath)
  os.chmod(filepath, st_info.st_mode | stat.S_IEXEC)

  env = os.environ
  newpath = GetBionicBuildPath(arch, 'bin')  + ':' + env['PATH']

  proj = '%s %s' % (project, arch)
  setpath = ['/usr/bin/env', 'PATH=' + newpath]

  # Check if config changed or script is new
  config_path = os.path.join(workpath, 'config.info')
  updated = UpdateText(config_path, ' '.join(cfg))
  updated |= NeedsUpdate(config_path, BUILD_SCRIPT)

  if updated:
    print 'Configure ' + proj
    if process.Run(setpath + cfg, cwd=workpath, env=env, outfile=sys.stdout):
      raise RuntimeError('Failed to configure %s.\n' % proj)
  else:
    print 'Reusing config for %s.' % proj


def MakeGCCProject(arch, project, workpath, targets=None):
  env = os.environ
  newpath = GetBionicBuildPath(arch, 'bin')  + ':' + env['PATH']
  proj = '%s %s' % (project, arch)
  setpath = ['/usr/bin/env', 'PATH=' + newpath]

  targets = targets or []
  if targets:
    proj = project = ': ' + ' '.join(targets)
  else:
    proj = project

  print 'Make ' + proj
  if process.Run(setpath + ['make', '-j16', 'V=1'] + targets,
                  cwd=workpath, outfile=sys.stdout):
    raise RuntimeError('Failed to build %s.\n' % proj)
  print 'Done ' + proj


def ConfigureAndBuild_libgcc(skip_build=False):
  arch = 'arm'
  project = 'libgcc'
  tcpath = GetBionicBuildPath(arch)

  # Prep work path
  workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_work')
  workpath = ReplaceArch(workpath, arch)

  if not skip_build:
    Mkdir(workpath)
    Symlink('../gcc_libs_arm_work/gcc' , os.path.join(workpath, 'gcc'))

  # Prep install path
  inspath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_install')
  inspath = ReplaceArch(inspath, arch)

  dstpath = ReplaceArch(os.path.join(workpath, '$NACL-nacl/libgcc'), arch)
  cfg = [
    '../../../../src/gcc_libs/libgcc/configure',
    '--host=arm-nacl',
    '--build=i686-linux',
    '--target=arm-nacl',
    '--enable-shared',
    '--enable-shared-libgcc',
    '--with-dwarf3',
    '--with-newlib',
    '--prefix=' + inspath,
    'CFLAGS=-I../../../gcc_lib_arm_work'
  ]

  if not skip_build:
    ConfigureGCCProject(arch, project, cfg, dstpath)
    MakeGCCProject(arch, project, dstpath, ['libgcc.a'])

  # Copy temp version of libgcc.a for linking libc.so
  UpdateFromTo(os.path.join(dstpath, 'libgcc.a'),
               os.path.join(tcpath, 'arm-nacl', 'lib', 'libgcc.a'))


def BuildAndInstall_libgcc_s(skip_build=False):
  arch = 'arm'
  project = 'libgcc'
  tcpath = GetBionicBuildPath(arch)

  # Remove temp copy of libgcc.a, it get's installed at the end
  os.remove(os.path.join(tcpath, 'arm-nacl', 'lib', 'libgcc.a'))

  # Prep work path
  workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_work')
  workpath = ReplaceArch(workpath, arch)
  dstpath = ReplaceArch(os.path.join(workpath, '$NACL-nacl/libgcc'), arch)

  # Prep install path
  inspath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_install')
  inspath = ReplaceArch(inspath, arch)

  if not skip_build:
    MakeGCCProject(arch, project, dstpath)
    MakeGCCProject(arch, project, dstpath, ['install'])

  UpdateFromTo(os.path.join(inspath, 'lib', 'gcc'),
               os.path.join(tcpath, 'lib', 'gcc'),
               filters=['*.o'])
  UpdateFromTo(os.path.join(inspath, 'lib', 'libgcc_s.so.1'),
               os.path.join(tcpath, 'arm-nacl', 'lib', 'libgcc_s.so.1'))
  UpdateFromTo(os.path.join(inspath, 'lib', 'libgcc_s.so'),
               os.path.join(tcpath, 'arm-nacl', 'lib', 'libgcc_s.so'))


def ConfigureAndBuild_libstdcpp(skip_build=False):
  arch = 'arm'
  project = 'libstdc++'
  tcpath = GetBionicBuildPath(arch)

  # Prep work path
  workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_work')
  workpath = ReplaceArch(workpath, arch)

  # Prep install path
  inspath = os.path.join(TOOLCHAIN_BUILD_OUT, 'gcc_$GCC_bionic_install')
  inspath = ReplaceArch(inspath, arch)

  dstpath = ReplaceArch(os.path.join(workpath, '$NACL-nacl/libstdc++-v3'), arch)
  Mkdir(dstpath)
  cfg = [
    '../../../../src/gcc_libs/libstdc++-v3/configure',
    '--host=arm-nacl',
    '--build=i686-linux',
    '--target=arm-nacl',
    '--enable-shared',
    '--with-newlib',
    '--disable-libstdcxx-pch',
    '--enable-shared-libgcc',
    '--with-dwarf3',
    '--prefix=' + inspath,
    'CFLAGS=-I../../../gcc_lib_arm_work'
  ]

  if not skip_build:
    ConfigureGCCProject(arch, project, cfg, dstpath)
    MakeGCCProject(arch, project, dstpath)
    MakeGCCProject(arch, project, dstpath, ['install'])

  # Copy libsupc++ and libstdc++ files and symlinks
  UpdateFromTo(os.path.join(inspath, 'lib'),
               os.path.join(tcpath, 'arm-nacl', 'lib'),
               paterns=['*libstdc++.*', '*libsupc++.*'])

  # Copy C++ headers
  UpdateFromTo(os.path.join(inspath, 'include'),
               os.path.join(tcpath, 'arm-nacl', 'include'))


def GetProjectPaths(arch, project):
  srcpath = os.path.join(BIONIC_SRC, project)
  workpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_work')
  instpath = os.path.join(TOOLCHAIN_BUILD_OUT, 'bionic_$ARCH_install')

  toolpath = GetBionicBuildPath(arch)
  workpath = ReplaceArch(os.path.join(workpath, 'bionic', project), arch)
  instpath = ReplaceArch(os.path.join(toolpath, '$NACL-nacl', 'lib'), arch)
  gccpath = os.path.join(toolpath, 'lib', 'gcc', '$NACL-nacl', '$VER')
  gccpath = ReplaceArch(gccpath, arch)
  out = {
    'src': srcpath,
    'work': workpath,
    'ins': instpath,
    'gcc': gccpath,
    'tc': toolpath,
  }
  return out


def CreateProject(arch, project, clobber=False):
  paths = GetProjectPaths(arch, project)

  MAKEFILE_TEMPLATE = """
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# GNU Makefile based on shared rules provided by the Native Client SDK.
# See README.Makefiles for more details.

NATIVE_CLIENT_PATH?=$(nacl_path)
TOOLCHAIN_PATH?=$(tc_path)
TOOLCHAIN_PREFIX:=$(TOOLCHAIN_PATH)/bin/$GCC-nacl-

CC:=$(TOOLCHAIN_PREFIX)gcc
CXX:=$(TOOLCHAIN_PREFIX)g++
AR:=$(TOOLCHAIN_PREFIX)ar
AS:=$(TOOLCHAIN_PREFIX)as
LD:=$(TOOLCHAIN_PREFIX)ld

SRC_ROOT=$(src_path)
DST_ROOT=$(dst_path)
INS_ROOT=$(ins_path)
GCC_ROOT=$(gcc_path)

NACL_ARCH=$NACL
GCC_ARCH=$GCC

MAKEFILE_DEPS:=$(build_tc_path)/tc_bionic.mk
MAKEFILE_DEPS+=$(src_path)/Makefile

include $(build_tc_path)/tc_bionic.mk
include $(src_path)/Makefile
"""
  remap = {
    '$(src_path)': paths['src'],
    '$(dst_path)': paths['work'],
    '$(ins_path)': paths['ins'],
    '$(tc_path)':  GetBionicBuildPath(arch),
    '$(build_tc_path)': TOOLCHAIN_BUILD,
    '$(nacl_path)': NATIVE_CLIENT,
    '$(gcc_path)': paths['gcc'],
  }
  text = ReplaceText(MAKEFILE_TEMPLATE, [remap])
  text = ReplaceArch(text, arch)

  if clobber:
    print 'Clobbering Bionic project directory: ' + paths['work']
    Rmdir(paths['work'])

  Mkdir(paths['work'])
  Mkdir(paths['ins'])
  UpdateText(os.path.join(paths['work'], 'Makefile'), text)


def ConfigureBionicProjects(clobber=False):
  PROJECTS = ['libc', 'libm', 'linker', 'tests', 'newlinker', 'newtests']
  arch = 'arm'
  for project in PROJECTS:
    print 'Configure %s for %s.' % (project, arch)
    CreateProject(arch, project, clobber)


def MakeBionicProject(project, targets=None, clobber=False):
  arch = 'arm'
  paths = GetProjectPaths(arch, project)
  workpath = paths['work']
  targets = targets or []

  targetlist = ' '.join(targets)
  print 'Building %s for %s at %s %s.' % (project, arch, workpath, targetlist)
  if clobber:
    args = ['make', '-j12', 'V=1', 'clean']
    if process.Run(args, cwd=workpath, outfile=sys.stdout):
      raise RuntimeError('Failed to clean %s for %s.\n' % (project, arch))

  args = ['make', '-j12', 'V=1'] + targets
  if process.Run(args, cwd=workpath, outfile=sys.stdout):
    raise RuntimeError('Failed to build %s for %s.\n' % (project, arch))

  print 'Done with %s for %s.\n' % (project, arch)


def ArchiveAndUpload(version, zipname, zippath, packages_file):
  sys.stdout.flush()
  print >>sys.stderr, '@@@BUILD_STEP archive_and_upload@@@'

  bucket_path = 'nativeclient-archive2/toolchain/%s' % version
  gsd_store = pynacl.gsd_storage.GSDStorage(bucket_path, [bucket_path])

  zipname = os.path.join(TOOLCHAIN_BUILD_OUT, zipname)
  try:
    os.remove(zipname)
  except:
    pass

  # Archive the zippath to the zipname.
  if process.Run(['tar', '-czf', zipname, zippath],
                 cwd=TOOLCHAIN_BUILD_OUT,
                 outfile=sys.stdout):
    raise RuntimeError('Failed to zip %s from %s.\n' % (zipname, zippath))

  # Create Zip Hash file using the hash of the zip file.
  hashzipname = zipname + '.sha1hash'
  hashval = pynacl.hashing_tools.HashFileContents(zipname)
  with open(hashzipname, 'w') as f:
    f.write(hashval)

  # Upload the Zip file.
  zipurl = gsd_store.PutFile(zipname, os.path.basename(zipname))
  sys.stdout.flush()
  print >>sys.stderr, ('@@@STEP_LINK@download (%s)@%s@@@' %
                       (os.path.basename(zipname), zipurl))

  # Upload the Zip Hash file.
  hashurl = gsd_store.PutFile(hashzipname, os.path.basename(hashzipname))
  sys.stdout.flush()
  print >>sys.stderr, ('@@@STEP_LINK@download (%s)@%s@@@' %
                       (os.path.basename(hashzipname), hashurl))

  # Create a package info file for the nacl_arm_bionic package.
  archive_desc = archive_info.ArchiveInfo(name=os.path.basename(zipname),
                                          hash=hashval,
                                          tar_src_dir='linux_arm_bionic',
                                          url=zipurl)
  package_desc = package_info.PackageInfo()
  package_desc.AppendArchive(archive_desc)

  os_name = pynacl.platform.GetOS()
  arch_name = pynacl.platform.GetArch()
  package_info_file = os.path.join(TOOLCHAIN_BUILD_OUT,
                                   'packages',
                                   '%s_%s' % (os_name, arch_name),
                                   'nacl_arm_bionic.json')
  package_desc.SavePackageFile(package_info_file)

  # If packages_file is specified, write out our packages file of 1 package.
  if packages_file:
    with open(packages_file, 'wt') as f:
      f.write(package_info_file)


def main(argv):
  parser = argparse.ArgumentParser(add_help=False)
  parser.add_argument(
      '-v', '--verbose', dest='verbose',
      default=False, action='store_true',
      help='Produce more output.')

  parser.add_argument(
      '-c', '--clobber', dest='clobber',
      default=False, action='store_true',
      help='Clobber working directories before building.')

  parser.add_argument(
      '-f', '--fast-clobber', dest='fast_clobber',
      default=False, action='store_true',
      help='Clobber bionic working directories before building.')

  parser.add_argument(
      '-s', '--sync', dest='sync',
      default=False, action='store_true',
      help='Sync sources first.')

  parser.add_argument(
      '-b', '--buildbot', dest='buildbot',
      default=False, action='store_true',
      help='Running on the buildbot.')

  parser.add_argument(
      '-l', '--llvm', dest='llvm',
      default=False, action='store_true',
      help='Enable building via llvm.')

  parser.add_argument(
      '-u', '--upload', dest='upload',
      default=False, action='store_true',
      help='Upload build artifacts.')

  parser.add_argument(
        '--packages-file', dest='packages_file',
        default=None,
        help='Output packages file describing list of package files built.')

  parser.add_argument(
      '--skip-gcc', dest='skip_gcc',
      default=False, action='store_true',
      help='Skip building GCC components (libgcc and libstdc++).')

  parser.add_argument(
      '--skip-scons', dest='skip_scons',
      default=False, action='store_true',
      help='Skip building scons components (sel_ldr, irt).')

  options, leftover_args = parser.parse_known_args(argv)
  if '-h' in leftover_args or '--help' in leftover_args:
    print 'The following arguments are specific to toolchain_build_bionic.py:'
    parser.print_help()
    print 'The rest of the arguments are generic, in toolchain_main.py'
    return 1

  pynacl.log_tools.SetupLogging(options.verbose)

  if options.llvm:
    ARCHES.append('pnacl')

  if options.buildbot or options.upload:
    version = os.environ['BUILDBOT_REVISION']

  if options.clobber or options.fast_clobber:
    Clobber(fast=options.fast_clobber)

  if options.sync or options.buildbot:
    FetchBionicSources()

  if not options.skip_gcc:
    # Build newlib gcc_libs for use by bionic
    FetchAndBuild_gcc_libs()

  # Copy headers and compiler tools
  CreateBasicToolchain()

  # Configure and build libgcc.a
  ConfigureAndBuild_libgcc(skip_build=options.skip_gcc)

  # Configure Bionic Projects, libc, libm, linker, tests, ...
  ConfigureBionicProjects(clobber=options.buildbot)

  # Build and install IRT header before building GCC
  MakeBionicProject('libc', ['irt'])

  # With libgcc.a, we can now build libc.so
  MakeBionicProject('libc')

  # With libc.so, we can build libgcc_s.so
  BuildAndInstall_libgcc_s(skip_build=options.skip_gcc)

  # With libc and libgcc_s, we can now build libm
  MakeBionicProject('libm')

  # With libc, libgcc, and libm, we can now build libstdc++
  ConfigureAndBuild_libstdcpp(skip_build=options.skip_gcc)

  # Now we can build the linker
  #MakeBionicProject('linker')
  MakeBionicProject('newlinker')

  # Now we have a full toolchain, so test it
  #MakeBionicProject('tests')
  MakeBionicProject('newtests')

  # We can run only off buildbots
  if not options.buildbot and not options.skip_scons:
    process.Run(['./scons', 'platform=arm', '--mode=nacl,dbg-linux', '-j20'],
                cwd=NATIVE_CLIENT)
  if not options.buildbot:
    MakeBionicProject('tests', ['run'])
    MakeBionicProject('newtests', ['run'])

  dst = os.path.join(TOOLCHAIN_BUILD_OUT, 'linux_arm_bionic', 'log.txt')
  with open(dst, 'w') as dstf:
    process.Run(['git', 'log', '-n', '1'],
                cwd=os.path.join(TOOLCHAIN_BUILD_SRC, 'bionic'),
                outfile=dstf,
                verbose=False)

  if options.buildbot or options.upload:
    zipname = 'naclsdk_linux_arm_bionic.tgz'
    ArchiveAndUpload(version, zipname, 'linux_arm_bionic',
                     options.packages_file)


if __name__ == '__main__':
  sys.exit(main(sys.argv))
  