blob: 6de181739bab0baf1c47566d43eef516cbdc98e0 [file] [log] [blame]
#######################################################################
# Common SCons code
import os
import os.path
import sys
import platform as _platform
#######################################################################
# Defaults
_platform_map = {
'linux2': 'linux',
'win32': 'winddk',
}
default_platform = sys.platform
default_platform = _platform_map.get(default_platform, default_platform)
_machine_map = {
'x86': 'x86',
'i386': 'x86',
'i486': 'x86',
'i586': 'x86',
'i686': 'x86',
'x86_64': 'x86_64',
}
if 'PROCESSOR_ARCHITECTURE' in os.environ:
default_machine = os.environ['PROCESSOR_ARCHITECTURE']
else:
default_machine = _platform.machine()
default_machine = _machine_map.get(default_machine, 'generic')
if default_platform in ('linux', 'freebsd', 'darwin'):
default_dri = 'yes'
elif default_platform in ('winddk', 'windows'):
default_dri = 'no'
else:
default_dri = 'no'
#######################################################################
# Common options
def AddOptions(opts):
try:
from SCons.Options.BoolOption import BoolOption
except ImportError:
from SCons.Variables.BoolVariable import BoolVariable as BoolOption
try:
from SCons.Options.EnumOption import EnumOption
except ImportError:
from SCons.Variables.EnumVariable import EnumVariable as EnumOption
opts.Add(BoolOption('debug', 'build debug version', 'no'))
#opts.Add(BoolOption('quiet', 'quiet command lines', 'no'))
opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine,
allowed_values=('generic', 'x86', 'x86_64')))
opts.Add(EnumOption('platform', 'target platform', default_platform,
allowed_values=('linux', 'cell', 'windows', 'winddk')))
opts.Add(BoolOption('llvm', 'use LLVM', 'no'))
opts.Add(BoolOption('dri', 'build DRI drivers', default_dri))
#######################################################################
# Quiet command lines
#
# See also http://www.scons.org/wiki/HidingCommandLinesInOutput
def quietCommandLines(env):
env['CCCOMSTR'] = "Compiling $SOURCE ..."
env['CXXCOMSTR'] = "Compiling $SOURCE ..."
env['ARCOMSTR'] = "Archiving $TARGET ..."
env['RANLIBCOMSTR'] = ""
env['LINKCOMSTR'] = "Linking $TARGET ..."
#######################################################################
# Convenience Library Builder
# based on the stock StaticLibrary and SharedLibrary builders
import SCons.Action
import SCons.Builder
def createConvenienceLibBuilder(env):
"""This is a utility function that creates the ConvenienceLibrary
Builder in an Environment if it is not there already.
If it is already there, we return the existing one.
"""
try:
convenience_lib = env['BUILDERS']['ConvenienceLibrary']
except KeyError:
action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
if env.Detect('ranlib'):
ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
action_list.append(ranlib_action)
convenience_lib = SCons.Builder.Builder(action = action_list,
emitter = '$LIBEMITTER',
prefix = '$LIBPREFIX',
suffix = '$LIBSUFFIX',
src_suffix = '$SHOBJSUFFIX',
src_builder = 'SharedObject')
env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
env['BUILDERS']['Library'] = convenience_lib
return convenience_lib
#######################################################################
# Build
def make_build_dir(env):
# Put build output in a separate dir, which depends on the current configuration
# See also http://www.scons.org/wiki/AdvancedBuildExample
build_topdir = 'build'
build_subdir = env['platform']
if env['dri']:
build_subdir += "-dri"
if env['llvm']:
build_subdir += "-llvm"
if env['machine'] != 'generic':
build_subdir += '-' + env['machine']
if env['debug']:
build_subdir += "-debug"
build_dir = os.path.join(build_topdir, build_subdir)
# Place the .sconsign file on the builddir too, to avoid issues with different scons
# versions building the same source file
env.SConsignFile(os.path.join(build_dir, '.sconsign'))
return build_dir
#######################################################################
# Common environment generation code
def generate(env):
# FIXME: this is already too late
#if env.get('quiet', False):
# quietCommandLines(env)
# shortcuts
debug = env['debug']
machine = env['machine']
platform = env['platform']
x86 = env['machine'] == 'x86'
gcc = env['platform'] in ('linux', 'freebsd', 'darwin')
msvc = env['platform'] in ('windows', 'winddk')
# C preprocessor options
cppdefines = []
if debug:
cppdefines += ['DEBUG']
else:
cppdefines += ['NDEBUG']
if platform == 'windows':
cppdefines += [
'WIN32',
'_WINDOWS',
'_UNICODE',
'UNICODE',
# http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
'WIN32_LEAN_AND_MEAN',
'VC_EXTRALEAN',
'_CRT_SECURE_NO_DEPRECATE',
]
if debug:
cppdefines += ['_DEBUG']
if platform == 'winddk':
# 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 debug:
cppdefines += [('DBG', 1)]
if platform == 'windows':
cppdefines += ['PIPE_SUBSYSTEM_USER']
if platform == 'winddk':
cppdefines += ['PIPE_SUBSYSTEM_KERNEL']
env.Append(CPPDEFINES = cppdefines)
# C compiler options
cflags = []
if gcc:
if debug:
cflags += ['-O0', '-g3']
else:
cflags += ['-O3', '-g3']
cflags += [
'-Wall',
'-Wmissing-prototypes',
'-Wno-long-long',
'-ffast-math',
'-pedantic',
'-fmessage-length=0', # be nice to Eclipse
]
if msvc:
# See also:
# - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
# - cl /?
if debug:
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
]
if platform == 'windows':
cflags += [
# TODO
#'/Wp64', # enable 64 bit porting warnings
]
if platform == 'winddk':
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
]
# Put debugging information in a separate .pdb file for each object file as
# descrived in the scons manpage
env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
env.Append(CFLAGS = cflags)
env.Append(CXXFLAGS = cflags)
# Linker options
if platform == 'winddk':
# 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',
])
createConvenienceLibBuilder(env)
# for debugging
#print env.Dump()