# 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('*')

# Raw source files.
m5_mmap = 'm5_mmap.c'
args = 'args.c'
m5 = 'm5.c'
jni = 'jni_gem5Op.c'
lua = 'lua_gem5Op.c'

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

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['VARIANT'], len(default_call_type))
default_call_type = default_call_type[0]

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

for ct in all_call_types:
    static_env.Append(CFLAGS='-DENABLE_CT_%s=%d' %
                (ct.name, 1 if ct.enabled else 0))
    static_env.Append(CFLAGS='-DDEFAULT_CT_%s=%d' %
                (ct.name, 1 if ct.default else 0))
static_env.Append(CFLAGS='-DDEFAULT_CALL_TYPE=%s' % default_call_type.name)

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


#
# The m5 stand alone command line utility.
#
ct_support = list([ File('%s_call_type.c' % ct.name) for ct in call_types ])
m5_bin = static_env.Program('out/m5',
        ct_support + [ args, m5, m5_mmap, libm5 ])


# 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(m5ops)

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 ] + m5op_shared)
