Merge remote-tracking branch 'base/master' into develop
Conflicts: .gitignore SConstruct src/SConscript test/SConscript
This commit is contained in:
commit
391251940b
45 changed files with 32192 additions and 100 deletions
253
SConstruct
253
SConstruct
|
@ -1,8 +1,5 @@
|
|||
# SConstruct
|
||||
# vim: set ft=python:
|
||||
#
|
||||
# Toplevel Scons build script for the Charles project.
|
||||
#
|
||||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
|
||||
|
@ -10,89 +7,199 @@
|
|||
# DEFAULT CONFIGURATION VALUES
|
||||
#
|
||||
|
||||
# Enabling debugging does the following things:
|
||||
# 1. Turns on debugging symbols
|
||||
# 2. Turns off all optimization
|
||||
# 3. Sets the DEBUG define
|
||||
DEBUG = True
|
||||
# Settings for the default toolchain binaries. Setting these overrides the
|
||||
# defaults, provided your the given binary exists.
|
||||
CC = None
|
||||
CXX = None
|
||||
AS = None
|
||||
LINK = 'clang++'
|
||||
|
||||
# Show build commands ("cc [args] -o [out] [file], etc"). If this is False, show
|
||||
# some nice messages for each step of the build.
|
||||
BUILD_CMDS = False
|
||||
CCFLAGS = ['-Wall', '-Wextra', '-pedantic']
|
||||
|
||||
# Library directories. Where should scons look for .a files during linking?
|
||||
lib_directories = Split("""
|
||||
/usr/local/lib
|
||||
""")
|
||||
|
||||
# Source directories. New directories should contain a SConscript file and be
|
||||
# added here.
|
||||
source_directories = lib_directories + Split("""
|
||||
#src
|
||||
#test
|
||||
""")
|
||||
|
||||
# Include directories. Where should scons look for headers during preprocessing
|
||||
# and compiling?
|
||||
include_directories = Split("""
|
||||
/usr/local/include
|
||||
#src
|
||||
""")
|
||||
|
||||
#
|
||||
# BUILD STUFF BELOW HERE
|
||||
#
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
cflags='-Wall -fcolor-diagnostics'
|
||||
env = Environment(CC='clang', CXX='clang++',
|
||||
CFLAGS=cflags + ' -std=c99',
|
||||
CXXFLAGS=cflags + ' -std=c++11',
|
||||
CPPPATH=include_directories,
|
||||
LIBS=['png'],
|
||||
LIBPATH=lib_directories)
|
||||
import sys
|
||||
import SCons.Errors
|
||||
|
||||
|
||||
# Handle command line variables
|
||||
DEBUG = bool(int(ARGUMENTS.get('DEBUG', DEBUG)))
|
||||
if DEBUG:
|
||||
debug_flags=' -g -O0'
|
||||
env.Append(CFLAGS=debug_flags, CXXFLAGS=debug_flags)
|
||||
env.Append(CPPDEFINES=['DEBUG'])
|
||||
else:
|
||||
flags = ' -O2'
|
||||
env.Append(CFLAGS=flags, CXXFLAGS=flags)
|
||||
def which(program):
|
||||
def is_executable(path):
|
||||
return os.path.exists(path) and os.access(path, os.X_OK)
|
||||
|
||||
BUILD_CMDS = bool(int(ARGUMENTS.get('BUILD_CMDS', BUILD_CMDS)))
|
||||
if not BUILD_CMDS:
|
||||
path, name = os.path.split(program)
|
||||
if path:
|
||||
if is_executable(program):
|
||||
return program
|
||||
else:
|
||||
pathext = [''] + os.environ.get('PATHEXT', '').split(os.pathsep)
|
||||
for path in os.environ.get('PATH', '').split(os.pathsep):
|
||||
exe = os.path.join(path, program)
|
||||
for ext in pathext:
|
||||
candidate = exe + ext
|
||||
if is_executable(candidate):
|
||||
return candidate
|
||||
return None
|
||||
|
||||
|
||||
def get_bool_argument(arg):
|
||||
try:
|
||||
return bool(int(arg))
|
||||
except ValueError:
|
||||
pass
|
||||
if arg in ('False', 'FALSE', 'false', ''):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def set_toolchain_binary(env, var, user_binary, binaries=()):
|
||||
if user_binary and which(user_binary):
|
||||
env[var] = user_binary
|
||||
return
|
||||
for c in binaries:
|
||||
if which(c):
|
||||
env[var] = c
|
||||
break
|
||||
|
||||
common_env = Environment()
|
||||
set_toolchain_binary(common_env, 'CC', CC, ('clang', 'gcc'))
|
||||
set_toolchain_binary(common_env, 'CXX', CXX, ('clang++', 'g++'))
|
||||
set_toolchain_binary(common_env, 'AS', AS)
|
||||
set_toolchain_binary(common_env, 'LINK', LINK)
|
||||
|
||||
|
||||
def verbose_build_cmds():
|
||||
def generate_comstr(action):
|
||||
return '%18s: $TARGET' % (action,)
|
||||
env['CCCOMSTR'] = generate_comstr('Building (C)'),
|
||||
env['CXXCOMSTR'] = generate_comstr('Building (C++)'),
|
||||
env['LINKCOMSTR'] = generate_comstr('Linking'),
|
||||
env['ARCOMSTR'] = generate_comstr('Archiving'),
|
||||
env['RANLIBCOMSTR'] = generate_comstr('Indexing')
|
||||
return '{:>25}: $TARGET'.format(action)
|
||||
common_env['ARCOMSTR'] = generate_comstr('Archiving')
|
||||
common_env['ASCOMSTR'] = generate_comstr('Assembling')
|
||||
common_env['ASPPCOMSTR'] = generate_comstr('Assembling')
|
||||
common_env['CCCOMSTR'] = generate_comstr('Building (C)')
|
||||
common_env['CXXCOMSTR'] = generate_comstr('Building (C++)')
|
||||
common_env['LINKCOMSTR'] = generate_comstr('Linking')
|
||||
common_env['RANLIBCOMSTR'] = generate_comstr('Indexing')
|
||||
common_env['SHCCCOMSTR'] = generate_comstr('Building (C, Shared)')
|
||||
common_env['SHCXXCOMSTR'] = generate_comstr('Building (C++, Shared)')
|
||||
common_env['SHLINKCOMSTR'] = generate_comstr('Linking (Shared)')
|
||||
|
||||
|
||||
# Build charles
|
||||
src_dir = Dir('#src')
|
||||
charles_lib = env.SConscript(os.path.join(src_dir.path, 'SConscript'),
|
||||
exports=['env'],
|
||||
variant_dir=os.path.join('build', src_dir.path),
|
||||
duplicate=0)
|
||||
def succinct_build_cmds():
|
||||
def generate_comstr(action):
|
||||
return ' [{:^6}] $TARGET'.format(action)
|
||||
common_env['ARCOMSTR'] = generate_comstr('AR')
|
||||
common_env['ASCOMSTR'] = generate_comstr('AS')
|
||||
common_env['ASPPCOMSTR'] = generate_comstr('AS')
|
||||
common_env['CCCOMSTR'] = generate_comstr('CC')
|
||||
common_env['CXXCOMSTR'] = generate_comstr('CXX')
|
||||
common_env['LINKCOMSTR'] = generate_comstr('LINK')
|
||||
common_env['RANLIBCOMSTR'] = generate_comstr('RANLIB')
|
||||
common_env['SHCCCOMSTR'] = generate_comstr('SHCC')
|
||||
common_env['SHCXXCOMSTR'] = generate_comstr('SHCXX')
|
||||
common_env['SHLINKCOMSTR'] = generate_comstr('SHLINK')
|
||||
|
||||
# Build test
|
||||
gtest_dir = Dir('#gtest')
|
||||
gtest_include_dir = Dir('#gtest/include')
|
||||
gtest = env.SConscript(os.path.join(gtest_dir.path, 'SConscript'),
|
||||
exports=['env'],
|
||||
variant_dir=os.path.join('build', gtest_dir.path),
|
||||
duplicate=0)
|
||||
test_dir = Dir('#test')
|
||||
env.SConscript(os.path.join(test_dir.path, 'SConscript'),
|
||||
exports=['env', 'gtest', 'gtest_include_dir', 'charles_lib'],
|
||||
variant_dir=os.path.join('build', test_dir.path),
|
||||
duplicate=0)
|
||||
|
||||
env.Default('charles')
|
||||
BUILD_CMDS = get_bool_argument(ARGUMENTS.get('BUILD_CMDS', False))
|
||||
if not BUILD_CMDS:
|
||||
verbose_build_cmds()
|
||||
|
||||
# Separate environment for building libraries because they often don't use the
|
||||
# same CCFLAGS I do.
|
||||
lib_env = common_env.Clone()
|
||||
|
||||
common_env.Append(CCFLAGS=CCFLAGS)
|
||||
common_env.Append(CFLAGS=['-std=c99'])
|
||||
common_env.Append(CXXFLAGS=['-std=c++11'])
|
||||
|
||||
# Add color error messages for clang
|
||||
if sys.stdout.isatty():
|
||||
if 'clang' in common_env['CC'] or 'clang' in common_env['CXX']:
|
||||
common_env.Append(CCFLAGS=['-fcolor-diagnostics'])
|
||||
|
||||
BUILD_DIR = Dir('#build')
|
||||
LIB_DIR = Dir('#lib')
|
||||
SRC_DIR = Dir('#src')
|
||||
TEST_DIR = Dir('#test')
|
||||
|
||||
|
||||
def create_env(name, appends=None):
|
||||
output_dir = BUILD_DIR.Dir(name)
|
||||
env = common_env.Clone()
|
||||
# Standard env extensions.
|
||||
env.Append(CPPPATH=[SRC_DIR])
|
||||
# Custom env stuff.
|
||||
env['__name'] = name
|
||||
if appends:
|
||||
for k, v in appends.iteritems():
|
||||
if k.startswith('='):
|
||||
env[k[1:]] = v
|
||||
else:
|
||||
env.Append(**{k: v})
|
||||
return env
|
||||
|
||||
|
||||
def do_sconscript(env, build_env, src_dir, out_dir):
|
||||
sconscript = src_dir.File('SConscript')
|
||||
print 'Reading {}'.format(sconscript)
|
||||
env.SConscript(sconscript,
|
||||
{'env': build_env},
|
||||
variant_dir=out_dir)
|
||||
|
||||
|
||||
debug_env = create_env('debug', {
|
||||
'CPPDEFINES': ['NDEBUG'],
|
||||
'CCFLAGS': ['-O0', '-g'],
|
||||
})
|
||||
|
||||
beta_env = create_env('beta', {
|
||||
'CPPDEFINES': ['NDEBUG'],
|
||||
'CCFLAGS': ['-O3', '-g'],
|
||||
})
|
||||
|
||||
release_env = create_env('release', {
|
||||
'CPPDEFINES': ['NRELEASE'],
|
||||
'CCFLAGS': ['-O2']
|
||||
})
|
||||
|
||||
|
||||
modes = {
|
||||
'debug': debug_env,
|
||||
'beta': beta_env,
|
||||
'release': release_env,
|
||||
}
|
||||
|
||||
mode = ARGUMENTS.get('MODE', None)
|
||||
build_modes = []
|
||||
if mode:
|
||||
# If MODE=foo is specified, build only that mode.
|
||||
build_modes.append(mode)
|
||||
else:
|
||||
build_modes = ['debug']
|
||||
|
||||
for mode in build_modes:
|
||||
try:
|
||||
env = modes[mode]
|
||||
except KeyError:
|
||||
print 'Skipping invalid mode: {}'.format(mode)
|
||||
break
|
||||
|
||||
out_dir = BUILD_DIR.Dir(env['__name'])
|
||||
|
||||
# Process all lib dirs.
|
||||
for lib in os.listdir(LIB_DIR.abspath):
|
||||
lib_out_dir = out_dir.Dir('lib').Dir(lib)
|
||||
if not os.path.isdir(lib_out_dir.abspath):
|
||||
continue
|
||||
do_sconscript(env, lib_env, LIB_DIR.Dir(lib), lib_out_dir)
|
||||
env.Append(LIBPATH=[lib_out_dir])
|
||||
|
||||
# Get source files.
|
||||
src_out_dir = out_dir.Dir('src')
|
||||
do_sconscript(env, env, SRC_DIR, src_out_dir)
|
||||
env.Append(LIBPATH=[src_out_dir])
|
||||
|
||||
# Get test binaries.
|
||||
do_sconscript(env, env, TEST_DIR, out_dir.Dir('test'))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue