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

from optparse import OptionParser
import os
import subprocess
import sys


"""NEXE building script

This module will take a set of source files, include paths, library paths, and
additional arguments, and use them to build.
"""


def ErrOut(text):
  """ErrOut prints an error message and the command-line that caused it.

  Prints to standard err, both the command-line normally, and separated by
  >>...<< to make it easier to copy and paste the command, or to
  find command formating issues.
  """
  sys.stderr.write('\n\n')
  sys.stderr.write( '>>>' + '>> <<'.join(sys.argv) + '<<\n\n')
  sys.stderr.write(' '.join(sys.argv) + '<<\n\n')
  sys.stderr.write(text + '\n')
  sys.exit(1)


def MakeDir(outdir):
  if outdir and not os.path.exists(outdir):
    # There may be a race creating this directory, so ignore failure
    try:
      os.makedirs(outdir)
    except OSError:
      pass


def RemoveQuotes(opt):
  if opt and opt[0] == '"':
    return opt[1:-1]
  return opt


def ArgToList(opt):
  outlist = []
  optlist = RemoveQuotes(opt).split(' ')
  for optitem in optlist:
    optitem = RemoveQuotes(optitem).replace('\\"', '"')
    if optitem:
      outlist.append(optitem)
  return outlist


class Builder(object):
  """Builder object maintains options and generates build command-lines.

  The Builder object takes a set of script command-line options, and generates
  a set of paths, and command-line options for the NaCl toolchain.
  """
  def __init__(self, options):
    arch = options.arch
    build_type = options.build.split('_')
    toolname = build_type[0]
    self.outtype = build_type[1]

    if sys.platform.startswith('linux'):
      self.osname = 'linux'
    elif sys.platform.startswith('win'):
      self.osname = 'win'
    elif sys.platform.startswith('darwin'):
      self.osname = 'mac'
    else:
      ErrOut('Toolchain OS %s not supported.' % sys.platform)

    if arch  in ['x86-32', 'x86-64']:
      self.arch = arch
      self.mainarch = 'x86'
      self.subarch = arch.split('-')[1]
      tool_subdir = 'x86_64-nacl'
      self.pnacl = False
    elif arch == 'arm':
      self.arch = arch
      self.mainarch = 'arm'
      self.subarch = ''
      self.pnacl = True
    else:
      ErrOut('Toolchain architecture %s not supported.' % arch)

    if arch == 'arm' and toolname == 'glibc':
      ErrOut('arm/glibc not yet supported.')

    if toolname == 'newlib':
      toolchain = '%s_%s_newlib' % (self.osname, self.mainarch)
      self.toolname = 'newlib'
    elif toolname == 'glibc':
      toolchain = '%s_%s' % (self.osname, self.mainarch)
      self.toolname = 'glibc'
    else:
      ErrOut('Toolchain of type %s not supported.' % toolname)

    self.root_path = options.root
    self.nacl_path = os.path.join(self.root_path, 'native_client')

    project_path, project_name = os.path.split(options.name)
    self.outdir = options.objdir

    # Set the toolchain directories
    if self.pnacl:
      pnacldir = 'pnacl_%s_x86_64' % self.osname
      self.toolchain = self.GenNaClPath(os.path.join('toolchain',
                                                     pnacldir,
                                                     self.toolname))
      self.toolbin = os.path.join(self.toolchain, 'bin')
      self.toollib = os.path.join(self.toolchain, 'lib')
      self.toolinc = os.path.join(self.toolchain, 'sysroot', 'include')
    else:
      self.toolchain = self.GenNaClPath(os.path.join('toolchain',
                                                     toolchain))
      self.toolbin = os.path.join(self.toolchain, tool_subdir, 'bin')
      self.toollib = os.path.join(self.toolchain,
                                  tool_subdir,
                                  'lib' + self.subarch)
      self.toolinc = os.path.join(self.toolchain, tool_subdir, 'include')

    self.inc_paths = ArgToList(options.incdirs)
    self.lib_paths = ArgToList(options.libdirs)
    self.define_list = ArgToList(options.defines)

    self.name = options.name
    self.BuildCompileOptions(options.compile_flags, self.define_list)
    self.BuildLinkOptions(options.link_flags)
    self.BuildArchiveOptions()
    self.verbose = options.verbose
    self.suffix = options.suffix
    self.strip = options.strip
    self.empty = options.empty
    self.strip_debug = options.strip_debug

    if self.verbose:
      print 'Compile options: %s' % self.compile_options
      print 'Linker options: %s' % self.link_options

  def GenNaClPath(self, path):
    """Helper which prepends path with the native client source directory."""
    return os.path.join(self.root_path, 'native_client', path)

  def GetBinName(self, name):
    """Helper which prepends executable with the toolchain bin directory."""
    return os.path.join(self.toolbin, name)

  def GetCCompiler(self):
    """Helper which returns C compiler path."""
    if self.pnacl:
      return self.GetBinName('pnacl-clang')
    else:
      return self.GetBinName('gcc')

  def GetCXXCompiler(self):
    """Helper which returns C++ compiler path."""
    if self.pnacl:
      return self.GetBinName('pnacl-clang++')
    else:
      return self.GetBinName('g++')

  def GetAr(self):
    """Helper which returns ar path."""
    if self.pnacl:
      return self.GetBinName('pnacl-ar')
    else:
      return self.GetBinName('ar')

  def GetStrip(self):
    """Helper which returns strip path."""
    if self.pnacl:
      return self.GetBinName('pnacl-strip')
    else:
      return self.GetBinName('strip')

  def BuildAssembleOptions(self, options):
    options = ArgToList(options)
    self.assemble_options = options + ['-I' + name for name in self.inc_paths]

  def BuildCompileOptions(self, options, define_list):
    """Generates compile options, called once by __init__."""
    options = ArgToList(options)
    # We want to shared gyp 'defines' with other targets, but not
    # ones that are host system dependent. Filtering them out.
    # This really should be better.
    # See: http://code.google.com/p/nativeclient/issues/detail?id=2936
    define_list = [define for define in define_list
                   if not (define.startswith('NACL_TARGET_ARCH=') or
                           define.startswith('NACL_TARGET_SUBARCH=') or
                           define.startswith('NACL_WINDOWS=') or
                           define.startswith('NACL_OSX=') or
                           define.startswith('NACL_LINUX=') or
                           define == 'COMPONENT_BUILD' or
                           'WIN32' in define or
                           'WINDOWS' in define or
                           'WINVER' in define)]
    options += ['-D' + define for define in define_list]
    self.compile_options = options + ['-I' + name for name in self.inc_paths]

  def BuildLinkOptions(self, options):
    """Generates link options, called once by __init__."""
    options = ArgToList(options)
    if self.toolname in ['glibc', 'newlib'] and self.mainarch == 'x86':
      options += ['-B' + self.toollib]
    self.link_options = options + ['-L' + name for name in self.lib_paths]

  def BuildArchiveOptions(self):
    """Generates link options, called once by __init__."""
    self.archive_options = []

  def Run(self, cmd_line, out):
    """Helper which runs a command line."""

    # For POSIX style path on windows for POSIX based toolchain
    cmd_line = [cmd.replace('\\', '/') for cmd in cmd_line]

    if self.verbose:
      print ' '.join(cmd_line)
    try:
      ecode = subprocess.call(cmd_line)
    except Exception, err:
      ErrOut('\n%s\nFAILED: %s\n\n' % (' '.join(cmd_line), str(err)))
    if ecode != 0:
      print 'Err %d: nacl-%s %s' % (ecode, os.path.basename(cmd_line[0]), out)
      print '>>%s<<' % '<< >>'.join(cmd_line)
    return ecode

  def GetObjectName(self, src):
    if self.strip:
      src = src.replace(self.strip,'')
    filepath, filename = os.path.split(src)
    filename, ext = os.path.splitext(filename)
    if self.suffix:
      return os.path.join(self.outdir, filename + '.o')
    else:
      filename = os.path.split(src)[1]
      return os.path.join(self.outdir, os.path.splitext(filename)[0] + '.o')

  def CleanOutput(self, out):
    if os.path.isfile(out):
      os.remove(out)

  def Compile(self, src):
    """Compile the source with pre-determined options."""

    filename, ext = os.path.splitext(src)
    if ext in ['.c', '.S']:
      bin_name = self.GetCCompiler()
      extra = ['-std=gnu99']
      if self.pnacl and ext == '.S':
        extra.append('-arch')
        extra.append(self.arch)
    elif ext in ['.cc', '.cpp']:
      bin_name = self.GetCXXCompiler()
      extra = []
    else:
      if self.verbose and ext != '.h':
        print 'Skipping unknown type %s for %s.' % (ext, src)
      return None

    if self.verbose:
      print '\nCompile %s' % src

    out = self.GetObjectName(src)
    MakeDir(os.path.dirname(out))
    self.CleanOutput(out)
    cmd_line = [bin_name, '-c', src, '-o', out] + extra + self.compile_options
    err = self.Run(cmd_line, out)
    if sys.platform.startswith('win') and err == 5:
      # Try again on mystery windows failure.
      err = self.Run(cmd_line, out)
    if err:
      ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line)))
    return out

  def Link(self, srcs):
    """Link these objects with predetermined options and output name."""
    out = self.name
    if self.verbose:
      print '\nLink %s' % out
    bin_name = self.GetCXXCompiler()
    MakeDir(os.path.dirname(out))
    self.CleanOutput(out)

    cmd_line = [bin_name, '-o', out, '-Wl,--as-needed']
    if not self.empty:
      cmd_line += srcs
    cmd_line += self.link_options

    err = self.Run(cmd_line, out)
    # TODO( Retry on windows
    if sys.platform.startswith('win') and err == 5:
      # Try again on mystery windows failure.
      err = self.Run(cmd_line, out)
    if err:
      ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line)))
    return out

  def Archive(self, srcs):
    """Archive these objects with predetermined options and output name."""
    out = self.name
    if self.verbose:
      print '\nArchive %s' % out


    if '-r' in self.link_options:
      bin_name = self.GetCXXCompiler()
      cmd_line = [bin_name, '-o', out, '-Wl,--as-needed']
      if not self.empty:
        cmd_line += srcs
      cmd_line += self.link_options
    else:
      bin_name = self.GetAr()
      cmd_line = [bin_name, '-rc', out]
      if not self.empty:
        cmd_line += srcs

    MakeDir(os.path.dirname(out))
    self.CleanOutput(out)
    err = self.Run(cmd_line, out)
    if sys.platform.startswith('win') and err == 5:
      # Try again on mystery windows failure.
      err = self.Run(cmd_line, out)
    if err:
      ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line)))
    return out

  def Strip(self, out):
    """Strip the NEXE"""
    if self.verbose:
      print '\nStrip %s' % out

    tmp = out + '.tmp'
    self.CleanOutput(tmp)
    os.rename(out, tmp)
    bin_name = self.GetStrip()
    cmd_line = [bin_name, '--strip-debug', tmp, '-o', out]
    err = self.Run(cmd_line, out)
    if sys.platform.startswith('win') and err == 5:
      # Try again on mystery windows failure.
      err = self.Run(cmd_line, out)
    if err:
      ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line)))
    return out

  def Generate(self, srcs):
    """Generate final output file.

    Link or Archive the final output file, from the compiled sources.
    """
    if self.outtype == 'nexe':
      out = self.Link(srcs)
      if self.strip_debug:
        self.Strip(out)
    elif self.outtype == 'nlib':
      self.Archive(srcs)


