comparison SConstruct @ 6:dd4ed4945411

Ported binary launcher to Windows. * Reorganized the parpg executable source so that it now compiles with the MSVC compiler (tested with MSVC Express 2010). * Cleaned up the launcher source by adding a bunch of const statements and removing the superfluous NULL_TERMINATE macro. * Fixed a few memory leaks in the launcher source by freeing malloced/calloced pointers; * Added a new SubstfileEscape builder to the SConstruct script used to escape certain sequences when substituting a template file. This is used to escape backslashes ("\") in c strings in the bin/parpg.c.in template for Windows paths. * Fixed the PY_LIB_DIR_DEFAULT for Windows so that it now correctly points to the default Python installation path. * Modified the SConstruct script to support compiling the launcher executable with debugging symbols in Windows with the DEBUG flag.
author M. George Hansen
date Sun, 22 May 2011 00:53:59 -0700
parents 33684971cdb1
children 4706e0194af3
comparison
equal deleted inserted replaced
5:33684971cdb1 6:dd4ed4945411
4 import compileall 4 import compileall
5 import fnmatch 5 import fnmatch
6 from collections import Sequence 6 from collections import Sequence
7 from types import StringType 7 from types import StringType
8 from multiprocessing import cpu_count 8 from multiprocessing import cpu_count
9
10 from SCons.Util import is_Sequence, is_Dict
9 11
10 def InstallChmod(env, dest, source, mode): 12 def InstallChmod(env, dest, source, mode):
11 targets = env.Install(dest, source) 13 targets = env.Install(dest, source)
12 for target in targets: 14 for target in targets:
13 env.AddPostAction(target, Chmod(target, mode)) 15 env.AddPostAction(target, Chmod(target, mode))
60 compileall.compile_dir(str(dir), ddir=str(dest), force=True) 62 compileall.compile_dir(str(dir), ddir=str(dest), force=True)
61 _add_targets(str(dir)) 63 _add_targets(str(dir))
62 targets = env.InstallReadOnly(dest, source) 64 targets = env.InstallReadOnly(dest, source)
63 return targets 65 return targets
64 66
67 def SubstfileEscape(env, *args, **kwargs):
68 subst_dict = kwargs.get('SUBST_DICT') or env.get('SUBST_DICT')
69 escape_sequences = kwargs.get('ESCAPE_SEQUENCES') or env.get('ESCAPE_SEQUENCES')
70 if subst_dict is not None and escape_sequences is not None:
71 if not is_Dict(subst_dict) and is_Sequence(subst_dict):
72 subst_dict = dict(subst_dict)
73 else:
74 error_message = 'SUBST_DICT must be dict or sequence'
75 raise SCons.Errors.UserError(error_message)
76 escaped_subst_dict = {}
77 for key, value in subst_dict.items():
78 escaped_value = value
79 for seq, escaped_seq in escape_sequences.items():
80 escaped_value = escaped_value.replace(seq, escaped_seq)
81 escaped_subst_dict[key] = escaped_value
82 kwargs['SUBST_DICT'] = escaped_subst_dict
83
84 target = env.Substfile(*args, **kwargs)
85 return target
86
65 AddMethod(Environment, InstallChmod) 87 AddMethod(Environment, InstallChmod)
66 AddMethod(Environment, InstallExecutable) 88 AddMethod(Environment, InstallExecutable)
67 AddMethod(Environment, InstallReadOnly) 89 AddMethod(Environment, InstallReadOnly)
68 AddMethod(Environment, InstallPyPackages) 90 AddMethod(Environment, InstallPyPackages)
91 AddMethod(Environment, SubstfileEscape)
69 92
70 EnsurePythonVersion(2, 6) 93 EnsurePythonVersion(2, 6)
71 94
72 AddOption( 95 AddOption(
73 '--stand-alone', 96 '--stand-alone',
137 DATA_ROOT_DIR_DEFAULT = '$PREFIX/data' 160 DATA_ROOT_DIR_DEFAULT = '$PREFIX/data'
138 SYS_CONF_DIR_DEFAULT = '$PREFIX/config' 161 SYS_CONF_DIR_DEFAULT = '$PREFIX/config'
139 INCLUDE_DIR_DEFAULT = '$PREFIX/include' 162 INCLUDE_DIR_DEFAULT = '$PREFIX/include'
140 DOC_DIR_DEFAULT = '$PREFIX/doc/' 163 DOC_DIR_DEFAULT = '$PREFIX/doc/'
141 LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib' 164 LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib'
142 PY_LIB_DIR_DEFAULT = '$EXEC_PREFIX/lib'
143 # FIXME M. George Hansen 2011-05-12: Does sys.prefix include the 165 # FIXME M. George Hansen 2011-05-12: Does sys.prefix include the
144 # PythonX.Y part on Windows? 166 # PythonX.Y part on Windows?
145 python_prefix = sys.prefix 167 python_prefix = sys.prefix
146 if GetOption('stand_alone'): 168 if GetOption('stand_alone'):
147 PY_PACKAGES_DIR_DEFAULT = '$PREFIX/lib' 169 PY_PACKAGES_DIR_DEFAULT = '$PREFIX/lib'
148 else: 170 else:
149 PY_PACKAGES_DIR_DEFAULT = \ 171 PY_PACKAGES_DIR_DEFAULT = \
150 os.path.join(python_prefix, 'Lib', 'site-packages') 172 os.path.join(python_prefix, 'Lib', 'site-packages')
151 PY_HEADERS_DIR_DEFAULT = os.path.join(python_prefix, 'include') 173 PY_HEADERS_DIR_DEFAULT = os.path.join(python_prefix, 'include')
152 try: 174 PY_LIB_DIR_DEFAULT = os.path.join(python_prefix, 'libs')
153 PY_LIB_DIR_DEFAULT = os.environ['SYSTEMROOT']
154 except KeyError:
155 PY_LIB_DIR_DEFAULT = ''
156 error_message = '%SYSTEMROOT% environmental variable is not set, ' \
157 'unable to determine path to Windows system folder'
158 raise SConfWarning(error_message)
159 PY_LIB_NAME = 'python$PY_VERSION_MAJOR$PY_VERSION_MINOR' 175 PY_LIB_NAME = 'python$PY_VERSION_MAJOR$PY_VERSION_MINOR'
160 176
161 # Platform-independant variables: 177 # Platform-independant variables:
162 variables.AddVariables( 178 variables.AddVariables(
163 PathVariable( 179 PathVariable(
248 'symbols', 264 'symbols',
249 False, 265 False,
250 ), 266 ),
251 ) 267 )
252 268
253 platform_name = platform.system()
254 python_version_tuple = platform.python_version_tuple() 269 python_version_tuple = platform.python_version_tuple()
255 270
256 environment = Environment( 271 environment = Environment(
257 tools=['default', 'cc', 'textfile', 'packaging'], 272 tools=['default', 'textfile', 'packaging'],
258 variables=variables, 273 variables=variables,
259 PROJECT_NAME='parpg', 274 PROJECT_NAME='parpg',
260 PROJECT_VERSION_MAJOR=0, 275 PROJECT_VERSION_MAJOR=0,
261 PROJECT_VERSION_MINOR=2, 276 PROJECT_VERSION_MINOR=2,
262 PROJECT_VERSION_PATCH=0, 277 PROJECT_VERSION_PATCH=0,
275 CONFIG_FILES=[], 290 CONFIG_FILES=[],
276 DATA_FILES=[], 291 DATA_FILES=[],
277 EXECUTABLES=[], 292 EXECUTABLES=[],
278 ) 293 )
279 if environment['DEBUG']: 294 if environment['DEBUG']:
280 environment.AppendUnique(CCFLAGS=['-gdwarf-2', '-g3']) 295 if platform_name == 'Windows':
296 environment['CCPDBFLAGS'] = '/Z7 /Od'
297 environment.AppendUnique(LINKFLAGS='/DEBUG')
298 else:
299 environment.AppendUnique(CCFLAGS=['-gdwarf-2', '-g3'])
281 300
282 Help(variables.GenerateHelpText(environment)) 301 Help(variables.GenerateHelpText(environment))
283 302
284 config_dict = [('@{0}@'.format(key), environment.Dictionary()[key]) for key in 303 config_dict = [('@{0}@'.format(key), environment.Dictionary()[key]) for key in
285 ('PREFIX', 'LIB_DIR', 'PY_PACKAGES_DIR', 'BIN_DIR', 304 ('PREFIX', 'LIB_DIR', 'PY_PACKAGES_DIR', 'BIN_DIR',
305 install_data = environment.InstallReadOnly( 324 install_data = environment.InstallReadOnly(
306 '$DATA_DIR', 325 '$DATA_DIR',
307 Glob('data/*'), 326 Glob('data/*'),
308 ) 327 )
309 328
310 executable_source = environment.Substfile( 329 # FIXME M. George Hansen 2011-05-20: Do any other sequences need to be escaped
330 # in a C string?
331 executable_source = environment.SubstfileEscape(
311 'bin/parpg.c.in', 332 'bin/parpg.c.in',
312 SUBST_DICT=config_dict, 333 SUBST_DICT=config_dict,
334 ESCAPE_SEQUENCES={'\\': r'\\\\', '"': r'\\"'},
313 ) 335 )
314 build_executable = environment.Program( 336 build_executable = environment.Program(
315 executable_source, 337 executable_source,
316 LIBS=['$PY_LIB_NAME'], 338 LIBS=['$PY_LIB_NAME'],
317 LIBPATH='$PY_LIB_DIR', 339 LIBPATH='$PY_LIB_DIR',
318 CPPPATH=['$PY_HEADERS_DIR'], 340 CPPPATH=['$PY_HEADERS_DIR'],
319 ) 341 )
320 # FIXME M. George Hansen 2011-05-17: Should the executable target be hard-coded 342 # Clean up any files created by the MSVC compiler on Windows.
321 # like this? 343 if platform_name == 'Windows':
344 environment.Clean(build_executable, 'bin/parpg.ilk')
345 environment.Clean(build_executable, 'bin/parpg.pdb')
322 install_executable = environment.InstallExecutable( 346 install_executable = environment.InstallExecutable(
323 '$BIN_DIR', 347 '$BIN_DIR',
324 'bin/parpg', 348 build_executable,
325 ) 349 )
326 350
327 # TODO M. George Hansen 2011-05-12: Implement package builder. 351 # TODO M. George Hansen 2011-05-12: Implement package builder.
328 #package = environment.Package( 352 #package = environment.Package(
329 # NAME='parpg', 353 # NAME='parpg',