# -*- 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[-1] == '\n':
        line = line[:-1]
    return line

# Compilation flags

#opt_arch = 'core2'

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

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

# Installation flags

tftp_dir = ARGUMENTS.get('tftp', '')
if tftp_dir:
    Install(tftp_dir, '#bin/sigma0.nul')

# 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 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

target_env['CCFLAGS'] = '-m32'
target_env.Append(CCFLAGS = debug_opts)
target_env.Append(CCFLAGS = '-mregparm=3 -pipe -nostdlib -ffunction-sections -fshort-enums -minline-all-stringops -nostdinc')
#target_env.Append(CCFLAGS = (' -march=' + opt_arch))

target_env['CXXFLAGS'] = "-fno-exceptions -fno-rtti -fcheck-new -fno-threadsafe-statics"
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"]

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

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,
                    [ Copy("$TARGET", "$SOURCE"),
                      "strip $TARGET",
                      "size $TARGET",
                      ])
    z = env.Command(target + ".gz", g, ["gzip -c $SOURCE > $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)
    Local(z)
    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
