"""winddk

Tool-specific initialization for Microsoft Windows DDK.

Based on engine.SCons.Tool.msvc.

There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.

"""

#
# Copyright (c) 2001-2007 The SCons Foundation
# Copyright (c) 2008 Tungsten Graphics, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

import os.path
import re
import string

import SCons.Action
import SCons.Builder
import SCons.Errors
import SCons.Platform.win32
import SCons.Tool
import SCons.Tool.mslib
import SCons.Tool.mslink
import SCons.Util
import SCons.Warnings

CSuffixes = ['.c', '.C']
CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']

def get_winddk_paths(env, version=None):
    """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
    of those three environment variables that should be set
    in order to execute the MSVC tools properly."""
    
    WINDDKdir = None
    exe_paths = []
    lib_paths = []
    include_paths = []

    if 'BASEDIR' in os.environ:
        WINDDKdir = os.environ['BASEDIR']
    else:
        WINDDKdir = "C:\\WINDDK\\3790.1830"

    exe_paths.append( os.path.join(WINDDKdir, 'bin') )
    exe_paths.append( os.path.join(WINDDKdir, 'bin', 'x86') )
    include_paths.append( os.path.join(WINDDKdir, 'inc', 'wxp') )
    lib_paths.append( os.path.join(WINDDKdir, 'lib') )

    target_os = 'wxp'
    target_cpu = 'i386'
    
    env['SDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', target_os) 
    env['CRT_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'crt') 
    env['DDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', target_os) 
    env['WDM_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', 'wdm', target_os) 

    env['SDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) 
    env['CRT_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', 'crt', target_cpu) 
    env['DDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
    env['WDM_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
                                     
    include_path = string.join( include_paths, os.pathsep )
    lib_path = string.join(lib_paths, os.pathsep )
    exe_path = string.join(exe_paths, os.pathsep )
    return (include_path, lib_path, exe_path)

def set_winddk_flags(env):
    """Mimic WINDDK's builtin flags.

    See also:
    - WINDDK's bin/makefile.new i386mk.inc for more info.
    - buildchk_wxp_x86.log files, generated by the WINDDK's build
    - http://alter.org.ua/docs/nt_kernel/vc8_proj/
    """
    
    cppdefines = [
        ('_X86_', '1'), 
        ('i386', '1'), 
        'STD_CALL', 
        ('CONDITION_HANDLING', '1'),
        ('NT_INST', '0'), 
        ('WIN32', '100'),
        ('_NT1X_', '100'),
        ('WINNT', '1'),
        ('_WIN32_WINNT', '0x0501'), # minimum required OS version
        ('WINVER', '0x0501'),
        ('_WIN32_IE', '0x0603'),
        ('WIN32_LEAN_AND_MEAN', '1'),
        ('DEVL', '1'),
        ('__BUILDMACHINE__', 'WinDDK'),
        ('FPO', '0'),
    ]
    if env.get('DEBUG', False):
         cppdefines += [
              ('DBG', 1),
         ]
    env.Append(CPPDEFINES = cppdefines)

    # See also:
    # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
    # - cl /?
    cflags = [
        '/Zl', # omit default library name in .OBJ
        '/Zp8', # 8bytes struct member alignment
        '/Gy', # separate functions for linker
        '/Gm-', # disable minimal rebuild
        '/W3', # warning level
        '/WX', # treat warnings as errors
        '/Gz', # __stdcall Calling convention
        '/GX-', # disable C++ EH
        '/GR-', # disable C++ RTTI
        '/GF', # enable read-only string pooling
        '/GS', # enable security checks
        '/G6', # optimize for PPro, P-II, P-III
        '/Ze', # enable extensions
        #'/Gi-', # ???
        '/QIfdiv-', # disable Pentium FDIV fix
        #'/hotpatch', # ???
        #'/Z7', #enable old-style debug info
    ]
    if env.get('debug', False):
        cflags += [
          '/Od', # disable optimizations
          '/Oi', # enable intrinsic functions
          '/Oy-', # disable frame pointer omission
        ]
    else:
        cflags += [
          '/Ox', # maximum optimizations
          '/Oi', # enable intrinsic functions
          '/Os', # favor code space
        ]
    env.Append(CFLAGS = cflags)
    env.Append(CXXFLAGS = cflags)
    
    # See also:
    # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
    env.Append(LINKFLAGS = [
        '/merge:_PAGE=PAGE',
        '/merge:_TEXT=.text',
        '/section:INIT,d',
        '/opt:ref',
        '/opt:icf',
        '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221',
        '/incremental:no',
        '/fullbuild',
        '/release',
        '/nodefaultlib',
        '/wx',
        '/debug',
        '/debugtype:cv',
        '/version:5.1',
        '/osversion:5.1',
        '/functionpadmin:5',
        '/safeseh',
        '/pdbcompress',
        '/stack:0x40000,0x1000',
        '/driver', 
        '/align:0x80',
        '/subsystem:native,5.01',
        '/base:0x10000',
        
        '/entry:DrvEnableDriver',
    ])

def validate_vars(env):
    """Validate the PCH and PCHSTOP construction variables."""
    if env.has_key('PCH') and env['PCH']:
        if not env.has_key('PCHSTOP'):
            raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
        if not SCons.Util.is_String(env['PCHSTOP']):
            raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']

def pch_emitter(target, source, env):
    """Adds the object file target."""

    validate_vars(env)

    pch = None
    obj = None

    for t in target:
        if SCons.Util.splitext(str(t))[1] == '.pch':
            pch = t
        if SCons.Util.splitext(str(t))[1] == '.obj':
            obj = t

    if not obj:
        obj = SCons.Util.splitext(str(pch))[0]+'.obj'

    target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work

    return (target, source)

def object_emitter(target, source, env, parent_emitter):
    """Sets up the PCH dependencies for an object file."""

    validate_vars(env)

    parent_emitter(target, source, env)

    if env.has_key('PCH') and env['PCH']:
        env.Depends(target, env['PCH'])

    return (target, source)

def static_object_emitter(target, source, env):
    return object_emitter(target, source, env,
                          SCons.Defaults.StaticObjectEmitter)

def shared_object_emitter(target, source, env):
    return object_emitter(target, source, env,
                          SCons.Defaults.SharedObjectEmitter)

pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')
pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
                                    emitter=pch_emitter,
                                    source_scanner=SCons.Tool.SourceFileScanner)
res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
res_builder = SCons.Builder.Builder(action=res_action,
                                    src_suffix='.rc',
                                    suffix='.res',
                                    src_builder=[],
                                    source_scanner=SCons.Tool.SourceFileScanner)
SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan)

def generate(env):
    """Add Builders and construction variables for MSVC++ to an Environment."""
    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)

    for suffix in CSuffixes:
        static_obj.add_action(suffix, SCons.Defaults.CAction)
        shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
        static_obj.add_emitter(suffix, static_object_emitter)
        shared_obj.add_emitter(suffix, shared_object_emitter)

    for suffix in CXXSuffixes:
        static_obj.add_action(suffix, SCons.Defaults.CXXAction)
        shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
        static_obj.add_emitter(suffix, static_object_emitter)
        shared_obj.add_emitter(suffix, shared_object_emitter)

    env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
    env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
    env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS'
    env['CC']         = 'cl'
    env['CCFLAGS']    = SCons.Util.CLVar('/nologo')
    env['CFLAGS']     = SCons.Util.CLVar('')
    env['CCCOM']      = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS'
    env['SHCC']       = '$CC'
    env['SHCCFLAGS']  = SCons.Util.CLVar('$CCFLAGS')
    env['SHCFLAGS']   = SCons.Util.CLVar('$CFLAGS')
    env['SHCCCOM']    = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS'
    env['CXX']        = '$CC'
    env['CXXFLAGS']   = SCons.Util.CLVar('$CCFLAGS $( /TP $)')
    env['CXXCOM']     = '$CXX $CXXFLAGS $CCCOMFLAGS'
    env['SHCXX']      = '$CXX'
    env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
    env['SHCXXCOM']   = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS'
    env['CPPDEFPREFIX']  = '/D'
    env['CPPDEFSUFFIX']  = ''
    env['INCPREFIX']  = '/I'
    env['INCSUFFIX']  = ''
#    env.Append(OBJEMITTER = [static_object_emitter])
#    env.Append(SHOBJEMITTER = [shared_object_emitter])
    env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1

    env['RC'] = 'rc'
    env['RCFLAGS'] = SCons.Util.CLVar('')
    env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
    env['BUILDERS']['RES'] = res_builder
    env['OBJPREFIX']      = ''
    env['OBJSUFFIX']      = '.obj'
    env['SHOBJPREFIX']    = '$OBJPREFIX'
    env['SHOBJSUFFIX']    = '$OBJSUFFIX'

    env['CFILESUFFIX'] = '.c'
    env['CXXFILESUFFIX'] = '.cc'

    env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
    env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
    env['BUILDERS']['PCH'] = pch_builder

    env['AR']          = 'lib'
    env['ARFLAGS']     = SCons.Util.CLVar('/nologo')
    env['ARCOM']       = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
    env['LIBPREFIX']   = ''
    env['LIBSUFFIX']   = '.lib'

    SCons.Tool.mslink.generate(env)

    set_winddk_flags(env)
    
    if not env.has_key('ENV'):
        env['ENV'] = {}
    
    try:
        include_path, lib_path, exe_path = get_winddk_paths(env)

        # since other tools can set these, we just make sure that the
        # relevant stuff from WINDDK is in there somewhere.
        env.PrependENVPath('INCLUDE', include_path)
        env.PrependENVPath('LIB', lib_path)
        env.PrependENVPath('PATH', exe_path)
    except (SCons.Util.RegError, SCons.Errors.InternalError):
        pass


def exists(env):
    return env.Detect('cl')

# vim:set sw=4 et:
