+++ /dev/null
-"""distutils.command.install_lib\r
-\r
-Implements the Distutils 'install_lib' command\r
-(install all Python modules)."""\r
-\r
-__revision__ = "$Id$"\r
-\r
-import os\r
-import sys\r
-\r
-from distutils.core import Command\r
-from distutils.errors import DistutilsOptionError\r
-\r
-\r
-# Extension for Python source files.\r
-if hasattr(os, 'extsep'):\r
- PYTHON_SOURCE_EXTENSION = os.extsep + "py"\r
-else:\r
- PYTHON_SOURCE_EXTENSION = ".py"\r
-\r
-class install_lib(Command):\r
-\r
- description = "install all Python modules (extensions and pure Python)"\r
-\r
- # The byte-compilation options are a tad confusing. Here are the\r
- # possible scenarios:\r
- # 1) no compilation at all (--no-compile --no-optimize)\r
- # 2) compile .pyc only (--compile --no-optimize; default)\r
- # 3) compile .pyc and "level 1" .pyo (--compile --optimize)\r
- # 4) compile "level 1" .pyo only (--no-compile --optimize)\r
- # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more)\r
- # 6) compile "level 2" .pyo only (--no-compile --optimize-more)\r
- #\r
- # The UI for this is two option, 'compile' and 'optimize'.\r
- # 'compile' is strictly boolean, and only decides whether to\r
- # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and\r
- # decides both whether to generate .pyo files and what level of\r
- # optimization to use.\r
-\r
- user_options = [\r
- ('install-dir=', 'd', "directory to install to"),\r
- ('build-dir=','b', "build directory (where to install from)"),\r
- ('force', 'f', "force installation (overwrite existing files)"),\r
- ('compile', 'c', "compile .py to .pyc [default]"),\r
- ('no-compile', None, "don't compile .py files"),\r
- ('optimize=', 'O',\r
- "also compile with optimization: -O1 for \"python -O\", "\r
- "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),\r
- ('skip-build', None, "skip the build steps"),\r
- ]\r
-\r
- boolean_options = ['force', 'compile', 'skip-build']\r
- negative_opt = {'no-compile' : 'compile'}\r
-\r
- def initialize_options(self):\r
- # let the 'install' command dictate our installation directory\r
- self.install_dir = None\r
- self.build_dir = None\r
- self.force = 0\r
- self.compile = None\r
- self.optimize = None\r
- self.skip_build = None\r
-\r
- def finalize_options(self):\r
- # Get all the information we need to install pure Python modules\r
- # from the umbrella 'install' command -- build (source) directory,\r
- # install (target) directory, and whether to compile .py files.\r
- self.set_undefined_options('install',\r
- ('build_lib', 'build_dir'),\r
- ('install_lib', 'install_dir'),\r
- ('force', 'force'),\r
- ('compile', 'compile'),\r
- ('optimize', 'optimize'),\r
- ('skip_build', 'skip_build'),\r
- )\r
-\r
- if self.compile is None:\r
- self.compile = 1\r
- if self.optimize is None:\r
- self.optimize = 0\r
-\r
- if not isinstance(self.optimize, int):\r
- try:\r
- self.optimize = int(self.optimize)\r
- if self.optimize not in (0, 1, 2):\r
- raise AssertionError\r
- except (ValueError, AssertionError):\r
- raise DistutilsOptionError, "optimize must be 0, 1, or 2"\r
-\r
- def run(self):\r
- # Make sure we have built everything we need first\r
- self.build()\r
-\r
- # Install everything: simply dump the entire contents of the build\r
- # directory to the installation directory (that's the beauty of\r
- # having a build directory!)\r
- outfiles = self.install()\r
-\r
- # (Optionally) compile .py to .pyc\r
- if outfiles is not None and self.distribution.has_pure_modules():\r
- self.byte_compile(outfiles)\r
-\r
- # -- Top-level worker functions ------------------------------------\r
- # (called from 'run()')\r
-\r
- def build(self):\r
- if not self.skip_build:\r
- if self.distribution.has_pure_modules():\r
- self.run_command('build_py')\r
- if self.distribution.has_ext_modules():\r
- self.run_command('build_ext')\r
-\r
- def install(self):\r
- if os.path.isdir(self.build_dir):\r
- outfiles = self.copy_tree(self.build_dir, self.install_dir)\r
- else:\r
- self.warn("'%s' does not exist -- no Python modules to install" %\r
- self.build_dir)\r
- return\r
- return outfiles\r
-\r
- def byte_compile(self, files):\r
- if sys.dont_write_bytecode:\r
- self.warn('byte-compiling is disabled, skipping.')\r
- return\r
-\r
- from distutils.util import byte_compile\r
-\r
- # Get the "--root" directory supplied to the "install" command,\r
- # and use it as a prefix to strip off the purported filename\r
- # encoded in bytecode files. This is far from complete, but it\r
- # should at least generate usable bytecode in RPM distributions.\r
- install_root = self.get_finalized_command('install').root\r
-\r
- if self.compile:\r
- byte_compile(files, optimize=0,\r
- force=self.force, prefix=install_root,\r
- dry_run=self.dry_run)\r
- if self.optimize > 0:\r
- byte_compile(files, optimize=self.optimize,\r
- force=self.force, prefix=install_root,\r
- verbose=self.verbose, dry_run=self.dry_run)\r
-\r
-\r
- # -- Utility methods -----------------------------------------------\r
-\r
- def _mutate_outputs(self, has_any, build_cmd, cmd_option, output_dir):\r
- if not has_any:\r
- return []\r
-\r
- build_cmd = self.get_finalized_command(build_cmd)\r
- build_files = build_cmd.get_outputs()\r
- build_dir = getattr(build_cmd, cmd_option)\r
-\r
- prefix_len = len(build_dir) + len(os.sep)\r
- outputs = []\r
- for file in build_files:\r
- outputs.append(os.path.join(output_dir, file[prefix_len:]))\r
-\r
- return outputs\r
-\r
- def _bytecode_filenames(self, py_filenames):\r
- bytecode_files = []\r
- for py_file in py_filenames:\r
- # Since build_py handles package data installation, the\r
- # list of outputs can contain more than just .py files.\r
- # Make sure we only report bytecode for the .py files.\r
- ext = os.path.splitext(os.path.normcase(py_file))[1]\r
- if ext != PYTHON_SOURCE_EXTENSION:\r
- continue\r
- if self.compile:\r
- bytecode_files.append(py_file + "c")\r
- if self.optimize > 0:\r
- bytecode_files.append(py_file + "o")\r
-\r
- return bytecode_files\r
-\r
-\r
- # -- External interface --------------------------------------------\r
- # (called by outsiders)\r
-\r
- def get_outputs(self):\r
- """Return the list of files that would be installed if this command\r
- were actually run. Not affected by the "dry-run" flag or whether\r
- modules have actually been built yet.\r
- """\r
- pure_outputs = \\r
- self._mutate_outputs(self.distribution.has_pure_modules(),\r
- 'build_py', 'build_lib',\r
- self.install_dir)\r
- if self.compile:\r
- bytecode_outputs = self._bytecode_filenames(pure_outputs)\r
- else:\r
- bytecode_outputs = []\r
-\r
- ext_outputs = \\r
- self._mutate_outputs(self.distribution.has_ext_modules(),\r
- 'build_ext', 'build_lib',\r
- self.install_dir)\r
-\r
- return pure_outputs + bytecode_outputs + ext_outputs\r
-\r
- def get_inputs(self):\r
- """Get the list of files that are input to this command, ie. the\r
- files that get installed as they are named in the build tree.\r
- The files in this list correspond one-to-one to the output\r
- filenames returned by 'get_outputs()'.\r
- """\r
- inputs = []\r
-\r
- if self.distribution.has_pure_modules():\r
- build_py = self.get_finalized_command('build_py')\r
- inputs.extend(build_py.get_outputs())\r
-\r
- if self.distribution.has_ext_modules():\r
- build_ext = self.get_finalized_command('build_ext')\r
- inputs.extend(build_ext.get_outputs())\r
-\r
- return inputs\r