# Copyright 2015, VIXL authors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions and the following disclaimer in the documentation
#     and/or other materials provided with the distribution.
#   * Neither the name of ARM Limited nor the names of its contributors may be
#     used to endorse or promote products derived from this software without
#     specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import glob
import itertools
import os
from os.path import join
import platform
import subprocess
import sys
from collections import OrderedDict

root_dir = os.path.dirname(File('SConstruct').rfile().abspath)
sys.path.insert(0, join(root_dir, 'tools'))
import config
import util

from SCons.Errors import UserError


Help('''
Build system for the VIXL project.
See README.md for documentation and details about the build system.
''')


# We track top-level targets to automatically generate help and alias them.
class VIXLTargets:
  def __init__(self):
    self.targets = []
    self.help_messages = []
  def Add(self, target, help_message):
    self.targets.append(target)
    self.help_messages.append(help_message)
  def Help(self):
    res = ""
    for i in range(len(self.targets)):
      res += '\t{0:<{1}}{2:<{3}}\n'.format(
        'scons ' + self.targets[i],
        len('scons ') + max(map(len, self.targets)),
        ' : ' + self.help_messages[i],
        len(' : ') + max(map(len, self.help_messages)))
    return res

top_level_targets = VIXLTargets()



# Build options ----------------------------------------------------------------

# Store all the options in a dictionary.
# The SConstruct will check the build variables and construct the build
# environment as appropriate.
options = {
    'all' : { # Unconditionally processed.
      'CCFLAGS' : ['-Wall',
                   '-Werror',
                   '-fdiagnostics-show-option',
                   '-Wextra',
                   '-Wredundant-decls',
                   '-pedantic',
                   '-Wwrite-strings',
                   '-Wunused'],
      'CPPPATH' : [config.dir_src_vixl]
      },
#   'build_option:value' : {
#     'environment_key' : 'values to append'
#     },
    'mode:debug' : {
      'CCFLAGS' : ['-DVIXL_DEBUG', '-O0']
      },
    'mode:release' : {
      'CCFLAGS' : ['-O3'],
      },
    'simulator:aarch64' : {
      'CCFLAGS' : ['-DVIXL_INCLUDE_SIMULATOR_AARCH64'],
      },
    'symbols:on' : {
      'CCFLAGS' : ['-g'],
      'LINKFLAGS' : ['-g']
      },
    'negative_testing:on' : {
      'CCFLAGS' : ['-DVIXL_NEGATIVE_TESTING']
      },
    'code_buffer_allocator:mmap' : {
      'CCFLAGS' : ['-DVIXL_CODE_BUFFER_MMAP']
      },
    'code_buffer_allocator:malloc' : {
      'CCFLAGS' : ['-DVIXL_CODE_BUFFER_MALLOC']
      },
    'ubsan:on' : {
      'CCFLAGS': ['-fsanitize=undefined'],
      'LINKFLAGS': ['-fsanitize=undefined']
      }
    }


# A `DefaultVariable` has a default value that depends on elements not known
# when variables are first evaluated.
# Each `DefaultVariable` has a handler that will compute the default value for
# the given environment.
def modifiable_flags_handler(env):
  env['modifiable_flags'] = \
      'on' if 'mode' in env and env['mode'] == 'debug' else 'off'


def symbols_handler(env):
  env['symbols'] = 'on' if 'mode' in env and env['mode'] == 'debug' else 'off'

def Is32BitHost(env):
  return env['host_arch'] in ['aarch32', 'i386']

def IsAArch64Host(env):
  return env['host_arch'] == 'aarch64'

def CanTargetA32(env):
  return 'a32' in env['target']

def CanTargetT32(env):
  return 't32' in env['target']

def CanTargetAArch32(env):
  return CanTargetA32(env) or CanTargetT32(env)

def CanTargetA64(env):
  return 'a64' in env['target']

def CanTargetAArch64(env):
  return CanTargetA64(env)


# By default, include the simulator only if AArch64 is targeted and we are not
# building VIXL natively for AArch64.
def simulator_handler(env):
  if not IsAArch64Host(env) and CanTargetAArch64(env):
    env['simulator'] = 'aarch64'
  else:
    env['simulator'] = 'none'


# 'mmap' is required for use with 'mprotect', which is needed for the tests
# (when running natively), so we use it by default where we can.
def code_buffer_allocator_handler(env):
  directives = util.GetCompilerDirectives(env)
  if '__linux__' in directives:
    env['code_buffer_allocator'] = 'mmap'
  else:
    env['code_buffer_allocator'] = 'malloc'

