# 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'
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 + [ 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)