def Main(argv):
  parser = OptionParser()
  parser.add_option('--empty', dest='empty', default=False,
                    help='Do not pass sources to library.', action='store_true')
  parser.add_option('--no-suffix', dest='suffix', default=True,
                    help='Do not append arch suffix.', action='store_false')
  parser.add_option('--sufix', dest='suffix',
                    help='Do append arch suffix.', action='store_true')
  parser.add_option('--strip-debug', dest='strip_debug', default=False,
                    help='Strip the NEXE', action='store_true')
  parser.add_option('--strip', dest='strip', default='',
                    help='Strip the filename')
  parser.add_option('--source-list', dest='source_list',
                    help='Filename to load a source list from')
  parser.add_option('-a', '--arch', dest='arch',
                    help='Set target architecture')
  parser.add_option('-c', '--compile', dest='compile_only', default=False,
                    help='Compile only.', action='store_true')
  parser.add_option('-i', '--include-dirs', dest='incdirs',
                    help='Set include directories.')
  parser.add_option('-l', '--lib-dirs', dest='libdirs',
                    help='Set library directories.')
  parser.add_option('-n', '--name', dest='name',
                    help='Base path and name of the nexe.')
  parser.add_option('-o', '--objdir', dest='objdir',
                    help='Base path of the object output dir.')
  parser.add_option('-r', '--root', dest='root',
                    help='Set the root directory of the sources')
  parser.add_option('-b', '--build', dest='build',
                    help='Set build type (newlib, glibc).')
  parser.add_option('--compile_flags', dest='compile_flags',
                    help='Set compile flags.')
  parser.add_option('--defines', dest='defines',
                    help='Set defines')
  parser.add_option('--link_flags', dest='link_flags',
                    help='Set link flags.')
  parser.add_option('-v', '--verbose', dest='verbose', default=False,
                    help='Enable verbosity', action='store_true')
  (options, files) = parser.parse_args(argv[1:])

  if not argv:
    parser.print_help()
    return 1

  if options.source_list:
    source_list_handle = open(options.source_list, 'r')
    source_list = source_list_handle.read().splitlines()
    source_list_handle.close()
    files = files + source_list

  build = Builder(options)
  objs = []
  for filename in files:
    out = build.Compile(filename)
    if out:
      objs.append(out)
  # Do not link if building an object
  if not options.compile_only:
    build.Generate(objs)
  return 0

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