# A validator checks the consistency of provided options against the environment.
def default_validator(env):
  pass


def simulator_validator(env):
  if env['simulator'] == 'aarch64' and not CanTargetAArch64(env):
    raise UserError('Building an AArch64 simulator implies that VIXL targets '
                    'AArch64. Set `target` to include `aarch64` or `a64`.')


# Default variables may depend on each other, therefore we need this dictionnary
# to be ordered.
vars_default_handlers = OrderedDict({
    # variable_name    : [ 'default val', 'handler', 'validator']
    'symbols'          : [ 'mode==debug', symbols_handler, default_validator ],
    'modifiable_flags' : [ 'mode==debug', modifiable_flags_handler, default_validator],
    'simulator'        : [ 'on if the target architectures include AArch64 but '
                           'the host is not AArch64, else off',
                           simulator_handler, simulator_validator ],
    'code_buffer_allocator' : [ 'mmap with __linux__, malloc otherwise',
                                code_buffer_allocator_handler, default_validator ]
    })


def DefaultVariable(name, help, allowed_values):
  help = '%s (%s)' % (help, '|'.join(allowed_values))
  default_value = vars_default_handlers[name][0]
  def validator(name, value, env):
    if value != default_value and value not in allowed_values:
        raise UserError('Invalid value for option {name}: {value}.  '
                        'Valid values are: {allowed_values}'.format(
                            name, value, allowed_values))
  return (name, help, default_value, validator)


def AliasedListVariable(name, help, default_value, allowed_values, aliasing):
  help = '%s (all|auto|comma-separated list) (any combination from [%s])' % \
         (help, ', '.join(allowed_values))

  def validator(name, value, env):
    # Here list has been converted to space separated strings.
    if value == '': return  # auto
    for v in value.split():
      if v not in allowed_values:
        raise UserError('Invalid value for %s: %s' % (name, value))

  def converter(value):
    if value == 'auto': return []
    if value == 'all':
      translated = [aliasing[v] for v in allowed_values]
      return list(set(itertools.chain.from_iterable(translated)))
    # The validator is run later hence the get.
    translated = [aliasing.get(v, v) for v in value.split(',')]
    return list(set(itertools.chain.from_iterable(translated)))

  return (name, help, default_value, validator, converter)


vars = Variables()
# Define command line build options.
vars.AddVariables(
    AliasedListVariable('target', 'Target ISA/Architecture', 'auto',
                        ['aarch32', 'a32', 't32', 'aarch64', 'a64'],
                        {'aarch32' : ['a32', 't32'],
                         'a32' : ['a32'], 't32' : ['t32'],
                         'aarch64' : ['a64'], 'a64' : ['a64']}),
    EnumVariable('mode', 'Build mode',
                 'release', allowed_values=config.build_options_modes),
    EnumVariable('ubsan', 'Enable undefined behavior checks',
                 'off', allowed_values=['on', 'off']),
    EnumVariable('negative_testing',
                  'Enable negative testing (needs exceptions)',
                 'off', allowed_values=['on', 'off']),
    DefaultVariable('symbols', 'Include debugging symbols in the binaries',
                    ['on', 'off']),
    DefaultVariable('simulator', 'Simulators to include', ['aarch64', 'none']),
    DefaultVariable('code_buffer_allocator',
                    'Configure the allocation mechanism in the CodeBuffer',
                    ['malloc', 'mmap']),
    ('std', 'C++ standard. The standards tested are: %s.' % \
                                         ', '.join(config.tested_cpp_standards))
    )

# We use 'variant directories' to avoid recompiling multiple times when build
# options are changed, different build paths are used depending on the options
# set. These are the options that should be reflected in the build directory
# path.
options_influencing_build_path = [
  'target', 'mode', 'symbols', 'CXX', 'std', 'simulator', 'negative_testing',
  'code_buffer_allocator'
]



# Build helpers ----------------------------------------------------------------

def RetrieveEnvironmentVariables(env):
  for key in ['CC', 'CXX', 'AR', 'RANLIB', 'LD']:
    if os.getenv(key): env[key] = os.getenv(key)
  if os.getenv('LD_LIBRARY_PATH'): env['LIBPATH'] = os.getenv('LD_LIBRARY_PATH')
  if os.getenv('CCFLAGS'):
    env.Append(CCFLAGS = os.getenv('CCFLAGS').split())
  if os.getenv('CXXFLAGS'):
    env.Append(CXXFLAGS = os.getenv('CXXFLAGS').split())
  if os.getenv('LINKFLAGS'):
    env.Append(LINKFLAGS = os.getenv('LINKFLAGS').split())
  # This allows colors to be displayed when using with clang.
  env['ENV']['TERM'] = os.getenv('TERM')


