Compare commits
	
		
			6 commits
		
	
	
		
			master
			...
			feature/si
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c9ff381f39 | |||
| d054006625 | |||
| 637cd2d664 | |||
| ee0808aa41 | |||
| 31a51b7ce9 | |||
| 42baed281a | 
					 4 changed files with 145 additions and 139 deletions
				
			
		
							
								
								
									
										169
									
								
								SConstruct
									
										
									
									
									
								
							
							
						
						
									
										169
									
								
								SConstruct
									
										
									
									
									
								
							|  | @ -27,149 +27,40 @@ CFLAGS = '-Wall -Wextra -pedantic' | |||
| # BUILD STUFF BELOW HERE | ||||
| # | ||||
| 
 | ||||
| import os | ||||
| import os.path | ||||
| import SCons.Errors | ||||
| 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)') | ||||
| 
 | ||||
| 
 | ||||
| def which(program): | ||||
|     def is_executable(path): | ||||
|         return 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 | ||||
| #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, | ||||
| #}) | ||||
| 
 | ||||
| 
 | ||||
| def get_bool_argument(arg): | ||||
| for mode in GetOption('modes'): | ||||
|     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) | ||||
| common_env.Append(CFLAGS='{} -std=c99'.format(CFLAGS)) | ||||
| common_env.Append(CXXFLAGS='{} -std=c++11'.format(CFLAGS)) | ||||
| 
 | ||||
| # Add color error messages for clang | ||||
| if 'clang' in common_env['CC']: | ||||
|     common_env.Append(CFLAGS=' -fcolor-diagnostics') | ||||
| if 'clang' in common_env['CXX']: | ||||
|     common_env.Append(CXXFLAGS=' -fcolor-diagnostics') | ||||
| 
 | ||||
| BUILD_CMDS = get_bool_argument(ARGUMENTS.get('BUILD_CMDS', False)) | ||||
| if not BUILD_CMDS: | ||||
|     def generate_comstr(action): | ||||
|         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_dir = Dir('#build') | ||||
| lib_dir = Dir('#lib') | ||||
| src_dir = Dir('#src') | ||||
| test_dir = Dir('#test') | ||||
| 
 | ||||
| 
 | ||||
| def create_env(name, src_dirs, appends=None): | ||||
|     output_dir = build_dir.Dir(name) | ||||
|     env = common_env.Clone() | ||||
|     env['__name'] = name | ||||
|     env['__build_dir'] = output_dir | ||||
|     env['__src_dirs'] = [] | ||||
|     env['__output_dirs'] = [] | ||||
|     for d in src_dirs: | ||||
|         out_dir = output_dir.Dir(d.path) | ||||
|         env['__src_dirs'].append(d) | ||||
|         env['__output_dirs'].append(out_dir) | ||||
|         env.VariantDir(out_dir, d.path, duplicate=0) | ||||
|         env.Clean('.', out_dir) | ||||
|     if appends: | ||||
|         for k, v in appends.iteritems(): | ||||
|             if k.startswith('='): | ||||
|                 env[k[1:]] = v | ||||
|             else: | ||||
|                 env.Append(**{k: v}) | ||||
|     return env | ||||
| 
 | ||||
| 
 | ||||
| debug_cflags = ' -O0 -g' | ||||
| debug_env = create_env('debug', [src_dir], { | ||||
|     'CPPDEFINES': ['DEBUG'], | ||||
|     'CFLAGS': debug_cflags, | ||||
|     'CXXFLAGS': debug_cflags, | ||||
| }) | ||||
| 
 | ||||
| release_cflags = ' -O2' | ||||
| release_env = create_env('release', [src_dir], { | ||||
|     'CPPDEFINES': ['RELEASE'], | ||||
|     'CFLAGS': release_cflags, | ||||
|     'CXXFLAGS': release_cflags, | ||||
| }) | ||||
| 
 | ||||
| test_gtest_dir = Dir('#lib/gtest') | ||||
| test_cpppath = test_gtest_dir.Dir('include') | ||||
| test_env = create_env('test', [src_dir, test_dir, test_gtest_dir], { | ||||
|     'CPPDEFINES': ['DEBUG'], | ||||
|     'CPPPATH': [test_cpppath], | ||||
|     'LIBPATH': [test_gtest_dir], | ||||
|     'CFLAGS': debug_cflags, | ||||
|     'CXXFLAGS': debug_cflags, | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| modes = { | ||||
|     'debug': debug_env, | ||||
|     'release': release_env, | ||||
|     'test': test_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 = modes.keys() | ||||
| 
 | ||||
| for mode in build_modes: | ||||
|     try: | ||||
|         env = modes[mode] | ||||
|         env = MODES[mode] | ||||
|     except KeyError: | ||||
|         print 'Skipping invalid mode: {}'.format(mode) | ||||
|     for d in env['__output_dirs']: | ||||
|         env.SConscript(d.File('SConscript'), {'env': env}) | ||||
|     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) | ||||
|  |  | |||
							
								
								
									
										1
									
								
								site_scons/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								site_scons/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| *.pyc | ||||
							
								
								
									
										42
									
								
								site_scons/binaries.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								site_scons/binaries.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| # files.py | ||||
| # | ||||
| # Utilities for working with files and paths in SCons. | ||||
| # | ||||
| # Eryn Wells <eryn@erynwells.me> | ||||
| 
 | ||||
| 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 | ||||
							
								
								
									
										72
									
								
								site_scons/site_init.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								site_scons/site_init.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,72 @@ | |||
| # 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 <eryn@erynwells.me> | ||||
| 
 | ||||
| import os.path | ||||
| import SCons.Defaults | ||||
| import binaries | ||||
| 
 | ||||
| 
 | ||||
| BUILD_DIR = Dir('#build') | ||||
| LIB_DIR = Dir('#lib') | ||||
| SRC_DIR = Dir('#src') | ||||
| TEST_DIR = Dir('#test') | ||||
| 
 | ||||
| # | ||||
| # Environment Configuration | ||||
| # | ||||
| 
 | ||||
| def has_clang(env): | ||||
|     _, cc_tail = os.path.split(env['CC']) | ||||
|     _, cxx_tail = os.path.split(env['CXX']) | ||||
|     return any([cc_tail.startswith('clang'), cxx_tail.startswith('clang')]) | ||||
| 
 | ||||
| default_env = SCons.Defaults.DefaultEnvironment() | ||||
| default_env.Replace(CC=binaries.first(['clang', 'gcc']), | ||||
|                     CXX=binaries.first(['clang++', 'g++'])) | ||||
| 
 | ||||
| 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 | ||||
| } | ||||
| 
 | ||||
| # | ||||
| # Command Line Options | ||||
| # | ||||
| 
 | ||||
| def process_modes_option(option, opt, value, parser): | ||||
|     modes = value.split(',') | ||||
|     for m in modes: | ||||
|         setattr(parser.values, 'modes', set(modes)) | ||||
| 
 | ||||
| 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()))) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue