# -*- Mode: Python -*-

import sys, os

target = os.environ.get('NRE_TARGET') or 'x86_64'
if target == 'x86_32':
    cross = 'i686-pc-nulnova'
elif target == 'x86_64':
    cross = 'x86_64-pc-nulnova'
else:
    print "Please define NRE_TARGET to x86_32 or x86_64 first!"
    Exit(1)
crossver = '4.6.3'
crossdir = os.path.abspath('/tmp/nre-cross-' + target)

hostenv = Environment(
    ENV = os.environ,
    CXXFLAGS = '-Wall -Wextra -ansi -g'
)
env = Environment(
    CXXFLAGS = '-Wall -Wextra -ansi -std=c++0x',
    CFLAGS = '-Wall -Wextra -std=c99',
    # without "-z max-page-size=0x1000" ld produces really large binaries for x86_64, because it
    # aligns to 2MiB (not only in virtual memory, but also in the binary)
    LINKFLAGS = '-Wl,--no-undefined -static -Wl,-static -static-libgcc -Wl,-z,max-page-size=0x1000',
    ENV = {'PATH' : crossdir + "/bin:" + os.environ['PATH']},
    CPPPATH = '#include',
    CXX = cross + '-g++',
    LD = cross + '-ld',
    AS = cross + '-as',
    CC = cross + '-gcc',
    AR = cross + '-ar',
    RANLIB = cross + '-ranlib',
)

btype = os.environ.get('NRE_BUILD')
if btype == 'debug':
    env.Append(CXXFLAGS = ' -O0 -ggdb')
    env.Append(CFLAGS = ' -O0 -ggdb')
else:
    # we enable the framepointer to get stacktraces in release-mode. of course, we could also
    # disable stacktraces later, so that we don't need the framepointer.
    env.Append(CXXFLAGS = ' -O3 -DNDEBUG -fno-omit-frame-pointer')
    env.Append(CFLAGS = ' -O3 -DNDEBUG -fno-omit-frame-pointer')
    btype = 'release'
if target == 'x86_64':
    env.Append(CXXFLAGS = ' -mcmodel=large')
    env.Append(CFLAGS = ' -mcmodel=large')
    env.Append(LINKFLAGS = ' -mcmodel=large')
builddir = 'build/' + target + '-' + btype

verbose = ARGUMENTS.get('VERBOSE',0);
if int(verbose) == 0:
    hostenv['ASCOMSTR'] = env['ASCOMSTR'] = "AS $TARGET"
    hostenv['ASPPCOMSTR'] = env['ASPPCOMSTR'] = "ASPP $TARGET"
    hostenv['CCCOMSTR'] = env['CCCOMSTR'] = "CC $TARGET"
    hostenv['CXXCOMSTR'] = env['CXXCOMSTR'] = "CXX $TARGET"
    hostenv['LINKCOMSTR'] = env['LINKCOMSTR'] = "LD $TARGET"
    hostenv['ARCOMSTR'] = env['ARCOMSTR'] = "AR $TARGET"
    hostenv['RANLIBCOMSTR'] = env['RANLIBCOMSTR'] = "RANLIB $TARGET"

env.Append(
    ARCH = target,
    ROOTDIR = '#',
    BUILDDIR = '#' + builddir,
    BINARYDIR = '#' + builddir + '/bin/apps',
    LIBPATH = '#' + builddir + '/bin/lib',
    SYSLIBPATH = crossdir + '/lib',
    SYSGCCLIBPATH = crossdir + '/lib/gcc/' + cross + '/' + crossver
)
if target == 'x86_64':
    env.Append(LINK_ADDR = 0x300000000)
else:
    env.Append(LINK_ADDR = 0x100000)

def NREProgram(env, target, source):
    # for better debugging: put every executable at a different address
    myenv = env.Clone()
    if target != 'vancouver' and target != 'root':
        myenv.Append(LINKFLAGS = ' -Wl,--section-start=.init=' + ("0x%x" % env['LINK_ADDR']))
        env['LINK_ADDR'] += 0x100000
    prog = myenv.Program(
        target, source,
        LIBS = ['stdc++','supc++'],
        LIBPATH = [myenv['LIBPATH'], myenv['SYSLIBPATH']]
    )
    myenv.Depends(prog, myenv['SYSGCCLIBPATH'] + '/crt0.o')
    myenv.Depends(prog, myenv['SYSGCCLIBPATH'] + '/crt1.o')
    myenv.Depends(prog, myenv['SYSGCCLIBPATH'] + '/crtn.o')
    myenv.Depends(prog, myenv['LIBPATH'] + '/libstdc++.a')
    myenv.Depends(prog, myenv['LIBPATH'] + '/libc.a')
    myenv.Depends(prog, myenv['LIBPATH'] + '/libm.a')
    myenv.Depends(prog, myenv['LIBPATH'] + '/libg.a')
    myenv.Install(env['BINARYDIR'], prog)

env.NREProgram = NREProgram
hostenv.SConscript('tools/SConscript', 'hostenv',
                   variant_dir = builddir + '/tools', duplicate = 0)

for d in ['libs', 'services', 'apps']:
    env.SConscript(d + '/SConscript', 'env',
                   variant_dir = builddir + '/' + d, duplicate = 0)

# EOF
