#! /usr/bin/env python
# encoding: utf-8

from __future__ import with_statement
import re, os
import Options, Constants

llvm_version_regex = re.compile('LLVM_VERSION=(\d)\.(\d)')

VERSION = '0.0.1'
APPNAME = 'sigdump'

srcdir = '.'
blddir = '.build'

def get_llvm_version():
    with open('llvm-versions.sh') as f:
        c = f.read()
        md = llvm_version_regex.search(c)
        return (int(md.group(1)), int(md.group(2)))

def init():
    pass

def set_options(opt):
    opt.tool_options('boost')

    # Default LLVM prefix is the directory with the waf script
    opt.add_option('--llvm-prefix', type='string', default=os.getcwd(), dest='llvmprefix', help='Root under which LLVM is installed.  Defaults to the local install.')

    # This is the directory Guile will search for its scripts to load
    opt.add_option('--scheme-libdir', type='string', default=("%s/share/sigdump/scheme" % os.getcwd()), dest='schemelibdir', help='Directory where the Scheme libraries for the analysis reside.')

    # This is the directory that the signature dumper will consult to look up external library dependencies
    opt.add_option('--dependency-libdir', type='string', default=("%s/share/sigdump/dependencies" % os.getcwd()), dest='dependencylibdir', help='Directory in which library dependencies will be resolved.')

def configure(conf):
    # Set default CXX flags
    # One LLVM header requires the __STDC_LIMIT_MACROS define
    conf.env['CXXFLAGS'] = ['-O2', '-D__STDC_LIMIT_MACROS', '-D_GNU_SOURCE']

    # Force the LLVM include and libpaths into the build flags
    llvm_include = "%s/include" % Options.options.llvmprefix
    llvm_lib = "%s/lib" % Options.options.llvmprefix
    conf.env.append_value('CPPPATH', llvm_include)
    conf.env.append_value('LIBPATH', llvm_lib)

    # Check for Boost/c++ support
    conf.check_tool('gcc g++ boost misc')
    conf.check_boost(lib=['regex'], score_version=(-1000,1000), tag_minscore=1000,mandatory=True)

    # See if we have guile available (using pkg-config)
    conf.check_cfg(atleast_pkgconfig_version='0.0.0')
    conf.check_cfg(package='guile-1.8', uselib_store='GUILE', args='--cflags --libs')

    # Check for LLVM
    conf.check_cxx(fragment='''
#include <llvm/System/TimeValue.h>
using namespace llvm;
int main(int argc, char** argv)
{
  sys::TimeValue tv(0.0);
  return 0;
}
''',
                   execute=1,
                   mandatory=1,
                   lib='LLVMSystem',
                   msg='Checking for LLVM libraries')

    # Check LLVM version
    (major, minor) = get_llvm_version()
    conf.check_cxx(fragment=('''
#include <llvm/Config/config.h>
#include <string.h>
int main(int arg, char** argv)
{
  return strcmp("%d.%d", PACKAGE_VERSION);
}
''' % (major,minor)),
                   execute=1,
                   mandatory=1,
                   msg=("Checking for required LLVM version (%d.%d)" % (major,minor)))


def build(bld):
    scc = bld.new_task_gen(
        features = 'subst',
        source = 'bin/scc.in',
        target = 'bin/scc',
        chmod = Constants.O755,
        install_path = '${PREFIX}/bin')
    scc.env.table.update({'PREFIX': bld.env['PREFIX']})

    ctypes_codegen = bld.new_task_gen(
        features = 'subst',
        source = 'bin/ctypes-generator.in',
        target = 'bin/ctypes-generator',
        chmod = Constants.O755,
        install_path = '${PREFIX}/bin')
    ctypes_codegen.env.table.update({'PREFIX': bld.env['PREFIX']})

    bld.add_subdirs([
            'src/clang',
            'src'
            ])

def shutdown():
    pass