# The architecture targeted by default will depend on the compiler being
# used. 'host_arch' is extracted from the compiler while 'target' can be
# set by the user.
# By default, we target both AArch32 and AArch64 unless the compiler targets a
# 32-bit architecture. At the moment, we cannot build VIXL's AArch64 support on
# a 32-bit platform.
# TODO: Port VIXL to build on a 32-bit platform.
def target_handler(env):
  # Auto detect
  if Is32BitHost(env):
    # We use list(set(...)) to keep the same order as if it was specify as
    # an option.
    env['target'] = list(set(['a32', 't32']))
  else:
    env['target'] = list(set(['a64', 'a32', 't32']))


def target_validator(env):
  # TODO: Port VIXL64 to work on a 32-bit platform.
  if Is32BitHost(env) and CanTargetAArch64(env):
    raise UserError('Building VIXL for AArch64 in 32-bit is not supported. Set '
                    '`target` to `aarch32`')


# The target option is handled differently from the rest.
def ProcessTargetOption(env):
  if env['target'] == []: target_handler(env)

  if 'a32' in env['target']: env['CCFLAGS'] += ['-DVIXL_INCLUDE_TARGET_A32']
  if 't32' in env['target']: env['CCFLAGS'] += ['-DVIXL_INCLUDE_TARGET_T32']
  if 'a64' in env['target']: env['CCFLAGS'] += ['-DVIXL_INCLUDE_TARGET_A64']

  target_validator(env)


def ProcessBuildOptions(env):
  # 'all' is unconditionally processed.
  if 'all' in options:
    for var in options['all']:
      if var in env and env[var]:
        env[var] += options['all'][var]
      else:
        env[var] = options['all'][var]

  # The target option *must* be processed before the options defined in
  # vars_default_handlers.
  ProcessTargetOption(env)

  # Other build options must match 'option:value'
  env_dict = env.Dictionary()

  # First apply the default variables handlers in order.
  for key, value in vars_default_handlers.items():
    default = value[0]
    handler = value[1]
    if env_dict.get(key) == default:
      handler(env_dict)

  # Second, run the series of validators, to check for errors.
  for _, value in vars_default_handlers.items():
    validator = value[2]
    validator(env)

  for key in env_dict.keys():
    # Then update the environment according to the value of the variable.
    key_val_couple = key + ':%s' % env_dict[key]
    if key_val_couple in options:
      for var in options[key_val_couple]:
        env[var] += options[key_val_couple][var]


def ConfigureEnvironmentForCompiler(env):
  if CanTargetA32(env) and CanTargetT32(env):
    # When building for only one aarch32 isa, fixing the no-return is not worth
    # the effort.
    env.Append(CPPFLAGS = ['-Wmissing-noreturn'])

  compiler = util.CompilerInformation(env)
  if compiler == 'clang':
    # These warnings only work for Clang.
    # -Wimplicit-fallthrough only works when compiling the code base as C++11 or
    # newer. The compiler does not complain if the option is passed when
    # compiling earlier C++ standards.
    env.Append(CPPFLAGS = ['-Wimplicit-fallthrough', '-Wshorten-64-to-32'])

    # The '-Wunreachable-code' flag breaks builds for clang 3.4.
    if compiler != 'clang-3.4':
      env.Append(CPPFLAGS = ['-Wunreachable-code'])

    if env['ubsan'] == 'on':
      env.Append(LINKFLAGS = ['-fuse-ld=lld'])

  # GCC 4.8 has a bug which produces a warning saying that an anonymous Operand
  # object might be used uninitialized:
  #   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57045
  # The bug does not seem to appear in GCC 4.7, or in debug builds with GCC 4.8.
  if env['mode'] == 'release':
    if compiler == 'gcc-4.8':
      env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized'])

  # GCC 6 and higher is able to detect throwing from inside a destructor and
  # reports a warning. However, if negative testing is enabled then assertions
  # will throw exceptions.
  if env['negative_testing'] == 'on' and env['mode'] == 'debug' \
      and compiler >= 'gcc-6':
    env.Append(CPPFLAGS = ['-Wno-terminate'])
    # The C++11 compatibility warning will also be triggered for this case, as
    # the behavior of throwing from desctructors has changed.
    if 'std' in env and env['std'] == 'c++98':
      env.Append(CPPFLAGS = ['-Wno-c++11-compat'])

  # When compiling with c++98 (the default), allow long long constants.
  if 'std' not in env or env['std'] == 'c++98':
    env.Append(CPPFLAGS = ['-Wno-long-long'])
    env.Append(CPPFLAGS = ['-Wno-variadic-macros'])
  # When compiling with c++11, suggest missing override keywords on methods.
  if 'std' in env and env['std'] in ['c++11', 'c++14']:
    if compiler >= 'gcc-5':
      env.Append(CPPFLAGS = ['-Wsuggest-override'])
    elif compiler >= 'clang-3.6':
      env.Append(CPPFLAGS = ['-Winconsistent-missing-override'])


