# Copyright 2020 Google, Inc.
#
# 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 the copyright holders 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 AND 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('*')

env.Append(CPPPATH=Dir('.'))

# Raw source files.
args = 'args.cc'
call_type = 'call_type.cc'
command = 'command.cc'
m5 = 'm5.cc'
m5_mmap = 'm5_mmap.c'
usage = 'usage.cc'

jni = 'jni_gem5Op.c'
lua = 'lua_gem5Op.cc'

all_call_types = list(env['CALL_TYPE'].values())
call_types = list([ ct for ct in all_call_types if ct.enabled ])
m5ops = { ct.name: 'abi/${ABI}/%s' % ct.impl_file
          for ct in call_types }
all_m5ops = list(m5ops.values())

default_call_type = list([ ct for ct in call_types if ct.default ])
assert len(default_call_type) == 1, \
        'There should be exactly one default call type for %s, found %d' % \
        (env['ABI'], len(default_call_type))
default_call_type = default_call_type[0]

static_env = env.Clone()
static_env.Append(LINKFLAGS=[ '-no-pie', '-static' ])

#
# The m5 library for use in other C/C++ programs.
#
libm5 = static_env.StaticLibrary('out/m5', [ m5_mmap ] + all_m5ops)

commands = env.SConscript('command/SConscript', exports={ "env": static_env })

#
# The m5 stand alone command line utility.
#
ct_support = []
for ct in call_types:
    ct_env = ct.setup_env(static_env)
    ct_support.extend(ct_env.StaticObject('call_type/%s.cc' % ct.name))
m5_bin = static_env.Program('out/m5', ct_support +
        [ args, call_type, command, commands, m5, m5_mmap, libm5, usage ])


# The shared version of the m5 op call sights, used by mutliple targets below.
shared_env = env.Clone()
shared_env.Append(ASFLAGS='-DM5OP_PIC')
m5op_shared = shared_env.SharedObject(all_m5ops)

#
# Unit tests for enabled call types.
#
call_type_shared = shared_env.SharedObject(call_type)
args_shared = shared_env.SharedObject(args)
m5_mmap_shared = shared_env.SharedObject(m5_mmap)
for ct in call_types:
    ct_env = ct.setup_env(shared_env, allow_default=False)
    srcs = [ 'call_type/%s.test.cc' % ct.name, 'call_type/%s.cc' % ct.name,
             call_type_shared, args_shared, m5_mmap_shared, m5ops[ct.name] ]
    if ct.verifier:
        srcs.append('abi/${ABI}/%s' % ct.verifier)
    ct_env.GTest('call_type/%s' % ct.name, *srcs)

if env['HAVE_JAVA']:
    #
    # A wrapper to make the m5 ops available in Java through the JNI.
    #
    java_env = shared_env.Clone()
    # SCons provides Java and JavaH builders, but the JavaH builder assumes
    # that the javah tool exists. Java has dropped that tool in favor of a -h
    # option on javac which the Java builder doesn't know how to use. To get
    # around this, we set up our own builder which does the "right thing" here.
    java_env.Command([ 'jni_gem5Op.h', 'out/gem5OpJni.jar' ],
                     'jni/gem5Op.java',
                     [ '${JAVAC} ${JAVACFLAGS} -d ${OUT} ${SOURCES} -h ${CWD}',
                       '${JAR} cvf ${TARGETS[1]} ${JNI_DIR}/*.class' ],
                     JNI_DIR=Dir('out').Dir('jni'),
                     OUT=Dir('out'), CWD=Dir('.'))
    # Set include paths to the C headers from the JDK which scons found for us.
    java_env.Append(CPPPATH='${JAVAINCLUDES}')
    java_env.SharedLibrary('out/gem5OpJni', [ jni ] + m5op_shared)


if env['HAVE_LUA51']:
    #
    # A wrapper to make the m5 ops available in lua version 5.1.
    #
    lua_env = shared_env.Clone()
    # Extract the include paths needed for lua51 using pkg-config.
    lua_env.ParseConfig('pkg-config --cflags lua51')
    lib = lua_env.SharedLibrary('out/gem5OpLua',
                                [ lua, m5_mmap_shared ] + m5op_shared)
