Mercurial > parpg-core
view SConstruct @ 2:e2a8e3805b04
Made parpg-core the main repository to pull from and build.
* Added parpg-assets as a subrepo under the data folder.
* Moved the SConstruct script into parpg-core and modified it to build and install parpg-assets as well.
* Made a few minor changes to the SConstruct file from the defunct parpg-main repository.
* Modified unix parpg executable script template to be more forgiving of installing the parpg Python package outside of PYTHONPATH.
* Updated the .hgignore file to include temporary SCons files.
author | M. George Hansen <technopolitica@gmail.com> |
---|---|
date | Sun, 15 May 2011 14:51:41 -0700 |
parents | |
children | 33684971cdb1 |
line wrap: on
line source
import sys import os import platform import compileall import fnmatch from collections import Sequence from multiprocessing import cpu_count def InstallChmod(env, dest, source, mode): targets = env.Install(dest, source) for target in targets: env.AddPostAction(target, Chmod(target, mode)) return targets def InstallExecutable(env, dest, source): return env.InstallChmod(dest, source, mode=0755) def InstallReadOnly(env, dest, source): if not isinstance(source, Sequence): source = [source] targets = [] for entry in map(Entry, source): entry.disambiguate() if entry.isdir(): target = env.InstallChmod(dest, entry, mode=0755) elif entry.isfile(): target = env.InstallChmod(dest, entry, mode=0644) else: # Something really weird happened and entry is not a Dir or a # File... (Note: Yes this can happen!) error_message = \ 'expected entry to be a Dir or a File, but got {0!r}' raise ValueError(error_message.format(entry)) 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): 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 AddMethod(Environment, InstallChmod) AddMethod(Environment, InstallExecutable) AddMethod(Environment, InstallReadOnly) AddMethod(Environment, InstallPyPackages) EnsurePythonVersion(2, 6) AddOption( '--stand-alone', dest='stand_alone', action='store_true', default=False, help='install the entire program under installation prefix instead of in ' 'various system folders' ) AddOption( '--no-compile', dest='compile', action='store_false', default=True, help='don\'t compile any Python modules into .pyc files', ) SetOption('num_jobs', cpu_count()) def is_abs_path(key, val, env): if not os.path.isabs(val): error_message = '${key} must be an absolute path' raise ValueError(error_message.format(key=key)) env[key] = os.path.normpath(val) variables = Variables() # NOTE M. George Hansen 2011-05-13: Path variables are based on the GNU # standards as defined at http://www.gnu.org/prep/standards/html_node/Directory-Variables.html # Platform-specific variable defaults. # FIXME M. George Hansen 2011-05-12: Define the MacOS-specific # environmental variables (and check version...) platform_name = platform.system() if platform_name in ['Linux', 'MacOS']: if GetOption('stand_alone'): PREFIX_DEFAULT = '/opt' else: PREFIX_DEFAULT = '/usr/local' BIN_DIR_DEFAULT = '$EXEC_PREFIX/bin' DATA_ROOT_DIR_DEFAULT = '$PREFIX/share/$PROJECT_NAME' SYS_CONF_DIR_DEFAULT = '$PREFIX/etc/$PROJECT_NAME' INCLUDE_DIR_DEFAULT = '$PREFIX/include/$PROJECT_NAME' DOC_DIR_DEFAULT = '$DATA_ROOT_DIR/doc/$PROJECT_NAME' LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib' dist_name, dist_version, dist_id = \ platform.linux_distribution(full_distribution_name=False) if dist_name in ['debian', 'Ubuntu']: # Debian uses dist-packages instead of site-packages for Python # versions > 2.5. PY_LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib/python$PY_VERSION_SHORT/' \ 'dist-packages' else: PY_LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib/python$PY_VERSION_SHORT/' \ 'site-packages' elif platform_name == 'Windows': try: PREFIX_DEFAULT = os.environ['ProgramFiles'] + r'\$PROGRAM_NAME' except KeyError: PREFIX_DEFAULT = '' error_message = '%ProgramFiles% environmental variable is not ' \ 'set, unable to determine path to Program Files ' \ 'folder (use --prefix to override)' raise SConfWarning(error_message) BIN_DIR_DEFAULT = '$EXEC_PREFIX' DATA_ROOT_DIR_DEFAULT = '$PREFIX/data' SYS_CONF_DIR_DEFAULT = '$PREFIX/config' INCLUDE_DIR_DEFAULT = '$PREFIX/include' DOC_DIR_DEFAULT = '$PREFIX/doc/' LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib' PY_LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib' if GetOption('stand_alone'): PY_LIB_DIR_DEFAULT = '$PREFIX/lib' else: python_prefix = sys.prefix # FIXME M. George Hansen 2011-05-12: Does sys.prefix include the # PythonX.Y part on Windows? PY_LIB_DIR_DEFAULT = \ os.path.join(python_prefix, 'Lib', 'site-packages') # Platform-independant variables: variables.AddVariables( PathVariable( 'PREFIX', 'directory under which most or all of the program components should ' 'be installed', PREFIX_DEFAULT, is_abs_path, ), PathVariable( 'EXEC_PREFIX', 'directory under which machine-specific compiled libraries and ' 'objects should be installed', '$PREFIX', is_abs_path, ), PathVariable( 'BIN_DIR', 'directory where program executables should be installed', BIN_DIR_DEFAULT, is_abs_path, ), PathVariable( 'DATA_ROOT_DIR', 'directory under which read-only, architecture-independant data files ' 'should be installed', DATA_ROOT_DIR_DEFAULT, is_abs_path, ), PathVariable( 'DATA_DIR', 'directory where read-only, architecture-independant data files ' 'should be installed', '$DATA_ROOT_DIR', is_abs_path, ), PathVariable( 'SYS_CONF_DIR', 'directory where read-only, machine-specific data files should be ' 'installed', SYS_CONF_DIR_DEFAULT, is_abs_path, ), PathVariable( 'INCLUDE_DIR', 'directory where C/C++ header files should be installed', INCLUDE_DIR_DEFAULT, is_abs_path, ), PathVariable( 'DOC_DIR', 'directory where program documentation should be installed', DOC_DIR_DEFAULT, is_abs_path, ), PathVariable( 'LIB_DIR', 'directory where platform-dependant, compiled library and object ' 'files should be installed', LIB_DIR_DEFAULT, is_abs_path, ), PathVariable( 'PY_LIB_DIR', 'directory where pure Python modules and packages should be installed', PY_LIB_DIR_DEFAULT, is_abs_path, ), PathVariable( 'INCLUDE_DIR', 'directory where C/C++ header files should be installed', INCLUDE_DIR_DEFAULT, is_abs_path, ), ) platform_name = platform.system() python_version_tuple = platform.python_version_tuple() environment = Environment( tools=['default', 'textfile', 'packaging'], variables=variables, PROJECT_NAME='parpg', PROJECT_VERSION_MAJOR=0, PROJECT_VERSION_MINOR=2, PROJECT_VERSION_PATCH=0, PROJECT_VERSION_SHORT='$PROJECT_VERSION_MAJOR.$PROJECT_VERSION_MAJOR', PROJECT_VERSION_LONG='$PROJECT_VERSION_MAJOR.$PROJECT_VERSION_MINOR.' '$PROJECT_VERSION_PATCH', PYTHON=sys.executable, PY_VERSION_SHORT='.'.join(python_version_tuple[:-1]), PY_VERSION_LONG='.'.join(python_version_tuple), PY_PACKAGES=[], CONFIG_FILES=[], DATA_FILES=[], EXECUTABLES=[], ) Help(variables.GenerateHelpText(environment)) config_dict = [('@{0}@'.format(key), environment.Dictionary()[key]) for key in ('PREFIX', 'LIB_DIR', 'PY_LIB_DIR', 'BIN_DIR', 'SYS_CONF_DIR', 'DATA_DIR', 'PYTHON')] environment['PY_PACKAGES'] += [ Dir('src/parpg'), ] config_file_template = File('system.cfg.in') subst_config_file = environment.Substfile(config_file_template, SUBST_DICT=config_dict) environment['CONFIG_FILES'] += [subst_config_file] environment['DATA_FILES'] += Glob('data/*') # TODO M. George Hansen 2011-05-12: Implement windows executable. executable_template = File('bin/unix/parpg.in') subst_executable = environment.Substfile(executable_template, SUBST_DICT=config_dict) environment['EXECUTABLES'] += [subst_executable] sources = environment.InstallPyPackages( '$PY_LIB_DIR', environment['PY_PACKAGES'], compile=GetOption('compile'), ) config_files = environment.InstallChmod( '$SYS_CONF_DIR', environment['CONFIG_FILES'], mode=0755, ) Requires(config_files, subst_config_file) data_files = environment.InstallReadOnly( '$DATA_DIR', environment['DATA_FILES'], ) executables = environment.InstallExecutable( '$BIN_DIR', environment['EXECUTABLES'], ) Requires(executables, subst_executable) # TODO M. George Hansen 2011-05-12: Implement package builder. #package = environment.Package( # NAME='parpg', # VERSION='0.2.0', # PACKAGEVERSION=0, # LICENSE='gpl', # SUMMARY='', # DESCRIPTION='', # X_RPM_GROUP='Application/parpg', #) Default([sources, config_files, data_files, executables]) Alias('install', [sources, config_files, data_files, executables])