def ConfigureEnvironment(env):
  RetrieveEnvironmentVariables(env)
  env['host_arch'] = util.GetHostArch(env)
  ProcessBuildOptions(env)
  if 'std' in env:
    env.Append(CPPFLAGS = ['-std=' + env['std']])
    std_path = env['std']
  ConfigureEnvironmentForCompiler(env)


def TargetBuildDir(env):
  # Build-time option values are embedded in the build path to avoid requiring a
  # full build when an option changes.
  build_dir = config.dir_build
  for option in options_influencing_build_path:
    option_value = ''.join(env[option]) if option in env else ''
    build_dir = join(build_dir, option + '_'+ option_value)
  return build_dir


def PrepareVariantDir(location, build_dir):
  location_build_dir = join(build_dir, location)
  VariantDir(location_build_dir, location)
  return location_build_dir


def VIXLLibraryTarget(env):
  build_dir = TargetBuildDir(env)
  # Create a link to the latest build directory.
  # Use `-r` to avoid failure when `latest` exists and is a directory.
  subprocess.check_call(["rm", "-rf", config.dir_build_latest])
  util.ensure_dir(build_dir)
  subprocess.check_call(["ln", "-s", build_dir, config.dir_build_latest])
  # Source files are in `src` and in `src/aarch64/`.
  variant_dir_vixl = PrepareVariantDir(join('src'), build_dir)
  sources = [Glob(join(variant_dir_vixl, '*.cc'))]
  if CanTargetAArch32(env):
    variant_dir_aarch32 = PrepareVariantDir(join('src', 'aarch32'), build_dir)
    sources.append(Glob(join(variant_dir_aarch32, '*.cc')))
  if CanTargetAArch64(env):
    variant_dir_aarch64 = PrepareVariantDir(join('src', 'aarch64'), build_dir)
    sources.append(Glob(join(variant_dir_aarch64, '*.cc')))
  return env.Library(join(build_dir, 'vixl'), sources)



# Build ------------------------------------------------------------------------

# The VIXL library, built by default.
env = Environment(variables = vars,
                  BUILDERS = {
                      'Markdown': Builder(action = 'markdown $SOURCE > $TARGET',
                                          suffix = '.html')
                  })
# Abort the build if any command line option is unknown or invalid.
unknown_build_options = vars.UnknownVariables()
if unknown_build_options:
  print 'Unknown build options:',  unknown_build_options.keys()
  Exit(1)

ConfigureEnvironment(env)
Help(vars.GenerateHelpText(env))
libvixl = VIXLLibraryTarget(env)
Default(libvixl)
env.Alias('libvixl', libvixl)
top_level_targets.Add('', 'Build the VIXL library.')


# Common test code.
test_build_dir = PrepareVariantDir('test', TargetBuildDir(env))
test_objects = [env.Object(Glob(join(test_build_dir, '*.cc')))]

# AArch32 support
if CanTargetAArch32(env):
  # The examples.
  aarch32_example_names = util.ListCCFilesWithoutExt(config.dir_aarch32_examples)
  aarch32_examples_build_dir = PrepareVariantDir('examples/aarch32', TargetBuildDir(env))
  aarch32_example_targets = []
  for example in aarch32_example_names:
    prog = env.Program(join(aarch32_examples_build_dir, example),
                       join(aarch32_examples_build_dir, example + '.cc'),
                       LIBS=[libvixl])
    aarch32_example_targets.append(prog)
  env.Alias('aarch32_examples', aarch32_example_targets)
  top_level_targets.Add('aarch32_examples', 'Build the examples for AArch32.')

  # The benchmarks
  aarch32_benchmark_names = util.ListCCFilesWithoutExt(config.dir_aarch32_benchmarks)
  aarch32_benchmarks_build_dir = PrepareVariantDir('benchmarks/aarch32', TargetBuildDir(env))
  aarch32_benchmark_targets = []
  for bench in aarch32_benchmark_names:
    prog = env.Program(join(aarch32_benchmarks_build_dir, bench),
                       join(aarch32_benchmarks_build_dir, bench + '.cc'),
                       LIBS=[libvixl])
    aarch32_benchmark_targets.append(prog)
  env.Alias('aarch32_benchmarks', aarch32_benchmark_targets)
  top_level_targets.Add('aarch32_benchmarks', 'Build the benchmarks for AArch32.')

  # The tests.
  test_aarch32_build_dir = PrepareVariantDir(join('test', 'aarch32'), TargetBuildDir(env))
  test_objects.append(env.Object(
      Glob(join(test_aarch32_build_dir, '*.cc')),
      CPPPATH = env['CPPPATH'] + [config.dir_tests]))

