Mercurial > parpg-core
diff SConstruct @ 11:4706e0194af3
Various improvements to the build process including support for self-contained builds.
* Note that despite all of these changes PARPG still does not run because asset paths are not standardized,
* Modified the SCons script so that by default running `scons` with no arguments creates a self-contained "build" under a build subdirectory to make in-source testing easier. To install PARPG, use `scons install` instead.
* Got rid of the binary launcher and replaced it with a shell script for unix and a batch script for Windows (batch script is untested). The binary turned out to be too much trouble to maintain.
* Modified the parpg.settings module and parpg.main entry script so that PARPG searches through several default search paths for configuration file(s). PARPG thus no longer crashes if it can't find a configuration file in any particular search path, but will crash it if can't find any configuration files.
* Paths supplied to parpg.main are now appended as search paths for the configuration file(s).
* Changed the default configuration file name to "parpg.cfg" to simplify searches.
* Created the site_scons directory tree where SCons extensions and tools should be placed.
* Created a new SCons builder, CopyRecurse, which can copy only certain files and folders from a directory tree using filters (files and folders that start with a leading dot "." e.g. ".svn" are ignored by default).
* Added the CPython SCons tool (stands for Compile-Python - I didn't name it!), which provides the InstallPython builder for pre-compiling python sources before they are installed. However, it is currently broken and only installs the python sources.
author | M. George Hansen <technopolitica@gmail.com> |
---|---|
date | Tue, 31 May 2011 02:46:20 -0700 |
parents | dd4ed4945411 |
children | d60f1dab8469 |
line wrap: on
line diff
--- a/SConstruct Wed Jun 01 00:45:27 2011 -0700 +++ b/SConstruct Tue May 31 02:46:20 2011 -0700 @@ -3,11 +3,31 @@ import platform import compileall import fnmatch +from copy import copy from collections import Sequence from types import StringType from multiprocessing import cpu_count from SCons.Util import is_Sequence, is_Dict +from SCons.Tool.install import copyFunc + +#def recursive_glob(topdir_path, include_pattern='*', exclude_pattern=''): +# """ +# Locate all files matching supplied filename pattern in and below +# supplied root directory. +# """ +# for dir_path, subdir_names, file_names in \ +# os.walk(os.path.abspath(topdir_path)): +# for file_name in fnmatch.filter(file_names, include_pattern): +# if not fnmatch.fnmatch(file_name, exclude_pattern): +# file_path = os.path.join(dir_path, file_name) +# yield File(file_path) +# for subdir_name in copy(subdir_names): +# if not fnmatch.fnmatch(subdir_name, include_pattern) or \ +# fnmatch.fnmatch(subdir_name, exclude_pattern): +# subdir_names.remove(subdir_name) +# else: +# subdir_path = os.path.join(dir_path, subdir_name) def InstallChmod(env, dest, source, mode): targets = env.Install(dest, source) @@ -37,33 +57,6 @@ targets.append(target) return targets -def InstallPyPackages(env, dest, source, compile=True): - # Remove all existing *.pyc and *.pyo files for a sanitary install - # environment. - def _remove_compiled_modules(path): - for dir_path, dir_names, file_names in os.walk(path): - for file_name in fnmatch.filter(file_names, '*.py[co]'): - file_path = os.path.join(dir_path, file_name) - os.remove(file_path) - - def _add_targets(path): - for dir_path, dir_names, file_names in os.walk(path): - for file_name in fnmatch.filter(file_names, '*.py[co]'): - file_path = os.path.join(dir_path, file_name) - env.Clean(path, file_path) - source_file_path = file_path.rstrip('oc') - env.Depends(file_path, source_file_path) - - if not isinstance(source, Sequence) or isinstance(source, StringType): - source = [source] - for dir in source: - _remove_compiled_modules(str(dir)) - if compile: - compileall.compile_dir(str(dir), ddir=str(dest), force=True) - _add_targets(str(dir)) - targets = env.InstallReadOnly(dest, source) - return targets - def SubstfileEscape(env, *args, **kwargs): subst_dict = kwargs.get('SUBST_DICT') or env.get('SUBST_DICT') escape_sequences = kwargs.get('ESCAPE_SEQUENCES') or env.get('ESCAPE_SEQUENCES') @@ -87,7 +80,6 @@ AddMethod(Environment, InstallChmod) AddMethod(Environment, InstallExecutable) AddMethod(Environment, InstallReadOnly) -AddMethod(Environment, InstallPyPackages) AddMethod(Environment, SubstfileEscape) EnsurePythonVersion(2, 6) @@ -269,7 +261,7 @@ python_version_tuple = platform.python_version_tuple() environment = Environment( - tools=['default', 'textfile', 'packaging'], + tools=['default', 'cpython', 'copyrecurse', 'textfile', 'packaging'], variables=variables, PROJECT_NAME='parpg', PROJECT_VERSION_MAJOR=0, @@ -286,10 +278,7 @@ PY_VERSION_LONG='${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}.' '${PY_VERSION_PATCH}', PY_LIB_NAME=PY_LIB_NAME, - PY_PACKAGES=[], - CONFIG_FILES=[], - DATA_FILES=[], - EXECUTABLES=[], + BUILD_DIR='build', ) if environment['DEBUG']: if platform_name == 'Windows': @@ -304,49 +293,56 @@ ('PREFIX', 'LIB_DIR', 'PY_PACKAGES_DIR', 'BIN_DIR', 'SYS_CONF_DIR', 'DATA_DIR', 'PYTHON')] -install_py_packages = environment.InstallPyPackages( +copy_py_packages = environment.Install( + '$BUILD_DIR', + 'src/parpg', +) +install_py_packages = environment.InstallPython( '$PY_PACKAGES_DIR', - 'src/parpg', - compile=GetOption('compile'), + copy_py_packages, + PYTHON_COMPILE=GetOption('compile'), +) + +copy_data = environment.CopyRecurse( + '$BUILD_DIR', + 'data', ) subst_config_file = environment.Substfile( - 'system.cfg.in', - SUBST_DICT=config_dict + '$BUILD_DIR/parpg.cfg', + 'parpg.cfg.in', + SUBST_DICT=config_dict, ) install_config_files = environment.InstallChmod( '$SYS_CONF_DIR', subst_config_file, - mode=0755 + mode=0755, ) Requires(install_config_files, subst_config_file) -install_data = environment.InstallReadOnly( - '$DATA_DIR', - Glob('data/*'), -) - -# FIXME M. George Hansen 2011-05-20: Do any other sequences need to be escaped -# in a C string? -executable_source = environment.SubstfileEscape( - 'bin/parpg.c.in', +if platform_name == 'Windows': + launcher_name = 'parpg.bat' +else: + launcher_name = 'parpg.sh' +# FIXME M. George Hansen 2011-05-20: Do any other sequences need to be escaped? +launcher = environment.SubstfileEscape( + 'build/$LAUNCHER_NAME', + 'bin/${LAUNCHER_NAME}.in', + LAUNCHER_NAME=launcher_name, SUBST_DICT=config_dict, ESCAPE_SEQUENCES={'\\': r'\\\\', '"': r'\\"'}, ) -build_executable = environment.Program( - executable_source, - LIBS=['$PY_LIB_NAME'], - LIBPATH='$PY_LIB_DIR', - CPPPATH=['$PY_HEADERS_DIR'], -) -# Clean up any files created by the MSVC compiler on Windows. if platform_name == 'Windows': - environment.Clean(build_executable, 'bin/parpg.ilk') - environment.Clean(build_executable, 'bin/parpg.pdb') -install_executable = environment.InstallExecutable( - '$BIN_DIR', - build_executable, -) + install_launcher = environment.InstallExecutable( + '$BIN_DIR', + launcher, + ) +else: + # Remove the .sh suffix, since it isn't needed on unix platforms. + install_launcher = environment.InstallAs( + '$BIN_DIR/parpg', + launcher, + ) # TODO M. George Hansen 2011-05-12: Implement package builder. #package = environment.Package( @@ -359,8 +355,9 @@ # X_RPM_GROUP='Application/parpg', #) -build = Alias('build', [build_executable]) -install = Alias('install', [build, install_executable, install_py_packages, - install_config_files, install_data]) +build = Alias('build', [launcher, subst_config_file, copy_py_packages, + copy_data]) +install = Alias('install', [build, install_launcher, install_py_packages, + install_config_files]) -Default(install) +Default(build)