# Copyright (c) 2017, TU Dresden
# Copyright (c) 2017, University of Kaiserslautern
# All rights reserved.

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Authors: Christian Menard
#          Matthias Jung

import os
from m5.util.terminal import get_termcap

Import('main')
systemc = main.Clone()

build_root = Dir('.').abspath
src_root = Dir('.').srcdir.abspath

systemc.Prepend(CPPPATH=Dir('./src'))
systemc.Prepend(CPATH=Dir('./src'))

systemc.Prepend(CXXFLAGS=['-DSC_INCLUDE_FX'])
systemc.Prepend(CFLAGS=['-DSC_INCLUDE_FX'])

conf = Configure(systemc,
                 conf_dir = os.path.join(build_root, '.scons_config'),
                 log_file = os.path.join(build_root, 'scons_config.log'))
systemc = conf.env

if systemc['PLATFORM'] == 'darwin':
    systemc.Append(LINKFLAGS=['-undefined', 'dynamic_lookup'])

arch = None
systemc['COROUTINE_LIB'] = ''
if conf.CheckDeclaration('__i386__'):
    systemc['COROUTINE_LIB'] = 'qt'
    systemc['QT_ARCH'] = 'i386'
    arch = 'i386'
elif conf.CheckDeclaration('__x86_64__'):
    systemc['COROUTINE_LIB'] = 'qt'
    systemc['QT_ARCH'] = 'iX86_64'
    arch = 'x86_64'
else:
    termcap = get_termcap(GetOption('use_colors'))
    print(termcap.Yellow + termcap.Bold +
          "Warning: Unrecognized architecture for systemc." + termcap.Normal)

systemc = conf.Finish()

if systemc['COROUTINE_LIB'] == 'pthreads':
    systemc.Prepend(CXXFLAGS=['-DSC_USE_PTHREADS'])

systemc_files = []
def SystemCSource(*args):
    for arg in args:
        systemc_files.append(systemc.File(arg))

if arch:
    for root, dirs, files in os.walk(src_root):
        if 'SConscript.sc' in files:
            build_dir = os.path.relpath(root, src_root)
            systemc.SConscript(os.path.join(root, 'SConscript.sc'),
                               exports=['systemc', 'SystemCSource'],
                               variant_dir=os.path.join(build_root, build_dir))

    systemc.Library('libsystemc', systemc_files)
    systemc.SharedLibrary('libsystemc', systemc_files)

