Created
September 22, 2011 07:14
-
-
Save ringods/1234232 to your computer and use it in GitHub Desktop.
Build setup (added .py extension to SConstruct/SConscript for gist to detect Python code, full path on first line of content)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# thirdparty/site_scons/site_tools/AutoConfig.py | |
# AutoConfig Builder: Runs ./configure inside a directory. | |
# This builder takes over the compile and linker flags from the following SCons settings. | |
# Set all required flags on the environment before calling the builder. | |
# - CFLAGS | |
# - CCFLAGS | |
# - CPPFLAGS | |
# - CXXFLAGS | |
# - LINKFLAGS | |
# | |
# Variables: | |
# CONFIGURE_FLAGS -- Sequence of parameter strings to include on the | |
# configure command line. | |
# Default: [ ] | |
# CONFIGURE_BUILDDIR -- The location where generated files will be put. | |
# Default: 'build' | |
# CONFIGURE_BUILDVARIANT -- An optional part to the build dir to separate build variants from each other | |
# Default: '' | |
# CONFIGURE_PREFIX -- The location that will be used by the Make builder for the install target | |
# Default: '' | |
# CONFIGURE_COMSTR -- Parameterized string to use for displaying the invoked command. | |
# Default: None | |
import subprocess | |
import SCons.Util | |
from SCons.Script import * | |
def __expand_paths(target, source, env): | |
""" | |
Expand the paths to be used by the emitter | |
""" | |
configure_path = Dir('.') | |
if len(source) > 0: | |
configure_path = source[0] | |
# Calculating the directory in which to run the configure script. | |
if 'CONFIGURE_BUILDDIR' in env: | |
configure_builddir = configure_path.Dir(str(env['CONFIGURE_BUILDDIR'])) | |
if 'CONFIGURE_BUILDVARIANT' in env: | |
if env['CONFIGURE_BUILDVARIANT']: | |
configure_builddir = configure_builddir.Dir(str(env['CONFIGURE_BUILDVARIANT'])) | |
#print '__expand_paths(target,source,env) returns:' | |
#print 'configure_path = %s' % configure_path.abspath | |
#print 'configure_builddir = %s' % configure_builddir.abspath | |
return (configure_path, configure_builddir) | |
def emitter(target, source, env): | |
(configure_path, | |
configure_builddir) = __expand_paths(target, source, env) | |
# Make sure there's a directory to run configure in | |
if configure_path and not os.path.exists(configure_path.abspath): | |
print 'Path %s not found' % configure_path | |
new_targets = [configure_builddir.File('Makefile'), | |
configure_builddir.File('config.log'), | |
configure_builddir.File('config.status'), | |
configure_builddir.File('libtool')] | |
new_sources = [configure_path.File(env['CONFIGURE']), | |
configure_path.File('Makefile.in')] | |
env.Clean(new_targets,configure_builddir) | |
return (new_targets, | |
new_sources) | |
def parms(target, source, env): | |
""" | |
Assemble various ./configure parameters. | |
""" | |
# We now receive the transformed sources and targets calculated by the emitter. | |
# configure_cmd is the File node pointing to the configure script | |
configure_cmd = source[0] | |
# configure path is the parent folder of the configure script | |
configure_path = Dir(os.path.dirname(configure_cmd.abspath)) | |
# Calculating the directory in which to run the configure script. | |
if 'CONFIGURE_BUILDDIR' in env: | |
configure_builddir = configure_path.Dir(str(env['CONFIGURE_BUILDDIR'])) | |
if 'CONFIGURE_BUILDVARIANT' in env: | |
if env['CONFIGURE_BUILDVARIANT']: | |
configure_builddir = configure_builddir.Dir(str(env['CONFIGURE_BUILDVARIANT'])) | |
configure_opts = None | |
if 'CONFIGURE_FLAGS' in env.Dictionary().keys(): | |
configure_opts = env.subst(env['CONFIGURE_FLAGS']) | |
if 'CONFIGURE_PREFIX' in env.Dictionary().keys(): | |
if env['CONFIGURE_PREFIX']: | |
configure_opts.append('--prefix=%s' % env.Dir(env['CONFIGURE_PREFIX']).abspath) | |
print 'params(target,source,env) returns:' | |
#print 'configure_builddir = %s' % configure_builddir.abspath | |
#print 'configure_cmd = %s' % configure_cmd.abspath | |
print 'configure_opts = %s' % configure_opts | |
return (configure_builddir.abspath, configure_cmd.abspath, configure_opts) | |
def message(target, source, env): | |
"""Return a pretty AutoConfig message.""" | |
(configure_builddir, | |
configure_cmd, | |
configure_flags) = parms(target, source, env) | |
if 'CONFIGURE_COMSTR' in env.Dictionary().keys(): | |
return env.subst(env['CONFIGURE_COMSTR'], | |
target = target, source = source, raw = 1) | |
msg = 'cd ' + configure_builddir + ' && CFLAGS="$_CPPINCFLAGS $CCFLAGS $CFLAGS" CXXFLAGS="$_CPPINCFLAGS $CCFLAGS $CXXFLAGS" LDFLAGS="$LINKFLAGS" ' + configure_cmd | |
if configure_flags is not None: | |
msg += ' ' + ' '.join(configure_flags) | |
return env.subst(msg) | |
def builder(target, source, env): | |
"""Run configure in a directory.""" | |
(configure_builddir, | |
configure_cmd, | |
configure_opts) = parms(target, source, env) | |
# First create the builddir if it doesn't exist. | |
env.Execute(Mkdir(configure_builddir)) | |
# Build up the command and its arguments in a list | |
fullcmd = [ configure_cmd ] | |
# Environment variables passed on to the script | |
env['ENV']['CFLAGS'] = env.subst("$_CPPINCFLAGS $CCFLAGS $CFLAGS") | |
env['ENV']['CXXFLAGS'] = env.subst("$_CPPINCFLAGS $CCFLAGS $CXXFLAGS") | |
env['ENV']['LDFLAGS'] = env.subst("$LINKFLAGS") | |
# Parameters behind the configure command | |
if configure_opts: | |
fullcmd.extend(configure_opts) | |
# Capture the configure command's output, unless we're verbose | |
# ./configure | |
configure = subprocess.Popen(fullcmd, | |
cwd = configure_builddir, | |
bufsize=0, | |
stdout = subprocess.PIPE, | |
stderr = subprocess.STDOUT, | |
env = env['ENV']) | |
# We need to read the generated output or the buffers will fill up and the process hangs | |
# Do not replace this with "for line in configure.stdout" due to buffering issues. | |
# Read more here: | |
# http://stackoverflow.com/questions/1183643/unbuffered-read-from-process-using-subprocess-in-python/1183654#1183654 | |
line = configure.stdout.readline() | |
while line: | |
print line.rstrip() | |
line = configure.stdout.readline() | |
return configure.returncode | |
def generate(env, **kwargs): | |
env['BUILDERS']['AutoConfig'] = env.Builder( | |
action = env.Action(builder,message), | |
emitter = emitter, | |
source_factory = Dir) | |
env['CONFIGURE'] = 'configure' | |
env['CONFIGURE_FLAGS'] = SCons.Util.CLVar('') | |
env['CONFIGURE_BUILDDIR'] = 'build' | |
env['CONFIGURE_BUILDVARIANT'] = None | |
env['CONFIGURE_PREFIX'] = None | |
def exists(env): | |
return True |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# thirdparty/site_scons/site_tools/Make.py | |
# Make Builder: Runs make. | |
# | |
# Parameters: | |
# MakePath -- SCons Dir node representing the directory in which to run make. REQUIRED. | |
# MakeCmd -- The 'make' executable to run. | |
# Default: make | |
# MakeEnv -- Dictionary of variables to set in the make execution environment. | |
# Default: none | |
# MakeOpts -- Options to pass on the make command line. | |
# Default: none | |
# MakeOneThread -- Don't pass any -j option to make. | |
# Default: False | |
# MakeTargets -- String of space-seperated targets to pass to make | |
# Default: "" | |
import subprocess | |
from SCons.Script import * | |
def parms(target, source, env): | |
"""Assemble various Make parameters.""" | |
if 'MakePath' in env.Dictionary().keys(): | |
make_path = env.subst(str(env['MakePath'])) | |
else: | |
make_path = os.path.dirname(source[0].abspath) | |
make_cmd = 'make' | |
if 'MakeCmd' in env.Dictionary().keys(): | |
make_cmd = env.subst(env['MakeCmd']) | |
elif 'MAKE' in env.Dictionary().keys(): | |
make_cmd = env.subst(env['MAKE']) | |
make_env = None | |
if 'CROSS_BUILD' in env.Dictionary().keys(): | |
make_env = env['CROSS_ENV'] | |
if 'MakeEnv' in env.Dictionary().keys(): | |
if make_env == None: | |
make_env = {} | |
else: | |
# We're appending to an existing dictionary, so create a copy | |
# instead of appending to the original env['CROSS_ENV'] | |
make_env = env['CROSS_ENV'][:] | |
for (k,v) in env['MakeEnv'].items(): | |
make_env[k] = v | |
make_opts = None | |
if 'MakeOpts' in env.Dictionary().keys(): | |
make_opts = env.subst(env['MakeOpts']) | |
make_jobs = GetOption('num_jobs') | |
if 'MakeOneThread' in env.Dictionary().keys() and env['MakeOneThread']: | |
make_jobs = 1 | |
make_targets = None | |
if 'MakeTargets' in env.Dictionary().keys(): | |
make_targets = env.subst(env['MakeTargets']) | |
return (make_path, make_env, make_targets, make_cmd, make_jobs, make_opts) | |
def message(target, source, env): | |
"""Return a pretty Make message""" | |
(make_path, | |
make_env, | |
make_targets, | |
make_cmd, | |
make_jobs, | |
make_opts) = parms(target, source, env) | |
myenv = env.Clone() | |
# Want to use MakeTargets in the MAKECOMSTR, but make it pretty first. | |
if 'MakeTargets' in myenv.Dictionary().keys(): | |
myenv['MakeTargets'] += ' ' | |
else: | |
myenv['MakeTargets'] = '' | |
if 'MAKECOMSTR' in myenv.Dictionary().keys(): | |
return myenv.subst(myenv['MAKECOMSTR'], | |
target = target, source = source, raw = 1) | |
msg = '' | |
if make_env != None: | |
for k, v in make_env.iteritems(): | |
msg += ' ' + k + '=' + v | |
msg += ' ' + make_cmd | |
if make_path: | |
msg += ' -C ' + make_path | |
if make_jobs > 1: | |
msg += ' -j %d' % make_jobs | |
if make_opts != None: | |
msg += ' ' + ' '.join(make_opts) | |
if make_targets != None: | |
msg += ' ' + make_targets | |
return msg | |
def builder(target, source, env): | |
"""Run make in a directory.""" | |
(make_path, | |
make_env, | |
make_targets, | |
make_cmd, | |
make_jobs, | |
make_opts) = parms(target, source, env) | |
# Make sure there's a directory to run make in | |
if make_path and not os.path.exists(make_path): | |
print 'Path %s not found' % make_path | |
# Build up the command and its arguments in a list | |
fullcmd = [ make_cmd ] | |
if make_jobs > 1: | |
fullcmd += [ '-j', str(make_jobs) ] | |
if make_opts: | |
fullcmd += make_opts | |
if make_targets: | |
fullcmd += make_targets.split() | |
# Capture the make command's output, unless we're verbose | |
real_stdout = subprocess.PIPE | |
if 'MAKECOMSTR' not in env.Dictionary().keys(): | |
real_stdout = None | |
# Make! | |
make = subprocess.Popen(fullcmd, | |
cwd = make_path, | |
stdout = real_stdout, | |
env = make_env) | |
# Some subprocesses don't terminate unless we communicate with them | |
output = make.communicate()[0] | |
return make.returncode | |
def generate(env, **kwargs): | |
env['BUILDERS']['Make'] = env.Builder( | |
action = env.Action(builder, message)) | |
def exists(env): | |
if env.WhereIs(env.subst('$MAKE')) != None: | |
return True | |
return False |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
thirdparty/gtest/SConscript | |
#################################################################################### | |
# Build file for GoogleTest | |
# | |
# This file is supposed to be invoked as a subscript from the toplevel SConstruct | |
# file in 'thirdparty'. | |
#################################################################################### | |
Import(['env', 'target']) | |
configureFlags = ['--disable-shared','--enable-static'] | |
installDir = Dir('../target/%s' % target) | |
# Google Test: ./configure | |
google_test_makefile = env.AutoConfig(CONFIGURE_FLAGS = configureFlags, | |
CONFIGURE_BUILDVARIANT = target, | |
CONFIGURE_PREFIX = installDir.abspath) | |
# Google Test: make | |
google_test_library = env.Make([installDir.File('lib/libgtest.la'), installDir.File('lib/libgtest_main.la')], | |
google_test_makefile, | |
MakePath = Dir('build/%s' % target), | |
MakeTargets = 'install') | |
env.Clean(google_test_library, installDir.File('bin/gtest-config')) | |
env.Clean(google_test_library, installDir.Dir('include/gtest')) | |
env.Clean(google_test_library, env.Glob(installDir.File('lib/libgtest*').abspath)) | |
env.Clean(google_test_library, installDir.File('share/aclocal/gtest.m4')) | |
#Alias('gtest', google_test_library) | |
Alias('gtest-%s' % target , google_test_library) | |
Alias(target,'gtest-%s' % target) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# thirdparty/SConstruct | |
################################################################################################ | |
# Build file for all Third-Party code | |
# | |
# Every 3rdparty library in use is mapped onto a Mercurial subrepository. | |
################################################################################################ | |
#----------------------------------------------------------------------------------------------- | |
# Load additional build tools in any of the environments. | |
# Since adding tools to the environment can't be done in site_init.py, it has to be done here | |
#----------------------------------------------------------------------------------------------- | |
base_environment.Tool('AutoConfig') | |
base_environment.Tool('Make') | |
debug_environment.Tool('AutoConfig') | |
debug_environment.Tool('Make') | |
production_environment.Tool('AutoConfig') | |
production_environment.Tool('Make') | |
#----------------------------------------------------------------------------------------------- | |
# Invoke the SConscript file of every 3rdparty library using every of the environments | |
#----------------------------------------------------------------------------------------------- | |
# Google Test | |
SConscript('gtest/SConscript', exports = { 'env' : debug_environment, 'target' : 'debug' }) | |
SConscript('gtest/SConscript', exports = { 'env' : production_environment, 'target' : 'production' }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# thirdparty/site_scons/site_init.py | |
import platform | |
from SCons.Script import * | |
EnsurePythonVersion(2, 6) | |
EnsureSConsVersion(1,2,0) | |
################################################################################################ | |
# Support for building with system packages or in Pylabs Sandbox | |
################################################################################################ | |
AddOption('--in-pylabs', | |
dest='in_pylabs', | |
action='store_true', | |
help='Build against the Pylabs sandbox') | |
if GetOption('in_pylabs'): | |
base_environment = Environment(platform = 'pylabs') | |
base_environment.Tool('pylabslink') | |
else: | |
base_environment = Environment() | |
################################################################################################ | |
# Definition of basic build environments | |
################################################################################################ | |
# SCons definitions | |
# C/C++ flags: CCFLAGS | |
# C flags: CFLAGS | |
# C++ flags: CXXFLAGS | |
# | |
#----------------------------------------------------------------------------------------------- | |
# The base_environment contains settings that are applicable to every situation. | |
#----------------------------------------------------------------------------------------------- | |
# Specific Preprocessor settings | |
# base_environment.Append(CPPFLAGS = []) | |
# Overal custom C/C++ settings | |
base_environment.Append(CCFLAGS = ['-fPIC']) | |
# Specific C settings | |
# base_environment.Append(CFLAGS = []) | |
# Specific C++ settings | |
# base_environment.Append(CXXFLAGS = []) | |
# Architecture specific settings | |
ARCHFLAGS = {'ia32': [], | |
'x86_64': ['-DSSE_16']} | |
base_environment.Replace(ARCH = {'i686':'ia32', | |
'x86_64':'x86_64'}.get(platform.machine(),'ia32')) | |
base_environment.Append(CCFLAGS = ARCHFLAGS[base_environment['ARCH']]) | |
# Path to 3rd party libraries | |
base_environment.Append(AMPLI_THIRD_PARTY = Dir('.').abspath) | |
#----------------------------------------------------------------------------------------------- | |
# The debug_environment contains settings that are applicable for debug building and testing. | |
#----------------------------------------------------------------------------------------------- | |
debug_environment = base_environment.Clone() | |
# Specific Preprocessor settings | |
# debug_environment.Append(CPPFLAGS = []) | |
# Overal custom C/C++ settings | |
# debug_environment.Append(CCFLAGS = ['-fPIC']) | |
# Specific C settings | |
# debug_environment.Append(CFLAGS = []) | |
# Specific C++ settings | |
# debug_environment.Append(CXXFLAGS = []) | |
#----------------------------------------------------------------------------------------------- | |
# The production_environment contains settings that are applicable for production building and testing. | |
#----------------------------------------------------------------------------------------------- | |
production_environment = base_environment.Clone() | |
# Specific Preprocessor settings | |
# production_environment.Append(CPPFLAGS = []) | |
# Overal custom C/C++ settings | |
# production_environment.Append(CCFLAGS = ['-fPIC']) | |
# Specific C settings | |
production_environment.Append(CFLAGS = [ '-DNDEBUG' ]) | |
# Specific C++ settings | |
# production_environment.Append(CXXFLAGS = []) | |
#----------------------------------------------------------------------------------------------- | |
# The above environments can be used further on in any SConstruct or SConscript file | |
#----------------------------------------------------------------------------------------------- | |
#----------------------------------------------------------------------------------------------- | |
# Default targets and the dependencies between them. | |
#----------------------------------------------------------------------------------------------- | |
Alias('production',[]) | |
Alias('test-production','production') | |
Alias('debug',[]) | |
Alias('test','debug') | |
Alias('coverage',[]) | |
Alias('test-coverage',[]) | |
Alias('all',['test','test-production','test-coverage']) | |
Default('test') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment