Mercurial > parpg-core
comparison site_scons/site_tools/cpython/__init__.py @ 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 | |
children |
comparison
equal
deleted
inserted
replaced
10:5deaf494934a | 11:4706e0194af3 |
---|---|
1 """SCons.Tool.cpython | |
2 | |
3 Tool-specific initialization for Python binary builder. | |
4 | |
5 There normally shouldn't be any need to import this module directly. | |
6 It will usually be imported through the generic SCons.Tool.Tool() | |
7 selection method. | |
8 | |
9 """ | |
10 | |
11 # | |
12 # Copyright (c) 2001-7,2010 The SCons Foundation | |
13 # | |
14 # Permission is hereby granted, free of charge, to any person obtaining | |
15 # a copy of this software and associated documentation files (the | |
16 # "Software"), to deal in the Software without restriction, including | |
17 # without limitation the rights to use, copy, modify, merge, publish, | |
18 # distribute, sublicense, and/or sell copies of the Software, and to | |
19 # permit persons to whom the Software is furnished to do so, subject to | |
20 # the following conditions: | |
21 # | |
22 # The above copyright notice and this permission notice shall be included | |
23 # in all copies or substantial portions of the Software. | |
24 # | |
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | |
26 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |
27 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
28 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
29 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
30 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
31 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
32 # | |
33 | |
34 __revision__ = "src/engine/SCons/Tool/python.py 3263 2008/07/31 13:50:51 MatiGruca" | |
35 | |
36 import os | |
37 try: | |
38 import py_compile | |
39 except ImportError: | |
40 raise SCons.Errors.InternalError, "Couldn't import py_compile module" | |
41 try: | |
42 import compileall | |
43 except ImportError: | |
44 raise SCons.Errors.InternalError, "Couldn't import compileall module" | |
45 import glob | |
46 | |
47 import SCons.Action | |
48 import SCons.Builder | |
49 import SCons.Errors | |
50 import SCons.Node | |
51 from SCons.Tool.install import installFunc, add_targets_to_INSTALLED_FILES | |
52 from SCons.Tool.install import copyFunc | |
53 | |
54 ########################################################################## | |
55 # Create Python builder | |
56 def createPythonBuilder(env): | |
57 """ | |
58 This is a utility function that creates the InstallPython | |
59 Builder in an Environment if it's not there already. | |
60 | |
61 If it's there already, we return the existing one. | |
62 | |
63 This builder is based on Install/InstallAs methods. It makes use | |
64 of those builder's functions: installFunc(), and | |
65 add_targets_to_INSTALLED_FILES()). | |
66 """ | |
67 | |
68 try: | |
69 InstallPythonBuilder = env['BUILDERS']['InstallPython'] | |
70 except KeyError: | |
71 installpython_action = SCons.Action.Action(installFunc, '$PYTHON_PYCOMSTR') | |
72 InstallPythonBuilder = SCons.Builder.Builder( | |
73 action=installpython_action, | |
74 src_suffix='$PYTHON_SUFFIX', | |
75 target_factory=env.fs.Entry, | |
76 source_factory=env.fs.Entry, | |
77 multi=1, | |
78 emitter=[add_targets_to_INSTALLED_FILES], | |
79 name='InstallPythonBuilder' | |
80 ) | |
81 | |
82 return InstallPythonBuilder | |
83 | |
84 def InstallPython(env, target=None, source=None): | |
85 """ | |
86 InstallPython creates .pyc or .pyo files for .py source files | |
87 and adds them to the list of targets along with the source files. | |
88 They are later copied to the destination (target) directory. | |
89 | |
90 InstallPython takes a target (destination) directory as its first | |
91 argument and a list of source files/directories as a second argument. | |
92 | |
93 InstallPython returns the list of target files to copy to the | |
94 target directory. | |
95 """ | |
96 try: | |
97 target_nodes = env.arg2nodes(target, env.fs.Dir) | |
98 except TypeError: | |
99 raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the InstallPython() arguments backwards?" % str(dir) | |
100 | |
101 source_nodes = env.arg2nodes(source, env.fs.Entry) | |
102 targets = [] | |
103 | |
104 # import `compileall` module only if there is a dir in sources list | |
105 dir_in_sources = any(entry.isdir() for entry in sources) | |
106 | |
107 compile_py = env['PYTHON_COMPILE'] | |
108 optimize = env['PYTHON_OPTIMIZE'] | |
109 if optimize: | |
110 PYTHON_TARGETSUFFIX = 'o' | |
111 else: | |
112 PYTHON_TARGETSUFFIX = 'c' | |
113 | |
114 for target_node in target_nodes: | |
115 for source_node in source_nodes: | |
116 # add *.py and *.pyc files from a directory to tgt list | |
117 if source_node.isdir() and compile_py: | |
118 compileall.compile_dir(str(source_node), maxlevels=0, quiet=True) | |
119 glob_path = os.path.join(source_node.path, '*.py') | |
120 py_and_pycs = glob.glob(glob_path) + glob.glob(glob_path + 'c') | |
121 for file_name in py_and_pycs: | |
122 target = env.Entry('.'+os.sep+filename, dnode) | |
123 targets.extend(apply(PythonInstallBuilder, (env, target, filename), kw)) | |
124 # add *.py and *.pyo files from a directory to tgt list | |
125 elif isinstance(src, SCons.Node.FS.Dir): | |
126 to_compile = [] | |
127 py_files = glob.glob(src.path + os.sep + '*.py') | |
128 for py_file in py_files: | |
129 to_compile.append(py_file) | |
130 target_path = '.' + os.sep + py_file | |
131 | |
132 # add '.py' file to tgt list | |
133 py_src = env.fs.Entry(py_file) | |
134 py_tgt = env.fs.Entry(target_path, dnode) | |
135 tgt.extend(apply(PIB, (env, py_tgt, py_src), kw)) | |
136 | |
137 # add '.pyo' file to tgt list | |
138 pyo_src = env.fs.Entry(py_file + CPYTHON_TARGETSUFFIX) | |
139 pyo_tgt = env.fs.Entry(target_path + CPYTHON_TARGETSUFFIX, dnode) | |
140 tgt.extend(apply(PIB, (env, pyo_tgt, pyo_src), kw)) | |
141 act = SCons.Action.CommandAction('@$CPYTHON_PYCOM %s' % (' '.join(to_compile))) | |
142 act([], [], env) | |
143 # add single '.py' and '.pyc' or '.pyo' file to tgt list | |
144 else: | |
145 # add '.py' file to tgt list | |
146 target = env.fs.Entry('.'+os.sep+src.path, dnode) | |
147 tgt.extend(apply(PIB, (env, target, src), kw)) | |
148 | |
149 # .pyc or .pyo source and target files | |
150 pyco_src = env.fs.Entry(src.path + CPYTHON_TARGETSUFFIX) | |
151 pyco_tgt = env.fs.Entry(target.path + CPYTHON_TARGETSUFFIX) | |
152 | |
153 if compile_pyc: | |
154 py_compile.compile(src.path) | |
155 else: | |
156 act = SCons.Action.CommandAction('@$CPYTHON_PYCOM %s' % (src.path)) | |
157 act([], [], env) | |
158 | |
159 # add '.pyc' or '.pyo' file to tgt list | |
160 tgt.extend(apply(PIB, (env, pyco_tgt, pyco_src), kw)) | |
161 | |
162 return tgt | |
163 | |
164 def generate(env): | |
165 try: | |
166 env['INSTALL'] | |
167 except KeyError: | |
168 env['INSTALL'] = copyFunc | |
169 | |
170 global InstallPythonBuilder | |
171 InstallPythonBuilder = createPythonBuilder(env) | |
172 | |
173 env['PYTHON_OPTIMIZE'] = False # generate '.pyc' files by default | |
174 env['PYTHON_OPTIMIZE_FLAGS'] = '-O' | |
175 env['PYTHON_COMPILE_CMD'] = "-m py_compile $SOURCES" | |
176 env['PYTHON_PYCOM'] = '$PYTHON ${PYTHON_OPTIMIZE_FLAGS if ' \ | |
177 'PYTHON_OPTIMIZE} $CPYTHON_COMPILE_CMD' | |
178 env['PYTHON_PYCOMSTR'] = 'Install file: "$SOURCE" as "$TARGET"' | |
179 env['PYTHON_SUFFIX'] = '.py' # extension for Python source files | |
180 | |
181 try: | |
182 env.Append(BUILDERS={'InstallPython': InstallPythonBuilder}) | |
183 except AttributeError: | |
184 # Looks like we use a pre-0.98 version of SCons... | |
185 from SCons.Script.SConscript import SConsEnvironment | |
186 SConsEnvironment.InstallPython = InstallPythonBuilder | |
187 | |
188 def exists(env): | |
189 return 1 |