# -*- Mode: Python -*-

import os
import subprocess

# Uncomment this to get ccache-like behaviour.
# CacheDir(".objcache")

# Uncomment this to optimizing build system performance by sacrificing
# accuracy. Does not help a lot. YMMV.
# SourceSignatures('timestamp')
# TargetSignatures('timestamp')
# SetOption('implicit_cache', 1)

# Collect output of external programs

def collect_output(cmd):
    return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]

def chomp(line):
    if line and line[-1] == '\n':
        line = line[:-1]
    return line

# Compilation flags

# Compiler override
target_cc  = ARGUMENTS.get('target_cc')
target_cxx = ARGUMENTS.get('target_cxx')
ld_path    = ARGUMENTS.get('ld_path')
# Optimization flags

debug = ARGUMENTS.get('debug', 0)
if int(debug):
    debug_opts = ' -g -O1 '
else:
    debug_opts = ' -g -Os -fomit-frame-pointer '

ndebug = ARGUMENTS.get('ndebug', 0)
if int(ndebug):
    debug_opts += ' -DNDEBUG '

# Default environment for host machine. Use this to build host tools,
# that need to run during the build.
host_env = Environment()

# Freestanding environment for IA-32. Use this to build standalone
# binaries.
target_env = Environment()


if ARGUMENTS.get('VERBOSE') != "1":
    target_env.Append(CCCOMSTR  = "\tCC  $TARGET", CXXCOMSTR  = "\tCXX $TARGET", LINKCOMSTR = "\tLNK $TARGET",
                      ASCOMSTR  = "\tAS  $TARGET", ARCOMSTR  = "\tAR  $TARGET", RANLIBCOMSTR  = "\tLIB $TARGET",
                      ASPPCOMSTR = "\tASC $TARGET",
                      )

if target_cc:
    print("Target CC forced to '%s'." % target_cc)
    if not target_cxx:
        print("!!! You probably want to set a proper target_cxx !!!")
    target_env['CC'] = target_cc

if target_cxx:
    print("Target CXX forced to '%s'." % target_cxx)
    if not target_cc:
        print("!!! You probably want to set a proper target_cc !!!")
    target_env['CXX'] = target_cxx

if ld_path:
    print("Add LD_LIBRARY_PATH = '%s' to Target env" % ld_path)
    target_env['ENV']['LD_LIBRARY_PATH'] = ld_path

target_env['CCFLAGS'] = '-m32'
target_env.Append(CCFLAGS = debug_opts)
target_env.Append(CCFLAGS = '-mregparm=3 -pipe -nostdlib -ffunction-sections -ffreestanding -fshort-enums -fno-strict-aliasing -fno-exceptions -mpreferred-stack-boundary=4 -mincoming-stack-boundary=4 -minline-all-stringops -nostdinc -Wall -Winit-self -Wextra -Wno-parentheses -Wno-unused-parameter -Wswitch-enum -Wstrict-aliasing=2 -Wmissing-noreturn')
target_env.Append(CCFLAGS = (' -march=core2 -mtune=generic '))

target_env['CXXFLAGS'] = "-std=gnu++0x -fno-exceptions -fno-rtti -fcheck-new -fno-threadsafe-statics -Wold-style-cast "
target_env['CFLAGS'] = " -std=gnu99 -Wimplicit-function-declaration"
target_env['ASFLAGS'] = "-m32 -pipe -g"
target_env['LINK'] = "ld"
target_env['LINKFLAGS'] = ["-m",  "elf_i386", "-gc-sections", "-N", "--whole-archive", "--warn-common"]

target_env['CPPPATH'] = [chomp(collect_output([target_env['CXX'], "-print-file-name=include"])),
                         "#include"]

target_env['LIBPATH'] = ['#bin/lib']

# We want to be able to use linker scripts without doing a manual
# Depends().

def link(env, target, source, linkscript=None, **rest):
    if linkscript:
        linkscript = File(linkscript)
        # XXX rstr() does not work if linkscript is in the current
        # repository, i.e. the repository in which you typed `scons'.
        add_ld = ["-T", linkscript.rstr()]
    else:
        add_ld = []
    p = env.Program(target + ".debug", source,
                    LINKFLAGS=env['LINKFLAGS'] + add_ld,
                    **rest)
    g = env.Command(target, p,
                    [ "@strip -o $TARGET $SOURCE",
                      "@size $TARGET",
                      ])
    # Explicitly add linkscript to the dependencies.
    if linkscript:
        env.Depends(p, linkscript)
    # Always put both the debug and the final version in the current
    # directory. Even if they are already built elsewhere.
    Local(p)
    Local(g)
    return g

target_env.AddMethod(link, "Link")

# Export our environments. Should be cloned before changing them.
Export('host_env')
Export('target_env')
Export('debug_opts')

SConscript(Glob('*/SConscript'))
SConscript(Glob('*/*/SConscript'))

# EOF