# AArch64 support
if CanTargetAArch64(env):
  # The benchmarks.
  aarch64_benchmark_names = util.ListCCFilesWithoutExt(config.dir_aarch64_benchmarks)
  aarch64_benchmarks_build_dir = PrepareVariantDir('benchmarks/aarch64', TargetBuildDir(env))
  aarch64_benchmark_targets = []
  for bench in aarch64_benchmark_names:
    prog = env.Program(join(aarch64_benchmarks_build_dir, bench),
                       join(aarch64_benchmarks_build_dir, bench + '.cc'),
                       LIBS=[libvixl])
    aarch64_benchmark_targets.append(prog)
  env.Alias('aarch64_benchmarks', aarch64_benchmark_targets)
  top_level_targets.Add('aarch64_benchmarks', 'Build the benchmarks for AArch64.')

  # The examples.
  aarch64_example_names = util.ListCCFilesWithoutExt(config.dir_aarch64_examples)
  aarch64_examples_build_dir = PrepareVariantDir('examples/aarch64', TargetBuildDir(env))
  aarch64_example_targets = []
  for example in aarch64_example_names:
    prog = env.Program(join(aarch64_examples_build_dir, example),
                       join(aarch64_examples_build_dir, example + '.cc'),
                       LIBS=[libvixl])
    aarch64_example_targets.append(prog)
  env.Alias('aarch64_examples', aarch64_example_targets)
  top_level_targets.Add('aarch64_examples', 'Build the examples for AArch64.')

  # The tests.
  test_aarch64_build_dir = PrepareVariantDir(join('test', 'aarch64'), TargetBuildDir(env))
  test_objects.append(env.Object(
      Glob(join(test_aarch64_build_dir, '*.cc')),
      CPPPATH = env['CPPPATH'] + [config.dir_tests]))

  # The test requires building the example files with specific options, so we
  # create a separate variant dir for the example objects built this way.
  test_aarch64_examples_vdir = join(TargetBuildDir(env), 'test', 'aarch64', 'test_examples')
  VariantDir(test_aarch64_examples_vdir, '.')
  test_aarch64_examples_obj = env.Object(
      [Glob(join(test_aarch64_examples_vdir, join('test', 'aarch64', 'examples', '*.cc'))),
       Glob(join(test_aarch64_examples_vdir, join('examples/aarch64', '*.cc')))],
      CCFLAGS = env['CCFLAGS'] + ['-DTEST_EXAMPLES'],
      CPPPATH = env['CPPPATH'] + [config.dir_aarch64_examples] + [config.dir_tests])
  test_objects.append(test_aarch64_examples_obj)

test = env.Program(join(test_build_dir, 'test-runner'), test_objects,
                   LIBS=[libvixl])
env.Alias('tests', test)
top_level_targets.Add('tests', 'Build the tests.')


env.Alias('all', top_level_targets.targets)
top_level_targets.Add('all', 'Build all the targets above.')

Help('\n\nAvailable top level targets:\n' + top_level_targets.Help())

extra_targets = VIXLTargets()

# Build documentation
doc = [
    env.Markdown('README.md'),
    env.Markdown('doc/changelog.md'),
    env.Markdown('doc/aarch32/getting-started-aarch32.md'),
    env.Markdown('doc/aarch32/design/code-generation-aarch32.md'),
    env.Markdown('doc/aarch32/design/literal-pool-aarch32.md'),
    env.Markdown('doc/aarch64/supported-instructions-aarch64.md'),
    env.Markdown('doc/aarch64/getting-started-aarch64.md'),
    env.Markdown('doc/aarch64/topics/ycm.md'),
    env.Markdown('doc/aarch64/topics/extending-the-disassembler.md'),
    env.Markdown('doc/aarch64/topics/index.md'),
]
env.Alias('doc', doc)
extra_targets.Add('doc', 'Convert documentation to HTML (requires the '
                         '`markdown` program).')

Help('\nAvailable extra targets:\n' + extra_targets.Help())
