########################################################################################
#
# SConscript
#
# Scons script for station / fully embedded (embedded side)
#
# Copyright (C) RivieraWaves 2011-2019
#
# $Id$
#
#########################################################################################

import sys
import os
import os.path

import SCons.Util
import scutils

#-----------------------------------------------------------
# Build tool and default settings
#-----------------------------------------------------------

# initialize the environment from the command line arguments
env = scutils.env_init()

# Get arch
arch = env['ARCH']

# Get buildtool
buildtool = env['BUILDTOOL']

# Build type
if env['LIBRARY'] == 'on':
    build_type = 'library'
else:
    build_type = 'executable'

# Get product
product = env['PRODUCT']
assert(product in ('lmac', 'fmac', 'fhost'))

# Get phy
phy = env['PHY']
assert(phy in ('trident', 'karst', 'elma', 'sdmb2b', 'aetnensis', 'custom_rf'))

# Get Platform
platform = env['PLATFORM']
assert(platform in ('tlm', 'virtex6', 'virtex7', 'custom'))

# Get RTOS
rtos = env['RTOS']
assert(rtos in ('none', 'freertos', 'rhino', 'rhino/rtos_al'))
assert(product != 'fhost' or rtos != 'none')

# Get Network Stack
nets = env['NETS']
assert(nets in ('none', 'lwip', 'lwip/net_al'))
assert(product != 'fhost' or nets != 'none')

# Get crypto library
crypto = env['CRYPTO']
assert(crypto in ('none', 'mbedtls'))

#-----------------------------------------------------------
# Paths
#-----------------------------------------------------------

# Default paths
plf_dft_dir      = scutils.ext_path('#/../plf/refip')
build_dft_dir    = scutils.ext_path('#/../build')
ip_dft_dir       = scutils.ext_path('#/../ip/')
mod_dft_dir      = scutils.ext_path('#/../modules/')
ext_dir          = scutils.diff_path('#','.')

# Build paths
build_dir = os.path.join(build_dft_dir, product + '_' + arch + '_' + phy)
obj_dir   = os.path.join(build_dir, buildtool)

# IP paths
lmacip_dir = os.path.join(ip_dft_dir, 'lmac')
umacip_dir = os.path.join(ip_dft_dir, 'umac')

# PLF paths
plf_cfg_dir = os.path.join(plf_dft_dir, 'config')
plf_build_dir = os.path.join(plf_dft_dir, 'build', 'reg')
plf_drv_dir = os.path.join(plf_dft_dir, 'src', 'driver')

# Extra component paths (RTOS, Network stack, Supplicant)
extra_comp = []
env['EXTRA_COMPONENT'] = []
if rtos != 'none':
    path = os.path.join(scutils.ext_path('#/../../'), rtos)
    extra_comp += [ [path, {}] ]
    env['EXTRA_COMPONENT'] += [rtos + "=" + path]

if product == 'fhost':
    if nets != 'none':
        path = os.path.join(scutils.ext_path('#/../../'), nets)
        extra_comp += [ [path, {}] ]
        env['EXTRA_COMPONENT'] += [nets + "=" + path]

    path = os.path.join(scutils.ext_path('#/../../wpa_supplicant'))
    extra_comp += [ [path,
                     {'WARNINGS':"$WARNINGS -Wno-switch-default -Wno-unused" }] ]
    env['EXTRA_COMPONENT'] += ["wpa_supplicant=" + path]

    if crypto != 'none':
        path = os.path.join(scutils.ext_path('#/../../'), crypto)
        env['EXTRA_COMPONENT'] += [crypto + "=" + path]

        if crypto == 'mbedtls':
            extra_comp += [ [path,
                             {'WARNINGS':"$WARNINGS -Wno-switch-default" }] ]
        else:
            extra_comp += [ [path, {}] ]


#-----------------------------------------------------------
# Target specific settings
#-----------------------------------------------------------

# save directory in environment
env['OBJ_DIR'] = obj_dir

# environment  settings
env['PROGNAME'] = product + 'fw'
env['TYPE']     = 'fw'

env['CPPDEFINES'] = []

if (arch == 'tl4xx'):
    env['ENV']['CPU'] = env['CPU']
    env['CPPDEFINES'] += ['CFG_RWTL']
elif (arch == 'ceva-x'):
    env['ENV']['CPU'] = env['CPU']
    env['CPPDEFINES'] += ['CFG_RWX1']
elif (arch == 'risc-v'):
    env['CPPDEFINES'] += ['CFG_ZERORISCY']

# platform
env['CPPDEFINES'] += ['CFG_' + platform.upper()]

# preprocessor macros
env['CPPDEFINES'] += ['CFG_EMB', 'CFG_SPLIT']

if rtos != 'none':
    env['CPPDEFINES'] += ['CFG_RTOS']

if product == 'fhost':
    env['CPPDEFINES'] += ['CFG_FHOST']

if product in ('fmac', 'fhost'):
    env['CPPDEFINES'] += ['CFG_UMAC']

# profiling on/off
if env['PROF'] == 'on':
    env['CPPDEFINES'] += ['CFG_PROF']

# System statistics on/off
if env['STATS'] == 'on':
    env['CPPDEFINES'] += ['CFG_STATS']

# Debug level
env['CPPDEFINES'] += ['CFG_DBG=' + env['DBG']]

# Beaconing modes on/off
if env['BCN'] == 'on':
    env['CPPDEFINES'] += ['CFG_BCN']

# A-MPDU TX on/off
if env['AGG'] == 'on':
    env['CPPDEFINES'] += ['CFG_AGG']

# Max A-MSDU RX size
assert(env['AMSDURX'] in ('4k', '8k', '12k'))
env['CPPDEFINES'] += ['CFG_AMSDU_' + env['AMSDURX'].upper()]

# number of virtual interfaces supported
env['CPPDEFINES'] += ['CFG_VIF_MAX=' + env['VIF']]

# number of peer devices supported
env['CPPDEFINES'] += ['CFG_STA_MAX=' + env['STA']]

# minimal MPDU spacing in TX
env['CPPDEFINES'] += ['CFG_SPC=' + env['SPC']]

# Number of TX descriptors per queue
env['CPPDEFINES'] += ['CFG_TXDESC0=' + env['TXDESC0']]
env['CPPDEFINES'] += ['CFG_TXDESC1=' + env['TXDESC1']]
env['CPPDEFINES'] += ['CFG_TXDESC2=' + env['TXDESC2']]
env['CPPDEFINES'] += ['CFG_TXDESC3=' + env['TXDESC3']]
env['CPPDEFINES'] += ['CFG_TXDESC4=' + env['TXDESC4']]

# MAC version
assert(env['MAC'] in ('v10', 'v20', 'v21'))
env['CPPDEFINES'] += ['CFG_MAC_VER_' + env['MAC'].upper()]

# MODEM version
assert(env['MDM'] in ('v10', 'v11', 'v20', 'v21', 'v22', 'v30'))
env['CPPDEFINES'] += ['CFG_MDM_VER_' + env['MDM'].upper()]

# IPC version
assert(env['IPC'] in ('v10', 'v11'))
env['CPPDEFINES'] += ['CFG_IPC_VER_' + env['IPC'].upper()]

# Platform version
if (env['MDM'] < 'v20'):
    env['PLFVER'] = 'v10'
elif (env['MDM'] < 'v30'):
    env['PLFVER'] = 'v20'
else:
    env['PLFVER'] = 'v30'
env['CPPDEFINES'] += ['CFG_PLF_VER_' + env['PLFVER'].upper()]

# RX path version
if (env['MAC'] < 'v21'):
    env['RXVER'] = 'v10'
else:
    env['RXVER'] = 'v20'

# POWERSAVE support on/off
if env['PS'] == 'on':
    env['CPPDEFINES'] += ['CFG_PS']

# BFMEE support on/off
if env['BFMEE'] == 'on':
    env['CPPDEFINES'] += ['CFG_BFMEE']

# MU-MIMO RX support on/off
if env['MURX'] == 'on':
    env['CPPDEFINES'] += ['CFG_MU_RX']

# BFMER support on/off
if env['BFMER'] == 'on':
    env['CPPDEFINES'] += ['CFG_BFMER']

# MU-MIMO maximum number of users
assert(env['MUCNT'] in ('1', '2', '3', '4'))
env['CPPDEFINES'] += ['CFG_MU_CNT=' + env['MUCNT']]

# DPSM support on/off
if env['DPSM'] == 'on':
    env['CPPDEFINES'] += ['CFG_DPSM']

# UAPSD support on/off
if env['UAPSD'] == 'on':
    env['CPPDEFINES'] += ['CFG_UAPSD']

# Connection monitoring support on/off
if env['CMON'] == 'on':
    env['CPPDEFINES'] += ['CFG_CMON']

# Multi-role support on/off
if env['MROLE'] == 'on':
    env['CPPDEFINES'] += ['CFG_MROLE']

# Scanning in LMAC support on/off
if env['HWSCAN'] == 'on':
    env['CPPDEFINES'] += ['CFG_HWSCAN']

# Autonomous beacon transmission in LMAC support on/off
if env['AUTOBCN'] == 'on':
    env['CPPDEFINES'] += ['CFG_AUTOBCN']

# Key RAM configuration support on/off
if env['KEYCFG'] == 'on':
    env['CPPDEFINES'] += ['CFG_KEYCFG']

# Number of P2P link that can be created in parallel (0=Disabled)
env['CPPDEFINES'] += ['CFG_P2P=' + env['P2P']]

# P2P GO PS support on/off
if env['P2P_GO'] == 'on':
    env['CPPDEFINES'] += ['CFG_P2P_GO']

# WAPI
if env['WAPI'] == 'on':
    env['CPPDEFINES'] += ['CFG_WAPI']

# A-MPDU length adaptation to BW
if env['BWLEN'] == 'on':
    env['CPPDEFINES'] += ['CFG_BWLEN']

# Mesh support
if env['MESH_VIF'] != '0':
    env['CPPDEFINES'] += ['CFG_MESH']
    env['CPPDEFINES'] += ['CFG_MESH_VIF=' + env['MESH_VIF']]
    env['CPPDEFINES'] += ['CFG_MESH_LINK=' + env['MESH_LINK']]
    env['CPPDEFINES'] += ['CFG_MESH_PATH=' + env['MESH_PATH']]
    env['CPPDEFINES'] += ['CFG_MESH_PROXY=' + env['MESH_PROXY']]

# VHT support on/off (only for FullMAC)
if env['VHT'] == 'on':
    env['CPPDEFINES'] += ['CFG_VHT']

# HE support on/off (only for FullMAC)
if env['HE'] == 'on':
    env['CPPDEFINES'] += ['CFG_HE']

# Maximum number of RX BlockAck agreements we can have in parallel
env['CPPDEFINES'] += ['CFG_BARX=' + env['BARX']]

# Maximum number of TX BlockAck agreements we can have in parallel
env['CPPDEFINES'] += ['CFG_BATX=' + env['BATX']]

# Number of buffers per reordering instance
env['CPPDEFINES'] += ['CFG_REORD_BUF=' + env['REORDBUF']]

if env['AMSDU'] == 'on':
    env['CPPDEFINES'] += ['CFG_AMSDU']

# Debug dump on/off
if env['DBGDUMP'] == 'on':
    env['CPPDEFINES'] += ['CFG_DBGDUMP']

# Debug key RAM dump on/off
if env['DBGDUMPKEY'] == 'on':
    env['CPPDEFINES'] += ['CFG_DBGDUMPKEY']

# Trace buffer on/off
if env['TRACE'] == 'on':
    env['CPPDEFINES'] += ['CFG_TRACE']

# Recovery mechanism on/off
if env['REC'] == 'on':
    env['CPPDEFINES'] += ['CFG_REC']

# RADAR detection support on/off
if env['RADAR'] == 'on':
    env['CPPDEFINES'] += ['CFG_RADAR']

# Unsupported HT Frame Logging support on/off
if env['UF'] == 'on':
    env['CPPDEFINES'] += ['CFG_UF']

# Monitor + Data interface support on/off
if env['MON_DATA'] == 'on':
    env['CPPDEFINES'] += ['CFG_MON_DATA']

# MFP support
if env['MFP'] == 'on':
    env['CPPDEFINES'] += ['CFG_MFP']

# TDLS support on/off
if env['TDLS'] == 'on':
    env['CPPDEFINES'] += ['CFG_TDLS']

# Antenna Diversity support on/off
if env['ANT_DIV'] == 'on':
    env['CPPDEFINES'] += ['CFG_ANT_DIV']

# HSU support 0/1/2
env['CPPDEFINES'] += ['CFG_HSU=' + env['HSU']]

