]> git.saurik.com Git - wxWidgets.git/blob - wxPython/distutils/command/install_lib.py
Don't use PyThreadState_Swap to get the current tstate, block threads
[wxWidgets.git] / wxPython / distutils / command / install_lib.py
1 # This module should be kept compatible with Python 1.5.2.
2
3 __revision__ = "$Id$"
4
5 import sys, os, string
6 from types import IntType
7 from distutils.core import Command
8 from distutils.errors import DistutilsOptionError
9
10 class install_lib (Command):
11
12 description = "install all Python modules (extensions and pure Python)"
13
14 # The byte-compilation options are a tad confusing. Here are the
15 # possible scenarios:
16 # 1) no compilation at all (--no-compile --no-optimize)
17 # 2) compile .pyc only (--compile --no-optimize; default)
18 # 3) compile .pyc and "level 1" .pyo (--compile --optimize)
19 # 4) compile "level 1" .pyo only (--no-compile --optimize)
20 # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more)
21 # 6) compile "level 2" .pyo only (--no-compile --optimize-more)
22 #
23 # The UI for this is two option, 'compile' and 'optimize'.
24 # 'compile' is strictly boolean, and only decides whether to
25 # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and
26 # decides both whether to generate .pyo files and what level of
27 # optimization to use.
28
29 user_options = [
30 ('install-dir=', 'd', "directory to install to"),
31 ('build-dir=','b', "build directory (where to install from)"),
32 ('force', 'f', "force installation (overwrite existing files)"),
33 ('compile', 'c', "compile .py to .pyc [default]"),
34 ('no-compile', None, "don't compile .py files"),
35 ('optimize=', 'O',
36 "also compile with optimization: -O1 for \"python -O\", "
37 "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
38 ('skip-build', None, "skip the build steps"),
39 ]
40
41 boolean_options = ['force', 'compile', 'skip-build']
42 negative_opt = {'no-compile' : 'compile'}
43
44
45 def initialize_options (self):
46 # let the 'install' command dictate our installation directory
47 self.install_dir = None
48 self.build_dir = None
49 self.force = 0
50 self.compile = None
51 self.optimize = None
52 self.skip_build = None
53
54 def finalize_options (self):
55
56 # Get all the information we need to install pure Python modules
57 # from the umbrella 'install' command -- build (source) directory,
58 # install (target) directory, and whether to compile .py files.
59 self.set_undefined_options('install',
60 ('build_lib', 'build_dir'),
61 ('install_lib', 'install_dir'),
62 ('force', 'force'),
63 ('compile', 'compile'),
64 ('optimize', 'optimize'),
65 ('skip_build', 'skip_build'),
66 )
67
68 if self.compile is None:
69 self.compile = 1
70 if self.optimize is None:
71 self.optimize = 0
72
73 if type(self.optimize) is not IntType:
74 try:
75 self.optimize = int(self.optimize)
76 assert 0 <= self.optimize <= 2
77 except (ValueError, AssertionError):
78 raise DistutilsOptionError, "optimize must be 0, 1, or 2"
79
80 def run (self):
81
82 # Make sure we have built everything we need first
83 self.build()
84
85 # Install everything: simply dump the entire contents of the build
86 # directory to the installation directory (that's the beauty of
87 # having a build directory!)
88 outfiles = self.install()
89
90 # (Optionally) compile .py to .pyc
91 if outfiles is not None and self.distribution.has_pure_modules():
92 self.byte_compile(outfiles)
93
94 # run ()
95
96
97 # -- Top-level worker functions ------------------------------------
98 # (called from 'run()')
99
100 def build (self):
101 if not self.skip_build:
102 if self.distribution.has_pure_modules():
103 self.run_command('build_py')
104 if self.distribution.has_ext_modules():
105 self.run_command('build_ext')
106
107 def install (self):
108 if os.path.isdir(self.build_dir):
109 outfiles = self.copy_tree(self.build_dir, self.install_dir)
110 else:
111 self.warn("'%s' does not exist -- no Python modules to install" %
112 self.build_dir)
113 return
114 return outfiles
115
116 def byte_compile (self, files):
117 from distutils.util import byte_compile
118
119 # Get the "--root" directory supplied to the "install" command,
120 # and use it as a prefix to strip off the purported filename
121 # encoded in bytecode files. This is far from complete, but it
122 # should at least generate usable bytecode in RPM distributions.
123 install_root = self.get_finalized_command('install').root
124
125 if self.compile:
126 byte_compile(files, optimize=0,
127 force=self.force, prefix=install_root,
128 dry_run=self.dry_run)
129 if self.optimize > 0:
130 byte_compile(files, optimize=self.optimize,
131 force=self.force, prefix=install_root,
132 verbose=self.verbose, dry_run=self.dry_run)
133
134
135 # -- Utility methods -----------------------------------------------
136
137 def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
138
139 if not has_any:
140 return []
141
142 build_cmd = self.get_finalized_command(build_cmd)
143 build_files = build_cmd.get_outputs()
144 build_dir = getattr(build_cmd, cmd_option)
145
146 prefix_len = len(build_dir) + len(os.sep)
147 outputs = []
148 for file in build_files:
149 outputs.append(os.path.join(output_dir, file[prefix_len:]))
150
151 return outputs
152
153 # _mutate_outputs ()
154
155 def _bytecode_filenames (self, py_filenames):
156 bytecode_files = []
157 for py_file in py_filenames:
158 if self.compile:
159 bytecode_files.append(py_file + "c")
160 if self.optimize > 0:
161 bytecode_files.append(py_file + "o")
162
163 return bytecode_files
164
165
166 # -- External interface --------------------------------------------
167 # (called by outsiders)
168
169 def get_outputs (self):
170 """Return the list of files that would be installed if this command
171 were actually run. Not affected by the "dry-run" flag or whether
172 modules have actually been built yet.
173 """
174 pure_outputs = \
175 self._mutate_outputs(self.distribution.has_pure_modules(),
176 'build_py', 'build_lib',
177 self.install_dir)
178 if self.compile:
179 bytecode_outputs = self._bytecode_filenames(pure_outputs)
180 else:
181 bytecode_outputs = []
182
183 ext_outputs = \
184 self._mutate_outputs(self.distribution.has_ext_modules(),
185 'build_ext', 'build_lib',
186 self.install_dir)
187
188 return pure_outputs + bytecode_outputs + ext_outputs
189
190 # get_outputs ()
191
192 def get_inputs (self):
193 """Get the list of files that are input to this command, ie. the
194 files that get installed as they are named in the build tree.
195 The files in this list correspond one-to-one to the output
196 filenames returned by 'get_outputs()'.
197 """
198 inputs = []
199
200 if self.distribution.has_pure_modules():
201 build_py = self.get_finalized_command('build_py')
202 inputs.extend(build_py.get_outputs())
203
204 if self.distribution.has_ext_modules():
205 build_ext = self.get_finalized_command('build_ext')
206 inputs.extend(build_ext.get_outputs())
207
208 return inputs
209
210 # class install_lib