diff --git a/SConstruct b/SConstruct index 48b0d84..bbd54b4 100644 --- a/SConstruct +++ b/SConstruct @@ -1,21 +1,80 @@ # SConstruct # vim: set ft=python: +# +# Toplevel Scons build script. This should be mostly complete and generic enough +# for most builds. +# # Eryn Wells -''' -Toplevel Scons build script. This should be mostly complete and generic enough -for most builds. -''' -import logging +# +# DEFAULT CONFIGURATION VALUES +# -setup_logging() +# Settings for the default toolchain binaries. Setting these overrides the +# defaults, provided your the given binary exists. +CC = None +CXX = None +AS = None +LINK = None -BUILD_CMDS = get_bool_argument(ARGUMENTS.get('BUILD_CMDS', False)) -MODE = ARGUMENTS.get('MODE', None) +# Same as above but for default CFLAGS. These are appended to both CFLAGS and +# CXXFLAGS. +CFLAGS = '-Wall -Wextra -pedantic' -for mode in (MODE.split(',') if MODE else ['debug']): - env = Environment.for_mode(mode) - env.process_lib_dirs() - env.process_src() - env.process_tests() + +# +# BUILD STUFF BELOW HERE +# + +if not GetOption('build_cmds'): + def comstr(action): + return '{:>18}: $TARGET'.format(action) + default_env = DefaultEnvironment() + default_env['ARCOMSTR'] = comstr('Archiving') + default_env['ASCOMSTR'] = comstr('Assembling') + default_env['ASPPCOMSTR'] = comstr('Assembling') + default_env['CCCOMSTR'] = comstr('Building (C)') + default_env['CXXCOMSTR'] = comstr('Building (C++)') + default_env['LINKCOMSTR'] = comstr('Linking') + default_env['RANLIBCOMSTR'] = comstr('Indexing') + default_env['SHCCCOMSTR'] = comstr('Building (C)') + default_env['SHCXXCOMSTR'] = comstr('Building (C++)') + default_env['SHLINKCOMSTR'] = comstr('Linking (Shared)') + + +#test_gtest_dir = Dir('#lib/gtest') +#test_gtest_include = test_gtest_dir.Dir('include') +#test_env = create_env('test', [src_dir, test_dir, test_gtest_dir], { +# 'CPPDEFINES': ['DEBUG'], +# 'CPPPATH': [test_gtest_include], +# 'LIBPATH': [test_gtest_dir], +# 'CFLAGS': debug_cflags, +# 'CXXFLAGS': debug_cflags, +#}) + + +for mode in GetOption('modes'): + try: + env = MODES[mode] + except KeyError: + print 'Skipping invalid mode: {}'.format(mode) + + # Process libraries + env.SConscript(LIB_DIR.File('SConscript'), { + 'env': env, + }, variant_dir=BUILD_DIR.Dir(env['MODE']).Dir('lib'), duplicate=0) + + # Process source + library, binary = env.SConscript(SRC_DIR.File('SConscript'), { + 'env': env + }, variant_dir=BUILD_DIR.Dir(env['MODE']).Dir('src'), duplicate=0) + env.Alias('lib', library) + env.Alias('bin', binary) + + env.SConscript(TEST_DIR.File('SConscript'), { + 'env': env, + }, variant_dir=BUILD_DIR.Dir(env['MODE']).Dir('test'), duplicate=0) + +Import('LIBS') +print LIBS diff --git a/lib/SConscript b/lib/SConscript new file mode 100644 index 0000000..1e223b9 --- /dev/null +++ b/lib/SConscript @@ -0,0 +1,24 @@ +# SConscript +# +# SCons build script for libs in base. Aggregates static and shared libraries in +# these directories and exports them in the 'LIBS' variable. +# +# Eryn Wells + + +Import('env') + +dirs = ( + 'gtest', +) + +env['LIBS'] = {} +for d in dirs: + static, dynamic = env.SConscript(Dir(d).File('SConscript'), { + 'env': env, + }) + env['LIBS'][d] = {} + if static: + env['LIBS'][d]['static'] = static + if dynamic: + env['LIBS'][d]['dynamic'] = dynamic diff --git a/lib/gtest/SConscript b/lib/gtest/SConscript index 5d2e1c7..a86241e 100644 --- a/lib/gtest/SConscript +++ b/lib/gtest/SConscript @@ -1,8 +1,14 @@ # SConscript # vim: set ft=python: +# # Eryn Wells -Library('gtest', [ +import os.path + +Import('env') + + +files = [ 'gtest-all.cc', 'gtest-death-test.cc', 'gtest-filepath.cc', @@ -11,5 +17,14 @@ Library('gtest', [ 'gtest-test-part.cc', 'gtest-typed-test.cc', 'gtest.cc', - 'gtest_main.cc' -]) +] + +objs = [] +for f in files: + objs.append(env.Object(f)) + +env.Append(CPPPATH=[Dir('include').srcnode()]) + +gtest_static = env.Library('gtest', [env.StaticObject(f) for f in files]) +gtest_dynamic = None +Return('gtest_static gtest_dynamic') diff --git a/site_scons/binaries.py b/site_scons/binaries.py new file mode 100644 index 0000000..b858376 --- /dev/null +++ b/site_scons/binaries.py @@ -0,0 +1,42 @@ +# files.py +# +# Utilities for working with files and paths in SCons. +# +# Eryn Wells + +import os + + +def which(program): + ''' + Given a program name, search the system environment's $PATH for a binary of + that name. If one exists, return its name. If not, return None. This + function will also use the system environment's $PATHEXT to find binaries + with appropriate extensions (i.e., .exe on Windows). + ''' + is_executable = lambda path: ( os.path.exists(path) + and os.access(path, os.X_OK)) + + 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 first(binaries): + ''' + Given a list of binaries, return the first one found. + ''' + for binary in binaries: + if which(binary): + return binary + return None diff --git a/site_scons/dirs.py b/site_scons/dirs.py new file mode 100644 index 0000000..7aa8751 --- /dev/null +++ b/site_scons/dirs.py @@ -0,0 +1,9 @@ +# dirs.py +# Eryn Wells + +from SCons.Script import Dir + +BUILD_DIR = Dir('#build') +LIB_DIR = Dir('#lib') +SRC_DIR = Dir('#src') +TEST_DIR = Dir('#test') diff --git a/site_scons/site_init.py b/site_scons/site_init.py index 0c2f2ba..d296109 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -1,210 +1,71 @@ # site_init.py +# +# This file is read before every SConstruct and SConscript. So, anything that +# should be available to every build script should go here. +# # Eryn Wells -import logging -import sys -import SCons.Environment -import SCons.Errors +import os.path +import SCons.Defaults +from dirs import * -def setup_logging(level=logging.DEBUG): - '''Configure global logging for the SCons system.''' - root = logging.getLogger() - root.setLevel(logging.DEBUG) - root.addHandler(logging.StreamHandler()) - # -# Argument utils +# Environment Configuration # -def get_bool_argument(arg): - ''' - Convert the given argument value to a bool. True values are any integer that - is considered true by Python, and any string value that isn't a - capitalization variant of the word "false". - ''' - try: - return bool(int(arg)) - except ValueError: - pass - return str(arg).lower() != 'false' +def has_clang(env): + _, cc_tail = os.path.split(env['CC']) + _, cxx_tail = os.path.split(env['CXX']) + return all([cc_tail.startswith('clang'), cxx_tail.startswith('clang')]) + +default_env = SCons.Defaults.DefaultEnvironment() +default_env.Append(TOOLS=['gtest']) +print default_env.Dump() + +default_env.Replace( + CC=default_env.WhereIs('clang') or default_env.WhereIs('gcc'), + CXX=default_env.WhereIs('clang++') or default_env.WhereIs('gcc++')) + +default_env.Append(CCFLAGS=['-Wall', '-Wextra', '-pedantic'], + CFLAGS=['-std=c99'], + CXXFLAGS=['-std=c++11']) +if has_clang(default_env): + # Only clang supports color. + default_env.Append(CCFLAGS=['-fcolor-diagnostics']) + + +debug_env = default_env.Clone(MODE='debug', + CCFLAGS=['-O0', '-g'], + CPPDEFINES=['DEBUG']) +release_env = default_env.Clone(MODE='release', + CCFLAGS=['-O2'], + CPPDEFINES=['RELEASE']) + +MODES = { + 'debug': debug_env, + 'release': release_env +} # -# Builders +# Command Line Options # -def program_builder(env): - original_builder = env.Program - def builder(env, prog_name, sources, *args, **kwargs): - return original_builder(prog_name, sources, *args, **kwargs) - return builder +def process_modes_option(option, opt, value, parser): + modes = value.split(',') + for m in modes: + setattr(parser.values, 'modes', set(modes)) -# -# Environments -# - -class Environment(SCons.Environment.Environment): - ''' - Default SCons environment for building things. - ''' - - @classmethod - def _comstr(cls, action, succinct=True): - if succinct: - return '{:>25}: $TARGET'.format(action) - # Use the default *COMSTR. - return None - - @classmethod - def for_mode(cls, mode, name=None, succinct=True): - kwargs = {'succinct': succinct} - if name: - kwargs['name'] = name - mode_lower = mode.lower() - if mode_lower == 'debug': - return DebugEnvironment(**kwargs) - elif mode_lower == 'beta': - return BetaEnvironment(**kwargs) - elif mode_lower == 'release': - return ReleaseEnvironment(**kwargs) - raise SCons.Errors.UserError('Invalid mode: {}'.format(mode)) - - def __init__(self, name, modern=True, paranoid=True, colorful=True, succinct=True, **kwargs): - super(Environment, self).__init__(**self._append_custom_tools(kwargs)) - - self.SetDefault(NAME=name) - - self.SetDefault(LOGGER=logging.getLogger(name)) - - self.SetDefault(BUILD_ROOT=self.Dir('#build')) - self.SetDefault(LIB_ROOT=self.Dir('#lib')) - self.SetDefault(SRC_ROOT=self.Dir('#src')) - self.SetDefault(TEST_ROOT=self.Dir('#test')) - self.SetDefault(INCLUDE_ROOT=self.Dir('#include')) - - # Allow same directory includes. - self.AppendUnique(CPPPATH=['.']) - - self['CC'] = self.Detect(['clang', 'gcc']) - self['CXX'] = self.Detect(['clang++', 'g++']) - self['LINK'] = self.Detect(['clang++', 'clang', 'ld']) - - # Modern C/C++ - if modern: - self.AppendUnique(CFLAGS=['-std=c99']) - self.AppendUnique(CXXFLAGS=['-std=c++11']) - - # Paranoid C/C++ - if paranoid: - self.AppendUnique(CCFLAGS=['-Wall', '-Wextra', '-pedantic']) - - # Colorful C/C++ - if colorful and sys.stdout.isatty(): - if 'clang' in self['CC'] or 'clang' in self['CXX']: - self.AppendUnique(CCFLAGS=['-fcolor-diagnostics']) - elif 'gcc' in self['CC'] or 'g++' in self['CXX']: - # TODO: Also set a GCC_COLORS variable in the system environment? - self.AppendUnique(CCFLAGS=['-fdiagnostics-color=always']) - - # Pretty printing - self.SetDefault(ARCOMSTR=Environment._comstr('Archiving', succinct)) - self.SetDefault(ASCOMSTR=Environment._comstr('Assembling', succinct)) - self.SetDefault(ASPPCOMSTR=Environment._comstr('Assembling', succinct)) - self.SetDefault(CCCOMSTR=Environment._comstr('Building (C)', succinct)) - self.SetDefault(CXXCOMSTR=Environment._comstr('Building (C++)', succinct)) - self.SetDefault(LINKCOMSTR=Environment._comstr('Linking', succinct)) - self.SetDefault(RANLIBCOMSTR=Environment._comstr('Indexing', succinct)) - self.SetDefault(SHCCCOMSTR=Environment._comstr('Building (C, Shared)', succinct)) - self.SetDefault(SHCXXCOMSTR=Environment._comstr('Building (C++, Shared)', succinct)) - self.SetDefault(SHLINKCOMSTR=Environment._comstr('Linking (Shared)', succinct)) - - @property - def build_root(self): - '''Return the build output directory for this environment.''' - return self['BUILD_ROOT'].Dir(self['NAME']) - - @property - def lib_root(self): - '''Return the root directory for libraries for this environment.''' - return self['LIB_ROOT'] - - @property - def src_root(self): - '''Return the main source root directory for this environment.''' - return self['SRC_ROOT'] - - def process_src(self): - out_dir = self.build_root.Dir('src') - self.SConscript(self.src_root.File('SConscript'), - variant_dir=out_dir) - self.Append(CPPPATH=[self.src_root]) - - # - # Test processing - # - - def test_objects(self, name): - self._ensure_test_structure(name) - return self['TESTS'][name]['objects'] - - def test_program(self, name): - self._ensure_test_structure(name) - return self['TESTS'][name]['program'] - - def register_test_program(self, name, prog): - self._ensure_test_structure(name) - self['TESTS'][name]['program'] = prog - - def process_tests(self): - tests = [] - for test, struct in self['TESTS'].iteritems(): - if not struct['program']: - continue - tests.append(self.TestRun(test)) - self.Alias('test', tests) - - def _ensure_test_structure(self, name): - self['TESTS'].setdefault(name, {'program': None, 'objects': []}) - - # - # Logging - # - - def log(self, msg, *args, **kwargs): - self['LOGGER'].info(msg, *args, **kwargs) - - def log_debug(self, msg, *args, **kwargs): - self['LOGGER'].debug(msg, *args, **kwargs) - - def log_error(self, msg, *args, **kwargs): - self['LOGGER'].error(msg, *args, **kwargs) - - def _append_custom_tools(self, kwargs): - '''Add custom tools to the `kwargs`.''' - tools = kwargs.setdefault('tools', ['default']) - for tool in ['lib', 'test', 'program', 'sconscript', 'swiftc']: - if tool in tools: - continue - tools.append(tool) - return kwargs - - -class DebugEnvironment(Environment): - def __init__(self, name='debug', **kwargs): - super(DebugEnvironment, self).__init__(name, **kwargs) - self.Append(CPPDEFINES=['DEBUG']) - self.Append(CCFLAGS=['-O0', '-g']) - - -class BetaEnvironment(Environment): - def __init__(self, name='beta', **kwargs): - super(BetaEnvironment, self).__init__(name, **kwargs) - self.Append(CPPDEFINES=['DEBUG']) - self.Append(CCFLAGS=['-O3', '-g']) - - -class ReleaseEnvironment(Environment): - def __init__(self, name='release', **kwargs): - super(ReleaseEnvironment, self).__init__(name, **kwargs) - self.Append(CPPDEFINES=['NDEBUG', 'RELEASE']) - self.Append(CCFLAGS=['-O3']) +AddOption('--show-build-cmds', + dest='build_cmds', + action='store_true', + help='Show build commands instead of friendly build messages') +AddOption('--modes', + type='string', + action='callback', + dest='modes', + metavar='MODES', + default=set(['debug']), + callback=process_modes_option, + help=('A comma separated list of modes. Choose from: {}. Default is ' + 'debug.').format(', '.join(MODES.keys()))) diff --git a/site_scons/site_tools/gtest/__init__.py b/site_scons/site_tools/gtest/__init__.py new file mode 100644 index 0000000..4bb21ae --- /dev/null +++ b/site_scons/site_tools/gtest/__init__.py @@ -0,0 +1,28 @@ +# gtestprogram.py +# Eryn Wells + +import SCons.Util +import dirs + + +def build_gtest_program(env, target, source=None, *args, **kwargs): + if not SCons.Util.is_List(source): + source = [source] + source.insert(0, dirs.LIB_DIR.Dir('gtest').File('gtest_main.cc')) + source.append(env['LIBS']['gtest']['static']) + return env.Program(target, source, *args, **kwargs) + + +def generate(env): + print 'gtestprogram generate()' + try: + env.AddMethod(build_gtest_program, 'GTestProgram') + except AttributeError: + # Old version of SCons + from SCons.Script.SConscript import SConsEnvironment + SConsEnvironment.GTestProgram = build_gtest_program + + +def exists(env): + print 'gtestprogram exists()' + return 'gtest' in env['LIBS'] diff --git a/site_scons/site_tools/lib.py b/site_scons/site_tools/lib.py deleted file mode 100644 index dd47f61..0000000 --- a/site_scons/site_tools/lib.py +++ /dev/null @@ -1,81 +0,0 @@ -# lib.py -# Eryn Wells - -''' -SCons builder for a lib directory. -''' - -import os - -import SCons.Errors -import SCons.Script - - -def _lib(env, name): - return env['LOCAL_LIBS'].get(name) - - -def _register_lib(env, name, lib): - if name in env['LOCAL_LIBS']: - env.log_error('Library has already been built: {}'.format(name)) - env['LOCAL_LIBS'][name] = lib - - -def _lib_dirs(env): - for lib in os.listdir(env.lib_root.abspath): - lib_dir = env.lib_root.Dir(lib) - if not lib_dir.isdir(): - continue - yield (lib, lib_dir) - - -def _process_lib_dirs(env): - for name, _ in _lib_dirs(env): - env.LibDir(name) - - -def _process_lib_dir(env, lib, src_dir=None, out_dir=None, inc_dir=None): - if not src_dir: - src_dir = env.lib_root.Dir(lib) - if not src_dir.isdir(): - err = 'Invalid library source directory: {}'.format(src_dir) - env.log_error(err) - raise SCons.Errors.UserError(err) - if not out_dir: - out_dir = env.build_root.Dir('lib').Dir(lib) - if not inc_dir: - include_dir = src_dir.Dir('include') - if include_dir.isdir(): - inc_dir = [include_dir] - env.Append(CPPPATH=inc_dir) - out = env.SConscript(src_dir.File('SConscript'), - clone=True, - variant_dir=out_dir) - return out - - -def _build_library(env, lib_func): - original_builder = lib_func - - def builder(env, lib_name, sources, *args, **kwargs): - lib = original_builder(lib_name, sources, *args, **kwargs) - _register_lib(env, lib_name, lib) - return lib - - return builder - -# -# SCons tool interface -# - -def generate(env): - env.SetDefault(LOCAL_LIBS={}) - env.AddMethod(_process_lib_dir, 'LibDir') - env.AddMethod(_build_library(env, env.Library), 'Library') - env.AddMethod(_build_library(env, env.StaticLibrary), 'StaticLibrary') - env.AddMethod(_build_library(env, env.SharedLibrary), 'SharedLibrary') - env.AddMethod(_lib, 'lib') - env.AddMethod(_process_lib_dirs, 'process_lib_dirs') - -def exists(env): - return True diff --git a/site_scons/site_tools/osxapp.py b/site_scons/site_tools/osxapp.py deleted file mode 100644 index e56a795..0000000 --- a/site_scons/site_tools/osxapp.py +++ /dev/null @@ -1,36 +0,0 @@ -# osxapp.py -# Eryn Wells - -import os.path - -_BUNDLE_SUFFIX = '.app' - - -def _assemble_app_bundle(env, bundle_name, binary, info_plist, resources_dir): - # TODO: Create directory structure, copy binary, plist, and resources. Sign the binary? app bundle? - - if not bundle_name.endswith('.app'): - bundle_name += '.app' - - bundle_dir = env.Dir(bundle_name) - contents_dir = bundle_dir.Dir('Contents') - macos_dir = contents_dir.Dir('MacOS') - resources_dir = contents_dir.Dir('Resources') - - return [env.Mkdir(contents_dir), - env.Copy(contents_dir.File('Info.plist'), info_list), - env.Mkdir(macos_dir), - env.Copy(macos_dir.File(bundle_name), binary) - - -_app_builder = Builder(action=_assemble_app_bundle, - suffix=_BUNDLE_SUFFIX) - - -def generate(env): - env['OSXAPPBUNDLESUFFIX'] = _BUNDLE_SUFFIX - env['BUILDERS']['OSXApp'] = _app_builder - - -def exists(env): - return True diff --git a/site_scons/site_tools/program.py b/site_scons/site_tools/program.py deleted file mode 100644 index 21bbddf..0000000 --- a/site_scons/site_tools/program.py +++ /dev/null @@ -1,46 +0,0 @@ -# program.py -# Eryn Wells - -''' -SCons tool for working with Programs. -''' - -def _program(env, name): - return env['PROGRAMS'].get(name) - - -def _register_program(env, name, program): - env['PROGRAMS'][name] = program - - -def _build_program(env): - original_builder = env.Program - - def builder(env, name, sources, local_libs=None, *args, **kwargs): - # local_libs is an array of names of libs built in the local project. - # These will be looked up in the environment and added to the LIBS - # array, if present. -# if local_libs: -# local_libs = map(lambda lib: env.lib(lib), local_libs) -# try: -# kwargs['LIBS'].extend(local_libs) -# except KeyError: -# kwargs['LIBS'] = local_libs - prog = original_builder(name, sources, *args, **kwargs) - _register_program(env, name, prog) - return prog - - return builder - -# -# SCons tool interface -# - -def generate(env): - env.SetDefault(PROGRAMS={}) - env.AddMethod(_build_program(env), 'Program') - env.AddMethod(_program, 'program') - - -def exists(env): - return True diff --git a/site_scons/site_tools/sconscript.py b/site_scons/site_tools/sconscript.py deleted file mode 100644 index 3e9b597..0000000 --- a/site_scons/site_tools/sconscript.py +++ /dev/null @@ -1,38 +0,0 @@ -# sconscript.py -# Eryn Wells - -''' -SCons tool for working with SConscripts. -''' - -import SCons.Script - -def _do_sconscript(env): - original_sconscript = env.SConscript - - def sconscript(env, sconscript, clone=False, *args, **kwargs): - exports = { - 'Library': env.Library, - 'Object': env.Object, - 'SharedObject': env.SharedObject, - 'StaticLibrary': env.StaticLibrary, - 'SharedLibrary': env.SharedLibrary, - 'Program': env.Program, - 'env': env.Clone() if clone else env, - } - SCons.Script._SConscript.GlobalDict.update(exports) - env.log('Reading {}'.format(sconscript)) - return original_sconscript(sconscript, {}, *args, **kwargs) - - return sconscript - -# -# SCons tool interface -# - -def generate(env): - env.AddMethod(_do_sconscript(env), 'SConscript') - - -def exists(env): - return True diff --git a/site_scons/site_tools/swiftc.py b/site_scons/site_tools/swiftc.py deleted file mode 100644 index 5d2766d..0000000 --- a/site_scons/site_tools/swiftc.py +++ /dev/null @@ -1,33 +0,0 @@ -# swiftc.py -# vim: set ft=python: -# Eryn Wells - -''' -SCons plugin for building Swift files with swiftc. -''' - -import SCons.Action -import SCons.Tool -import SCons.Util - -SwiftSuffix = '.swift' -SwiftAction = SCons.Action.Action("$SWIFTCCOM", "$SWIFTCCOMSTR") - -compilers = ['swiftc'] - -def generate(env): - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - static_obj.add_action(SwiftSuffix, SwiftAction) - static_obj.add_emitter(SwiftSuffix, SCons.Defaults.SharedObjectEmitter) - shared_obj.add_action(SwiftSuffix, SwiftAction) - shared_obj.add_emitter(SwiftSuffix, SCons.Defaults.SharedObjectEmitter) - - if 'SWIFTC' not in env: - compiler = env.Detect(compilers) - env['SWIFTC'] = compiler if compiler else compilers[0] - env['SWIFTFLAGS'] = SCons.Util.CLVar('') - env['SWIFTCCOM'] = '$SWIFTC -o $TARGET -c $SWIFTFLAGS $SOURCES' - env['SWIFTFILESUFFIX'] = SwiftSuffix - -def exists(env): - return env.Detect(compilers) diff --git a/site_scons/site_tools/test.py b/site_scons/site_tools/test.py deleted file mode 100644 index df8e924..0000000 --- a/site_scons/site_tools/test.py +++ /dev/null @@ -1,51 +0,0 @@ -# test.py -# Eryn Wells - -''' -Test builder for SCons. Test files are compiled to objects and stored in the -environment. -''' - -def _process_test_dir(env, dir, program=None): - # TODO: Builder for test directories? - pass - - -def _build_test_object(env, source, program=None): - obj = env.Object(source) - if not program: - program = 'test' - try: - env.test_objects(program).extend(obj) - except TypeError: - env.test_objects(program).append(obj) - return obj - - -def _build_test_program(env, name=None): - if not name: - name = 'test' - prog = env.Program(name, env.test_objects(name), LIBS=[env.lib('gtest')]) - env.register_test_program(name, prog) - return - - -def _run_tests(env, name=None): - if not name: - name = 'test' - cmd = env.Command(env.test_program(name), None, '$SOURCE --gtest_color=yes') - env.AlwaysBuild(cmd) - return cmd - -# -# SCons tool interface -# - -def generate(env): - env.SetDefault(TESTS={}) - env.AddMethod(_build_test_object, 'Test') - env.AddMethod(_build_test_program, 'TestProgram') - env.AddMethod(_run_tests, 'TestRun') - -def exists(env): - return 'Object' in env diff --git a/src/SConscript b/src/SConscript index 5d9a22e..9e2c37e 100644 --- a/src/SConscript +++ b/src/SConscript @@ -1,5 +1,32 @@ # SConscript # vim: set ft=python: +# # Eryn Wells -Program('hello', ['hello.cc']) +import os.path + +Import('env') + + +subdirs = [ + # TODO: Put subdirectories here. +] + +for d in subdirs: + env.SConscript(os.path.join(d, 'SConscript'), {'env': env}) + + +files = [ + # TODO: Put files here. + #'hello.cc', +] + +objs = [] +for f in files: + objs.append(env.Object(f)) + +#lib = env.Library('hello', files) +#prog = env.Program('hello', lib) +lib = None +prog = None +Return('prog lib') diff --git a/src/hello.cc b/src/hello.cc deleted file mode 100644 index b02d2e0..0000000 --- a/src/hello.cc +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -main() -{ - std::cout << "Hello world!" << std::endl; - return 0; -} diff --git a/test/SConscript b/test/SConscript new file mode 100644 index 0000000..e46f7bc --- /dev/null +++ b/test/SConscript @@ -0,0 +1,27 @@ +# SConscript +# vim: set ft=python: +# +# Eryn Wells + +import os.path + +Import('env') + + +subdirs = [ + # TODO: Put subdirectories here. +] + +for d in subdirs: + env.SConscript(os.path.join(d, 'SConscript'), {'env': env}) + + +files = [ + # TODO: Put files here. +] + +objs = [] +for f in files: + objs.append(env.Object(f)) + +env.GTestProgram('test_hello', 'test_hello.cc')