# MAC interface
if product == 'fhost':
    env['MACIF'] = "fhost"
    env['IPC_TYPE'] = "_fhost"
    env['CPPDEFINES'] += ['CONFIG_RWNX_LWIP']
    if crypto != 'none':
        env['CPPDEFINES'] += ['CFG_CRYPTO']
        env['CPPDEFINES'] += ['CONFIG_' + crypto.upper()]
    # TG support on/off
    if env['TG'] == 'on':
        env['CPPDEFINES'] += ['CFG_TG']
    # Monitor mode support on/off
    if env['FHOST_MONITOR'] == 'on':
        env['CPPDEFINES'] += ['CFG_FHOST_MONITOR']
    # Smartconfig support on/off
    if env['SMARTCONFIG'] == 'on':
        env['CPPDEFINES'] += ['CFG_SMARTCONFIG']
    if env['STACK_CHECK'] == 'on':
        env['STACK_CHECK'] = 'off'
        # use RTOS facility for stack overflow check
        env['CPPDEFINES'] += ['RTOS_STACK_CHECK']
else:
    env['MACIF'] = "ipc"

#-----------------------------------------------------------
# List of Included modules
#-----------------------------------------------------------

modules_list = ['ke', 'common', 'mac', 'dbg', 'macif']
if env['MESH_VIF'] != '0' and product in ('fmac', 'fhost'):
    modules_list += ['mesh']
if rtos != 'none':
    modules_list += ['rtos']
if product == 'fhost'    :
    modules_list += ['fhost']

#-----------------------------------------------------------
# Generic settings
#-----------------------------------------------------------
env['SRC_LIST'] = []
env['SRC_DIR'] = []

#-----------------------------------------------------------
# Environment configuration
#-----------------------------------------------------------

if (buildtool == 'aps-gcc'):
    env['WARNINGS'] = ' -Wall -Wextra -Wno-array-bounds -Wno-unused-macros -Wno-cast-align'\
                     + ' -Wno-unused-function -Wno-unused-parameter -Wno-parentheses -Wundef -Winit-self -Werror'

    env['CCFLAGS'] = ' $WARNINGS -fdata-sections -ffunction-sections '        \
                   + ' -g3 -fmessage-length=0 -std=gnu99 -mmul -G0 '
    if env['STACK_CHECK'] == 'on':
            env['CCFLAGS'] += ' -fstack-check '
    env['ASFLAGS']   = '-g3'
    env['LINKFLAGS'] =   ' -g3 -G0 -nostartfiles '                     \
                       + ' -Wl,--noinhibit-exec,--gc-sections,--relax '

    if env['SAVETMP']:
        env.Append(CCFLAGS = ' --save-temps ')
elif (buildtool == 'rvds'):
    # msg 193-D is for undefined preprocessor identifier
    env['CCFLAGS']   = (  ' --asm --interleave --diag_style=gnu --debug --dwarf2 --c99 '
                        + ' --diag_warning=C193 ')

    env['ASFLAGS']   =  ' --diag_style=gnu --debug'
    env['LINKFLAGS'] = (' --map --symbols --diag_style gnu '
        + ' --info architecture,common,debug,exceptions,inline,inputs,libraries,sizes,stack,'
        + 'tailreorder,totals,unused --callgraph --entry 0x00 --datacompressor off ')

    if env['REM']:
        env.Append(CCFLAGS = ' --remarks --diag_suppress=1301,2530,826 ')
    else:
        env['CCFLAGS'] += '--diag_suppress=177'
elif (buildtool == 'gnuarm'):
    env['CCFLAGS'] = ' -mabi=aapcs -mfloat-abi=soft -mfpu=fpa -g3 -fms-extensions ' \
                   + ' -Wundef -std=c99 '
    env['ASFLAGS']   = ' -mfloat-abi=soft -mfpu=fpa -g'
    env['LINKFLAGS'] = ' --cref --gc-sections'

    if env['SAVETMP']:
        env.Append(CCFLAGS = ' --save-temps ')

elif (buildtool == 'armgcc_4_8'):
    env['CCFLAGS'] = ' -mabi=aapcs -mfloat-abi=soft -mfpu=vfp -g3 -fms-extensions ' \
                   + ' -Wall -Wchar-subscripts -Wformat -Wuninitialized ' \
                   + ' -Winit-self -Wignored-qualifiers -Wswitch-default -Wunused -Wundef -std=c99 '
    env['ASFLAGS']   = ' -mfloat-abi=soft -mfpu=vfp -g'
    if env['ARCH'] == 'cortex':
        env['CCFLAGS'] += ' -mthumb '
    env['LINKFLAGS'] = ' --cref --gc-sections '

    if env['SAVETMP']:
        env.Append(CCFLAGS = ' --save-temps ')

elif (buildtool == 'tl4'):
    # Assembler warnings 672 and 727 are relative to compability mode that is not used, so ignore them
    env['CCFLAGS'] = ' -c -Wundef -Os3 -std=gnu99 -maudio -mrelative-path -mno-allow-bubbles -mquiet -INLINE:=on -Wall -Wno-unused -D_DEBUG -Wa,-quiet,-ignoreWarnings\\\,672\\\,727 '
    env['ASFLAGS'] = '-w3 -vgen -quiet -p,-d,_DEBUG  -format 80,80 -ignoreWarnings,672,727'
    # Warning 111 is section location crossed internal memory boundary.
    env['LINKFLAGS'] = ' -m -s -quiet -unrefFuncs -removeUnRefFunc -enableExtMemTL41x -removeNoloadSec -p,-d,_DEBUG -internalCode128 -internalData64 -errForWarn 111'

elif (buildtool == 'riscv32'):
    env['WARNINGS'] = ' -Wall -Wchar-subscripts -Wformat -Wuninitialized ' \
                   + ' -Winit-self -Wignored-qualifiers -Wswitch-default -Wunused -Wundef -Werror'

    env['CCFLAGS'] = ' $WARNINGS -fdata-sections -ffunction-sections ' \
                   + ' -g3 -fmessage-length=0 -std=gnu99 '
    if env['STACK_CHECK'] == 'on':
            env['CCFLAGS'] += ' -fstack-check '
    env['LINKFLAGS'] =   ' -g3 -nostartfiles -Wl,--noinhibit-exec,--gc-sections,--relax '
    env['ASFLAGS']   = '-g'

    if env['SAVETMP']:
        env.Append(CCFLAGS = ' --save-temps ')

elif (buildtool == 'ceva-x-cc'):
    #Problem with -mno-wopt
    #-OPT:alias=no_typed -mno-ds -mno-if-conv -mno-peephole -fno-common -Bsymbolic  -mno-wopt -mrtl-version-1.1.0 -mno-call-save-funcs
    env['CCFLAGS'] = ' -c -g -mquiet -Wundef -Wall -Wno-unused -Wa,-quiet -Os3 -std=gnu99 -mrelative-path -CG:SPU_FP_num=0 -INLINE:asm=on -INLINE:=on -D_DEBUG,-ignoreWarnings\\\,672\\\,727 '
    env['ASFLAGS'] = '-w3 -vgen -quiet -p,-d,_DEBUG  -format 80,80 -ignoreWarnings,672,727'
    # Warning 111 is section location crossed internal memory boundary.
    env['LINKFLAGS'] = ' -m -s -quiet -noOs -unrefFuncs -removeUnRefFunc -removeNoloadSec -p,-d,_DEBUG -internalData128 -internalCode256 -errForWarn 111'

#-----------------------------------------------------------
# Input files
#-----------------------------------------------------------
# Registers generation
scutils.build_regs(env, plf_cfg_dir, plf_build_dir, build_dir, plf_dft_dir)

objectlist = []
includelist = []
exportlist = []

# LMAC
objectlist += scutils.build_object(env, lmacip_dir)
includelist += scutils.file_list_read(env, os.path.join(lmacip_dir, 'includelist.txt'))
exportlist += scutils.file_list_read(env, os.path.join(lmacip_dir, 'exportlist.txt'), must_exist = False)

# FMAC
if product in ('fmac', 'fhost'):
    objectlist += scutils.build_object(env, umacip_dir)
    includelist += scutils.file_list_read(env, os.path.join(umacip_dir, 'includelist.txt'))
    exportlist += scutils.file_list_read(env, os.path.join(umacip_dir, 'exportlist.txt'), must_exist = False)

# Modules
for module in modules_list:
    objectlist += scutils.build_object(env, os.path.join(mod_dft_dir, module))
    includelist += scutils.file_list_read(env, os.path.join(mod_dft_dir, module, 'includelist.txt'))
    exportlist += scutils.file_list_read(env, os.path.join(mod_dft_dir, module, 'exportlist.txt'), must_exist = False)

# Platform
if build_type == 'executable':
    objectlist += scutils.build_object(env, plf_dft_dir)
else:
    # We don't want to build the 'main' but still for now always compiled the platform drivers
    objectlist += scutils.build_object(env, plf_drv_dir)
    exportlist += scutils.file_list_read(env, os.path.join(plf_drv_dir, 'exportlist.txt'), must_exist = False)
includelist += scutils.file_list_read(env, os.path.join(plf_dft_dir, 'includelist.txt'))

# Extra components
for comp in extra_comp:
    objectlist += scutils.build_object(env, comp[0], comp[1])
    includelist += scutils.file_list_read(env, os.path.join(comp[0], 'includelist.txt'))
    exportlist += scutils.file_list_read(env, os.path.join(comp[0], 'exportlist.txt'), must_exist = False)

env.Replace(CPPPATH = includelist)

# Generate and add the file containing the version/build date strings
scutils.build_version_add(objectlist, env, os.path.join(plf_build_dir, platform, arch))

#-----------------------------------------------------------
# Output prog
#-----------------------------------------------------------
if build_type == 'executable':
    # Link objectlist into elf
    target = env.Program(os.path.join(build_dir, env['PROGNAME']), objectlist)

    # add the file where the link info must be stored
    linkinfo_path = os.path.join(build_dir, 'linkinfo.' + buildtool + '.txt')
    env.Replace(LINKINFOFILE = scutils.ext_path(linkinfo_path))

    linkmap_source = os.path.join(plf_cfg_dir, arch, buildtool, 'map_' + env['PRODUCT'] + '.txt')
    if not os.path.isfile(linkmap_source):
        linkmap_source = os.path.join(plf_cfg_dir, arch, buildtool, 'map.txt')
    linkmap_path = os.path.join(build_dir, 'map.txt')
    env.Replace(LINKMAPFILE = scutils.ext_path(linkmap_path))
    Depends(target, scutils.build_map(linkmap_path, linkmap_source, env, objectlist))

    # then convert elf to binary format
    if (buildtool == 'rvds'):
        target = scutils.rvds_elf2bin(env, os.path.join(build_dir, env['PROGNAME']), target)
    elif (buildtool == 'gnuarm'):
        target = scutils.gnuarm_elf2bin(env, os.path.join(build_dir, env['PROGNAME']), target)
    elif (buildtool == 'armgcc_4_8'):
        target = scutils.armgcc_4_8_elf2bin(env, os.path.join(build_dir, env['PROGNAME']), target)
    elif (buildtool == 'aps-gcc'):
        target = scutils.aps_elf2ihex(env, os.path.join(build_dir, env['PROGNAME']), target)
    elif (buildtool == 'tl4'):
        target = scutils.tl4_coff2hex(env, os.path.join(build_dir, env['PROGNAME']), target)
    elif (buildtool == 'ceva-x-cc'):
        target = scutils.ceva_x_coff2ihex(env, os.path.join(build_dir, env['PROGNAME']), target)
    elif (buildtool == 'riscv32'):
        target = scutils.riscv_elf2ihex(env, os.path.join(build_dir, env['PROGNAME']), target)
else:
    target = env.Library(os.path.join(build_dir, env['PROGNAME'] + '.a'), objectlist)
    target += exportlist

#-----------------------------------------------------------
# Trace dictionary
#-----------------------------------------------------------
if env['TRACE'] == 'on':
    target += scutils.build_dict(os.path.join(build_dir, env['PROGNAME'] + ".pm"), env)

#-----------------------------------------------------------
# Code analysis
#-----------------------------------------------------------
if sys.version_info >= (2, 7) and not GetOption('clean'):
    if env['ANALYSIS'] == 'all' or env['ANALYSIS'] == 'cppcheck':
        scutils.static_analysis('cppcheck', build_dir, env)
    if env['ANALYSIS'] == 'all' or env['ANALYSIS'] == 'flawfinder':
        scutils.static_analysis('flawfinder', build_dir, env)

#-----------------------------------------------------------
# Install and alias
#-----------------------------------------------------------

if env['INST']:
    env.Install(env['INST'], target, PRINT_CMD_LINE_FUNC=scutils.outstr_inst)
    Alias(ext_dir, env['INST'])
else:
    Alias(ext_dir, build_dir)
