import os

Import('env')

# Build environment configuration --------------------------------------------

# Apply CFLAGS, CXXFLAGS, LDFLAGS from the system environment.
flagnames = 'CFLAGS CXXFLAGS LDFLAGS'.split()
env.MergeFlags([os.environ.get(n, '') for n in flagnames])

# The directory of this SConscript should be searched first for any headers.
env.PrependUnique(CPPPATH=Dir('.'))

# Insert LIBRARY_PATH explicitly because some compilers
# ignore it in the system environment.
env.PrependUnique(LIBPATH=env['ENV'].get('LIBRARY_PATH', '').split(':'))

# Use Intel C++ compiler when it is available
icpc = env.WhereIs('icpc')
if icpc:
    env.Tool('intelc', topdir=icpc[:icpc.rfind('/bin')])

# Declare external libraries.
env.ParseConfig("gsl-config --cflags --libs")
# dladdr in runtimepath.cpp requires the dl library.
env.AppendUnique(LIBS=['dl'])

fast_linkflags = ['-s']

# Platform specific intricacies.
if env['PLATFORM'] == 'darwin':
    env.AppendUnique(CXXFLAGS='-ftemplate-depth-256')
    env.Append(SHLINKFLAGS=['-install_name', '$TARGET.abspath'])
    env.AppendUnique(SHLINKFLAGS='-headerpad_max_install_names')
    fast_linkflags[:] = []

# configure version specific options.
skip_configure = (GetOption('clean') or GetOption('help') or
        (['sdist'] == list(COMMAND_LINE_TARGETS)))
if not skip_configure:
    SConscript('SConscript.configure')
elif GetOption('clean'):
    # make sure ObjCryst files will be also cleaned
    env['has_objcryst'] = True

# Compiler specific options
if icpc:
    # options for Intel C++ compiler on hpc dev-intel07
    env.PrependUnique(CCFLAGS=['-w1', '-fp-model', 'precise'])
    env.PrependUnique(LIBS=['imf'])
    fast_optimflags = ['-fast', '-no-ipo']
else:
    # g++ options
    env.PrependUnique(CCFLAGS=['-Wall'])
    fast_optimflags = ['-ffast-math']

# Configure build variants
if env['build'] == 'debug':
    env.Append(CCFLAGS='-g')
elif env['build'] == 'fast':
    env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags)
    env.AppendUnique(CPPDEFINES={'NDEBUG' : None})
    env.AppendUnique(LINKFLAGS=fast_linkflags)

if env['profile']:
    env.AppendUnique(CCFLAGS='-pg')
    env.AppendUnique(LINKFLAGS='-pg')

if env['coverage']:
    env.Append(CCFLAGS=['--coverage', '-O0'])
    env.Append(LINKFLAGS='--coverage')

# Define lists for storing library source and include files.
env['lib_includes'] = []
env['lib_sources'] = []
env['lib_datafiles'] = []

# Subsidiary SConscripts -----------------------------------------------------

# Determine if unit tests need to be built.
build_tests = set(('test', 'alltests')).intersection(COMMAND_LINE_TARGETS)

# Short circuit if we test an already installed library.  Do not define
# any further targets as they may conflict with the installed files.
if build_tests and env['test_installed']:
    SConscript('tests/SConscript')
    Return()

# Load the version script first to resolve the majorminor tuple
SConscript('diffpy/SConscript.version')

# Path where datafiles should be installed
env['runtimepath'] = os.path.join(
        env['datadir'], 'diffpy/libdiffpy-%i.%i' % env['majorminor'])
SConscript('runtime/SConscript')

# Load all other sconscripts that update lib_includes and lib_sources
SConscript('diffpy/SConscript')

# Define sdist target for creating source distribution bundle
# Do so only if required to avoid extra git executions.
# Note: See .gitattributes for files excluded from sdist.
if 'sdist' in COMMAND_LINE_TARGETS:
    SConscript('SConscript.sdist')

# Top Level Targets ----------------------------------------------------------

# lib -- shared library object
libdiffpy = env.SharedLibrary('diffpy', env['lib_sources'])
Export('libdiffpy')
lib = Alias('lib', [libdiffpy, env['lib_includes']])
Default(lib)

# Define targets related to testing.  Do so only when testing is requested.
# This enables library build on machines without cxxtest.
if build_tests:
    assert not env['test_installed']
    SConscript('tests/SConscript')

# Installation targets.

prefix = env['prefix']

# install-lib
libinstall = env.Install(env['libdir'], libdiffpy)
if env['PLATFORM'] == 'darwin':
    # DARWIN_INSTALL_NAME can be pre-set in sconscript.local
    env.SetDefault(DARWIN_INSTALL_NAME='$TARGET.abspath')
    env.AddPostAction(libinstall,
            'install_name_tool -id $DARWIN_INSTALL_NAME $TARGET')
if env['PLATFORM'] == 'posix' and WhereIs('ldconfig'):
    opts = ''
    if os.getuid() != 0:  opts = '-n'
    env.AddPostAction(libinstall,
            'ldconfig %s $TARGET.dir' % opts)
Alias('install-lib', libinstall)

# install-includes
ninc = len(Dir('.').path) + 1
inc_target_path = lambda f: os.path.join(env['includedir'], f.path[ninc:])
include_targets = map(inc_target_path, env['lib_includes'])
Alias('install-include', InstallAs(include_targets, env['lib_includes']))

# install-data
nrt = len(Dir('runtime').path) + 1
data_target_path = lambda f: os.path.join(env['runtimepath'], f.path[nrt:])
data_targets = map(data_target_path, env['lib_datafiles'])
Alias('install-data', InstallAs(data_targets, env['lib_datafiles']))

# install
Alias('install', ['install-lib', 'install-include', 'install-data'])

# vim: ft=python
