# Copyright 2013, ARM Limited
# 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 os
import os.path
import sys

# Global configuration.
PROJ_SRC_DIR   = 'src'
PROJ_SRC_FILES = '''
src/utils-vixl.cc
src/a64/assembler-a64.cc
src/a64/macro-assembler-a64.cc
src/a64/instructions-a64.cc
src/a64/decoder-a64.cc
src/a64/debugger-a64.cc
src/a64/disasm-a64.cc
src/a64/cpu-a64.cc
src/a64/simulator-a64.cc
src/a64/instrument-a64.cc
'''.split()
PROJ_EXAMPLES_DIR = 'examples'
PROJ_EXAMPLES_SRC_FILES = '''
examples/debugger.cc
examples/add3-double.cc
examples/add4-double.cc
examples/factorial-rec.cc
examples/factorial.cc
examples/sum-array.cc
examples/abs.cc
examples/swap4.cc
examples/swap-int32.cc
examples/check-bounds.cc
examples/getting-started.cc
'''.split()
# List target specific files.
# Target names are used as dictionary entries.
TARGET_SRC_DIR = {
  'cctest': 'test',
  'bench_dataop': 'benchmarks',
  'bench_branch': 'benchmarks',
  'examples': 'examples'
}
TARGET_SRC_FILES = {
  'cctest': '''
    test/cctest.cc
    test/test-utils-a64.cc
    test/test-assembler-a64.cc
    test/test-simulator-a64.cc
    test/test-disasm-a64.cc
    test/test-fuzz-a64.cc
    test/examples/test-examples.cc
    '''.split() + PROJ_EXAMPLES_SRC_FILES,
  'bench_dataop': '''
    benchmarks/bench-dataop.cc
    '''.split(),
  'bench_branch': '''
    benchmarks/bench-branch.cc
    '''.split()
}
RELEASE_OBJ_DIR  = 'obj/release'
DEBUG_OBJ_DIR    = 'obj/debug'
COVERAGE_OBJ_DIR = 'obj/coverage'


# Helper functions.
def abort(message):
  print('ABORTING: ' + message)
  sys.exit(1)


def list_target(obj_dir, src_files):
  return map(lambda x: os.path.join(obj_dir, x), src_files)


def create_variant(obj_dir, targets_dir):
  VariantDir(os.path.join(obj_dir, PROJ_SRC_DIR), PROJ_SRC_DIR)
  for directory in targets_dir.itervalues():
    VariantDir(os.path.join(obj_dir, directory), directory)


# Build arguments.
args = Variables()
args.Add(EnumVariable('mode', 'Build mode', 'release',
                      allowed_values = ['release', 'debug', 'coverage']))
args.Add(EnumVariable('target', 'Target to build', 'cctest',
                      allowed_values = ['cctest',
                                        'bench_dataop',
                                        'bench_branch',
                                        'examples']))
args.Add(EnumVariable('simulator', 'build for the simulator', 'on',
                      allowed_values = ['on', 'off']))

# Configure the environment.
create_variant(RELEASE_OBJ_DIR, TARGET_SRC_DIR)
create_variant(DEBUG_OBJ_DIR, TARGET_SRC_DIR)
create_variant(COVERAGE_OBJ_DIR, TARGET_SRC_DIR)
env = Environment(variables=args)

# Commandline help.
Help(args.GenerateHelpText(env))

# Abort if any invalid argument was passed.
# This check must happened after an environment is created.
unknown_arg = args.UnknownVariables()
if unknown_arg:
  abort('Unknown variable(s): ' + str(unknown_arg.keys()))

# Setup tools.
# This is necessary for cross-compilation.
env['CXX'] = os.environ.get('CXX', env.get('CXX'))
env['AR'] = os.environ.get('AR', env.get('AR'))
env['RANLIB'] = os.environ.get('RANLIB', env.get('RANLIB'))
env['CC'] = os.environ.get('CC', env.get('CC'))
env['LD'] = os.environ.get('LD', env.get('LD'))

if os.environ.get('CPPFLAGS'):
  env.Append(CPPFLAGS = os.environ.get('CPPFLAGS').split())
if os.environ.get('LINKFLAGS'):
  env.Append(LINKFLAGS = os.environ.get('LINKFLAGS').split())

# Always look in 'src' for include files.
env.Append(CPPPATH = [PROJ_SRC_DIR])
env.Append(CPPFLAGS = ['-Wall',
                       '-Werror',
                       '-fdiagnostics-show-option',
                       '-Wextra',
                       '-pedantic',
                       # Explicitly enable the write-strings warning. VIXL uses
                       # const correctly when handling string constants.
                       '-Wwrite-strings'])

target_program = env['target']
build_suffix = ''

if env['simulator'] == 'on':
  env.Append(CPPFLAGS = ['-DUSE_SIMULATOR'])
  build_suffix += '_sim'

if env['mode'] == 'debug':
  env.Append(CPPFLAGS = ['-g', '-DDEBUG'])
  # Append the debug mode suffix to the executable name.
  build_suffix += '_g'
  build_dir = DEBUG_OBJ_DIR
elif env['mode'] == 'coverage':
  env.Append(CPPFLAGS = ['-g', '-DDEBUG', '-fprofile-arcs', '-ftest-coverage'])
  env.Append(LINKFLAGS = ['-fprofile-arcs'])
  # Append the coverage mode suffix to the executable name.
  build_suffix += '_gcov'
  build_dir = COVERAGE_OBJ_DIR
else:
  # Release mode.
  env.Append(CPPFLAGS = ['-O3'])
  build_dir = RELEASE_OBJ_DIR
  # 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.
  env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized'])


if target_program == 'cctest':
  env.Append(CPPPATH = [PROJ_EXAMPLES_DIR])
  env.Append(CPPFLAGS = ['-DTEST_EXAMPLES'])

# Build the library.
proj_library = env.Library('vixl' + build_suffix, list_target(build_dir, PROJ_SRC_FILES))

if target_program == 'examples':
  # Build the examples.
  env.Append(CPPPATH = [PROJ_EXAMPLES_DIR])
  for example in PROJ_EXAMPLES_SRC_FILES:
    example_name = "example-" + os.path.splitext(os.path.basename(example))[0]
    env.Program(example_name, list_target(build_dir, [example]) + proj_library)
else:
  # Build the target program.
  program_target_files = list_target(build_dir, TARGET_SRC_FILES[env['target']])
  env.Program(target_program + build_suffix, program_target_files + proj_library)
