PyXR

c:\python24\lib \ distutils \ command \ install_lib.py



0001 # This module should be kept compatible with Python 1.5.2.
0002 
0003 __revision__ = "$Id: install_lib.py,v 1.43 2004/07/28 14:55:10 fdrake Exp $"
0004 
0005 import sys, os, string
0006 from types import IntType
0007 from distutils.core import Command
0008 from distutils.errors import DistutilsOptionError
0009 
0010 
0011 # Extension for Python source files.
0012 PYTHON_SOURCE_EXTENSION = os.extsep + "py"
0013 
0014 
0015 class install_lib (Command):
0016 
0017     description = "install all Python modules (extensions and pure Python)"
0018 
0019     # The byte-compilation options are a tad confusing.  Here are the
0020     # possible scenarios:
0021     #   1) no compilation at all (--no-compile --no-optimize)
0022     #   2) compile .pyc only (--compile --no-optimize; default)
0023     #   3) compile .pyc and "level 1" .pyo (--compile --optimize)
0024     #   4) compile "level 1" .pyo only (--no-compile --optimize)
0025     #   5) compile .pyc and "level 2" .pyo (--compile --optimize-more)
0026     #   6) compile "level 2" .pyo only (--no-compile --optimize-more)
0027     #
0028     # The UI for this is two option, 'compile' and 'optimize'.
0029     # 'compile' is strictly boolean, and only decides whether to
0030     # generate .pyc files.  'optimize' is three-way (0, 1, or 2), and
0031     # decides both whether to generate .pyo files and what level of
0032     # optimization to use.
0033 
0034     user_options = [
0035         ('install-dir=', 'd', "directory to install to"),
0036         ('build-dir=','b', "build directory (where to install from)"),
0037         ('force', 'f', "force installation (overwrite existing files)"),
0038         ('compile', 'c', "compile .py to .pyc [default]"),
0039         ('no-compile', None, "don't compile .py files"),
0040         ('optimize=', 'O',
0041          "also compile with optimization: -O1 for \"python -O\", "
0042          "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
0043         ('skip-build', None, "skip the build steps"),
0044         ]
0045 
0046     boolean_options = ['force', 'compile', 'skip-build']
0047     negative_opt = {'no-compile' : 'compile'}
0048 
0049 
0050     def initialize_options (self):
0051         # let the 'install' command dictate our installation directory
0052         self.install_dir = None
0053         self.build_dir = None
0054         self.force = 0
0055         self.compile = None
0056         self.optimize = None
0057         self.skip_build = None
0058 
0059     def finalize_options (self):
0060 
0061         # Get all the information we need to install pure Python modules
0062         # from the umbrella 'install' command -- build (source) directory,
0063         # install (target) directory, and whether to compile .py files.
0064         self.set_undefined_options('install',
0065                                    ('build_lib', 'build_dir'),
0066                                    ('install_lib', 'install_dir'),
0067                                    ('force', 'force'),
0068                                    ('compile', 'compile'),
0069                                    ('optimize', 'optimize'),
0070                                    ('skip_build', 'skip_build'),
0071                                   )
0072 
0073         if self.compile is None:
0074             self.compile = 1
0075         if self.optimize is None:
0076             self.optimize = 0
0077 
0078         if type(self.optimize) is not IntType:
0079             try:
0080                 self.optimize = int(self.optimize)
0081                 assert 0 <= self.optimize <= 2
0082             except (ValueError, AssertionError):
0083                 raise DistutilsOptionError, "optimize must be 0, 1, or 2"
0084 
0085     def run (self):
0086 
0087         # Make sure we have built everything we need first
0088         self.build()
0089 
0090         # Install everything: simply dump the entire contents of the build
0091         # directory to the installation directory (that's the beauty of
0092         # having a build directory!)
0093         outfiles = self.install()
0094 
0095         # (Optionally) compile .py to .pyc
0096         if outfiles is not None and self.distribution.has_pure_modules():
0097             self.byte_compile(outfiles)
0098 
0099     # run ()
0100 
0101 
0102     # -- Top-level worker functions ------------------------------------
0103     # (called from 'run()')
0104 
0105     def build (self):
0106         if not self.skip_build:
0107             if self.distribution.has_pure_modules():
0108                 self.run_command('build_py')
0109             if self.distribution.has_ext_modules():
0110                 self.run_command('build_ext')
0111 
0112     def install (self):
0113         if os.path.isdir(self.build_dir):
0114             outfiles = self.copy_tree(self.build_dir, self.install_dir)
0115         else:
0116             self.warn("'%s' does not exist -- no Python modules to install" %
0117                       self.build_dir)
0118             return
0119         return outfiles
0120 
0121     def byte_compile (self, files):
0122         from distutils.util import byte_compile
0123 
0124         # Get the "--root" directory supplied to the "install" command,
0125         # and use it as a prefix to strip off the purported filename
0126         # encoded in bytecode files.  This is far from complete, but it
0127         # should at least generate usable bytecode in RPM distributions.
0128         install_root = self.get_finalized_command('install').root
0129 
0130         if self.compile:
0131             byte_compile(files, optimize=0,
0132                          force=self.force, prefix=install_root,
0133                          dry_run=self.dry_run)
0134         if self.optimize > 0:
0135             byte_compile(files, optimize=self.optimize,
0136                          force=self.force, prefix=install_root,
0137                          verbose=self.verbose, dry_run=self.dry_run)
0138 
0139 
0140     # -- Utility methods -----------------------------------------------
0141 
0142     def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
0143 
0144         if not has_any:
0145             return []
0146 
0147         build_cmd = self.get_finalized_command(build_cmd)
0148         build_files = build_cmd.get_outputs()
0149         build_dir = getattr(build_cmd, cmd_option)
0150 
0151         prefix_len = len(build_dir) + len(os.sep)
0152         outputs = []
0153         for file in build_files:
0154             outputs.append(os.path.join(output_dir, file[prefix_len:]))
0155 
0156         return outputs
0157 
0158     # _mutate_outputs ()
0159 
0160     def _bytecode_filenames (self, py_filenames):
0161         bytecode_files = []
0162         for py_file in py_filenames:
0163             # Since build_py handles package data installation, the
0164             # list of outputs can contain more than just .py files.
0165             # Make sure we only report bytecode for the .py files.
0166             ext = os.path.splitext(os.path.normcase(py_file))[1]
0167             if ext != PYTHON_SOURCE_EXTENSION:
0168                 continue
0169             if self.compile:
0170                 bytecode_files.append(py_file + "c")
0171             if self.optimize > 0:
0172                 bytecode_files.append(py_file + "o")
0173 
0174         return bytecode_files
0175 
0176 
0177     # -- External interface --------------------------------------------
0178     # (called by outsiders)
0179 
0180     def get_outputs (self):
0181         """Return the list of files that would be installed if this command
0182         were actually run.  Not affected by the "dry-run" flag or whether
0183         modules have actually been built yet.
0184         """
0185         pure_outputs = \
0186             self._mutate_outputs(self.distribution.has_pure_modules(),
0187                                  'build_py', 'build_lib',
0188                                  self.install_dir)
0189         if self.compile:
0190             bytecode_outputs = self._bytecode_filenames(pure_outputs)
0191         else:
0192             bytecode_outputs = []
0193 
0194         ext_outputs = \
0195             self._mutate_outputs(self.distribution.has_ext_modules(),
0196                                  'build_ext', 'build_lib',
0197                                  self.install_dir)
0198 
0199         return pure_outputs + bytecode_outputs + ext_outputs
0200 
0201     # get_outputs ()
0202 
0203     def get_inputs (self):
0204         """Get the list of files that are input to this command, ie. the
0205         files that get installed as they are named in the build tree.
0206         The files in this list correspond one-to-one to the output
0207         filenames returned by 'get_outputs()'.
0208         """
0209         inputs = []
0210 
0211         if self.distribution.has_pure_modules():
0212             build_py = self.get_finalized_command('build_py')
0213             inputs.extend(build_py.get_outputs())
0214 
0215         if self.distribution.has_ext_modules():
0216             build_ext = self.get_finalized_command('build_ext')
0217             inputs.extend(build_ext.get_outputs())
0218 
0219         return inputs
0220 
0221 # class install_lib
0222 

Generated by PyXR 0.9.4
SourceForge.net Logo