| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | # created 1999/03/13, Greg Ward | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-02 01:49:45 +00:00
										 |  |  | __revision__ = "$Id$" | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | import sys, os, string | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  | from types import IntType | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | from distutils.core import Command | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  | from distutils.errors import DistutilsOptionError | 
					
						
							| 
									
										
										
										
											2000-08-05 01:31:54 +00:00
										 |  |  | from distutils.dir_util import copy_tree | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-23 04:37:11 +00:00
										 |  |  | class install_lib (Command): | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-23 01:55:16 +00:00
										 |  |  |     description = "install all Python modules (extensions and pure Python)" | 
					
						
							| 
									
										
										
										
											2000-01-30 18:34:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |     # The byte-compilation options are a tad confusing.  Here are the | 
					
						
							|  |  |  |     # possible scenarios: | 
					
						
							|  |  |  |     #   1) no compilation at all (--no-compile --no-optimize) | 
					
						
							|  |  |  |     #   2) compile .pyc only (--compile --no-optimize; default) | 
					
						
							|  |  |  |     #   3) compile .pyc and "level 1" .pyo (--compile --optimize) | 
					
						
							|  |  |  |     #   4) compile "level 1" .pyo only (--no-compile --optimize) | 
					
						
							|  |  |  |     #   5) compile .pyc and "level 2" .pyo (--compile --optimize-more) | 
					
						
							|  |  |  |     #   6) compile "level 2" .pyo only (--no-compile --optimize-more) | 
					
						
							|  |  |  |     #  | 
					
						
							|  |  |  |     # The UI for this is two option, 'compile' and 'optimize'. | 
					
						
							|  |  |  |     # 'compile' is strictly boolean, and only decides whether to | 
					
						
							|  |  |  |     # generate .pyc files.  'optimize' is three-way (0, 1, or 2), and | 
					
						
							|  |  |  |     # decides both whether to generate .pyo files and what level of | 
					
						
							|  |  |  |     # optimization to use. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-18 00:25:39 +00:00
										 |  |  |     user_options = [ | 
					
						
							|  |  |  |         ('install-dir=', 'd', "directory to install to"), | 
					
						
							|  |  |  |         ('build-dir=','b', "build directory (where to install from)"), | 
					
						
							| 
									
										
										
										
											2000-09-13 01:02:25 +00:00
										 |  |  |         ('force', 'f', "force installation (overwrite existing files)"), | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |         ('compile', 'c', "compile .py to .pyc [default]"), | 
					
						
							|  |  |  |         ('no-compile', None, "don't compile .py files"), | 
					
						
							|  |  |  |         ('optimize=', 'O', | 
					
						
							|  |  |  |          "also compile with optimization: -O1 for \"python -O\", " | 
					
						
							|  |  |  |          "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), | 
					
						
							| 
									
										
										
										
											2000-05-12 01:46:47 +00:00
										 |  |  |         ('skip-build', None, "skip the build steps"), | 
					
						
							| 
									
										
										
										
											2000-02-18 00:25:39 +00:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											1999-05-02 21:39:13 +00:00
										 |  |  |                 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |     boolean_options = ['force', 'compile', 'skip-build'] | 
					
						
							|  |  |  |     negative_opt = {'no-compile' : 'compile'} | 
					
						
							| 
									
										
										
										
											2000-09-25 01:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-18 00:35:22 +00:00
										 |  |  |     def initialize_options (self): | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  |         # let the 'install' command dictate our installation directory | 
					
						
							| 
									
										
										
										
											1999-09-29 12:38:18 +00:00
										 |  |  |         self.install_dir = None | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  |         self.build_dir = None | 
					
						
							| 
									
										
										
										
											2000-09-13 01:02:25 +00:00
										 |  |  |         self.force = 0 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |         self.compile = None | 
					
						
							|  |  |  |         self.optimize = None | 
					
						
							| 
									
										
										
										
											2000-05-12 01:46:47 +00:00
										 |  |  |         self.skip_build = None | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-18 00:35:22 +00:00
										 |  |  |     def finalize_options (self): | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-09-13 13:58:34 +00:00
										 |  |  |         # Get all the information we need to install pure Python modules | 
					
						
							|  |  |  |         # from the umbrella 'install' command -- build (source) directory, | 
					
						
							|  |  |  |         # install (target) directory, and whether to compile .py files. | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |         self.set_undefined_options('install', | 
					
						
							|  |  |  |                                    ('build_lib', 'build_dir'), | 
					
						
							|  |  |  |                                    ('install_lib', 'install_dir'), | 
					
						
							|  |  |  |                                    ('force', 'force'), | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |                                    ('compile', 'compile'), | 
					
						
							|  |  |  |                                    ('optimize', 'optimize'), | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |                                    ('skip_build', 'skip_build'), | 
					
						
							|  |  |  |                                   ) | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |         if self.compile is None: | 
					
						
							|  |  |  |             self.compile = 1 | 
					
						
							|  |  |  |         if self.optimize is None: | 
					
						
							|  |  |  |             self.optimize = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if type(self.optimize) is not IntType: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 self.optimize = int(self.optimize) | 
					
						
							|  |  |  |                 assert 0 <= self.optimize <= 2 | 
					
						
							|  |  |  |             except (ValueError, AssertionError): | 
					
						
							|  |  |  |                 raise DistutilsOptionError, "optimize must be 0, 1, or 2" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  |     def run (self): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  |         # Make sure we have built everything we need first | 
					
						
							| 
									
										
										
										
											2000-09-23 01:20:19 +00:00
										 |  |  |         self.build() | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         # Install everything: simply dump the entire contents of the build | 
					
						
							|  |  |  |         # directory to the installation directory (that's the beauty of | 
					
						
							|  |  |  |         # having a build directory!) | 
					
						
							|  |  |  |         outfiles = self.install() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # (Optionally) compile .py to .pyc | 
					
						
							| 
									
										
										
										
											2000-10-01 23:50:13 +00:00
										 |  |  |         if outfiles is not None and self.distribution.has_pure_modules(): | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |             self.byte_compile(outfiles) | 
					
						
							| 
									
										
										
										
											2000-09-23 01:20:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # run () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # -- Top-level worker functions ------------------------------------ | 
					
						
							|  |  |  |     # (called from 'run()') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def build (self): | 
					
						
							| 
									
										
										
										
											2000-05-12 01:46:47 +00:00
										 |  |  |         if not self.skip_build: | 
					
						
							|  |  |  |             if self.distribution.has_pure_modules(): | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |                 self.run_command('build_py') | 
					
						
							| 
									
										
										
										
											2000-05-12 01:46:47 +00:00
										 |  |  |             if self.distribution.has_ext_modules(): | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |                 self.run_command('build_ext') | 
					
						
							| 
									
										
										
										
											2000-09-23 01:20:19 +00:00
										 |  |  |          | 
					
						
							|  |  |  |     def install (self): | 
					
						
							| 
									
										
										
										
											2000-05-20 15:08:57 +00:00
										 |  |  |         if os.path.isdir(self.build_dir): | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |             outfiles = self.copy_tree(self.build_dir, self.install_dir) | 
					
						
							| 
									
										
										
										
											2000-05-20 15:08:57 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.warn("'%s' does not exist -- no Python modules to install" % | 
					
						
							|  |  |  |                       self.build_dir) | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2000-09-23 01:20:19 +00:00
										 |  |  |         return outfiles | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |     def byte_compile (self, files): | 
					
						
							|  |  |  |         from distutils.util import byte_compile | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Get the "--root" directory supplied to the "install" command, | 
					
						
							|  |  |  |         # and use it as a prefix to strip off the purported filename | 
					
						
							|  |  |  |         # encoded in bytecode files.  This is far from complete, but it | 
					
						
							|  |  |  |         # should at least generate usable bytecode in RPM distributions. | 
					
						
							|  |  |  |         install_root = self.get_finalized_command('install').root | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.compile: | 
					
						
							|  |  |  |             byte_compile(files, optimize=0, | 
					
						
							|  |  |  |                          force=self.force, | 
					
						
							|  |  |  |                          prefix=install_root, | 
					
						
							|  |  |  |                          verbose=self.verbose, dry_run=self.dry_run) | 
					
						
							|  |  |  |         if self.optimize > 0: | 
					
						
							|  |  |  |             byte_compile(files, optimize=self.optimize, | 
					
						
							|  |  |  |                          force=self.force, | 
					
						
							|  |  |  |                          prefix=install_root, | 
					
						
							|  |  |  |                          verbose=self.verbose, dry_run=self.dry_run) | 
					
						
							| 
									
										
										
										
											1999-03-22 14:55:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-23 01:20:19 +00:00
										 |  |  |     # -- Utility methods ----------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  |     def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not has_any: | 
					
						
							|  |  |  |             return [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |         build_cmd = self.get_finalized_command(build_cmd) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  |         build_files = build_cmd.get_outputs() | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |         build_dir = getattr(build_cmd, cmd_option) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |         prefix_len = len(build_dir) + len(os.sep) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  |         outputs = [] | 
					
						
							|  |  |  |         for file in build_files: | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |             outputs.append(os.path.join(output_dir, file[prefix_len:])) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return outputs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # _mutate_outputs () | 
					
						
							| 
									
										
										
										
											2000-05-13 02:11:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _bytecode_filenames (self, py_filenames): | 
					
						
							|  |  |  |         bytecode_files = [] | 
					
						
							|  |  |  |         for py_file in py_filenames: | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |             if self.compile: | 
					
						
							|  |  |  |                 bytecode_files.append(py_file + "c") | 
					
						
							| 
									
										
										
										
											2000-10-02 02:25:51 +00:00
										 |  |  |             if self.optimize > 0: | 
					
						
							| 
									
										
										
										
											2000-10-02 02:15:08 +00:00
										 |  |  |                 bytecode_files.append(py_file + "o") | 
					
						
							| 
									
										
										
										
											2000-05-13 02:11:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return bytecode_files | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2000-09-23 01:20:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # -- External interface -------------------------------------------- | 
					
						
							|  |  |  |     # (called by outsiders) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  |     def get_outputs (self): | 
					
						
							|  |  |  |         """Return the list of files that would be installed if this command
 | 
					
						
							|  |  |  |         were actually run.  Not affected by the "dry-run" flag or whether | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |         modules have actually been built yet. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  |         pure_outputs = \ | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |             self._mutate_outputs(self.distribution.has_pure_modules(), | 
					
						
							|  |  |  |                                  'build_py', 'build_lib', | 
					
						
							|  |  |  |                                  self.install_dir) | 
					
						
							| 
									
										
										
										
											2000-05-13 02:11:10 +00:00
										 |  |  |         if self.compile: | 
					
						
							|  |  |  |             bytecode_outputs = self._bytecode_filenames(pure_outputs) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             bytecode_outputs = [] | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         ext_outputs = \ | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |             self._mutate_outputs(self.distribution.has_ext_modules(), | 
					
						
							|  |  |  |                                  'build_ext', 'build_lib', | 
					
						
							|  |  |  |                                  self.install_dir) | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-05-13 02:11:10 +00:00
										 |  |  |         return pure_outputs + bytecode_outputs + ext_outputs | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get_outputs () | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-31 02:53:07 +00:00
										 |  |  |     def get_inputs (self): | 
					
						
							|  |  |  |         """Get the list of files that are input to this command, ie. the
 | 
					
						
							|  |  |  |         files that get installed as they are named in the build tree. | 
					
						
							|  |  |  |         The files in this list correspond one-to-one to the output | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |         filenames returned by 'get_outputs()'. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2000-03-31 02:53:07 +00:00
										 |  |  |         inputs = [] | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if self.distribution.has_pure_modules(): | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |             build_py = self.get_finalized_command('build_py') | 
					
						
							|  |  |  |             inputs.extend(build_py.get_outputs()) | 
					
						
							| 
									
										
										
										
											2000-03-31 02:53:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.distribution.has_ext_modules(): | 
					
						
							| 
									
										
										
										
											2000-09-23 01:10:10 +00:00
										 |  |  |             build_ext = self.get_finalized_command('build_ext') | 
					
						
							|  |  |  |             inputs.extend(build_ext.get_outputs()) | 
					
						
							| 
									
										
										
										
											2000-03-31 02:53:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return inputs | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-29 02:17:42 +00:00
										 |  |  | # class install_lib |