blob: dac644ee68f7ce5525d7bf6c734364f123e52428 [file] [log] [blame]
Greg Ward13ae1c81999-03-22 14:55:25 +00001# created 1999/03/13, Greg Ward
2
Greg Ward3ce77fd2000-03-02 01:49:45 +00003__revision__ = "$Id$"
Greg Ward13ae1c81999-03-22 14:55:25 +00004
Greg Warde5dfba52000-03-29 02:17:42 +00005import sys, os, string
Greg Ward13ae1c81999-03-22 14:55:25 +00006from distutils.core import Command
Greg Wardab3a0f32000-08-05 01:31:54 +00007from distutils.dir_util import copy_tree
Greg Ward13ae1c81999-03-22 14:55:25 +00008
Greg Ward297dd9f2000-03-23 04:37:11 +00009class install_lib (Command):
Greg Ward13ae1c81999-03-22 14:55:25 +000010
Greg Wardd7ad5032000-05-23 01:55:16 +000011 description = "install all Python modules (extensions and pure Python)"
Greg Ward37bc8152000-01-30 18:34:15 +000012
Greg Wardbbeceea2000-02-18 00:25:39 +000013 user_options = [
14 ('install-dir=', 'd', "directory to install to"),
15 ('build-dir=','b', "build directory (where to install from)"),
Greg Ward3a0310a2000-09-13 01:02:25 +000016 ('force', 'f', "force installation (overwrite existing files)"),
Greg Wardbbeceea2000-02-18 00:25:39 +000017 ('compile', 'c', "compile .py to .pyc"),
18 ('optimize', 'o', "compile .py to .pyo (optimized)"),
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000019 ('skip-build', None, "skip the build steps"),
Greg Wardbbeceea2000-02-18 00:25:39 +000020 ]
Greg Ward0f726951999-05-02 21:39:13 +000021
Greg Ward13ae1c81999-03-22 14:55:25 +000022
Greg Warde01149c2000-02-18 00:35:22 +000023 def initialize_options (self):
Greg Ward13ae1c81999-03-22 14:55:25 +000024 # let the 'install' command dictate our installation directory
Greg Warde6ac2fc1999-09-29 12:38:18 +000025 self.install_dir = None
Greg Ward13ae1c81999-03-22 14:55:25 +000026 self.build_dir = None
Greg Ward3a0310a2000-09-13 01:02:25 +000027 self.force = 0
Greg Ward0f726951999-05-02 21:39:13 +000028 self.compile = 1
29 self.optimize = 1
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000030 self.skip_build = None
Greg Ward13ae1c81999-03-22 14:55:25 +000031
Greg Warde01149c2000-02-18 00:35:22 +000032 def finalize_options (self):
Greg Ward13ae1c81999-03-22 14:55:25 +000033
Greg Wardfa4eb181999-09-13 13:58:34 +000034 # Get all the information we need to install pure Python modules
35 # from the umbrella 'install' command -- build (source) directory,
36 # install (target) directory, and whether to compile .py files.
Greg Ward7b87c0e2000-09-23 01:10:10 +000037 self.set_undefined_options('install',
38 ('build_lib', 'build_dir'),
39 ('install_lib', 'install_dir'),
40 ('force', 'force'),
41 ('compile_py', 'compile'),
42 ('optimize_py', 'optimize'),
43 ('skip_build', 'skip_build'),
44 )
Greg Ward13ae1c81999-03-22 14:55:25 +000045
46 def run (self):
47
Greg Warde5dfba52000-03-29 02:17:42 +000048 # Make sure we have built everything we need first
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000049 if not self.skip_build:
50 if self.distribution.has_pure_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +000051 self.run_command('build_py')
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000052 if self.distribution.has_ext_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +000053 self.run_command('build_ext')
Greg Ward7478a482000-01-30 15:07:56 +000054
Greg Ward4f08e4f2000-02-26 00:49:04 +000055 # Install everything: simply dump the entire contents of the build
56 # directory to the installation directory (that's the beauty of
57 # having a build directory!)
Greg Wardf355d472000-05-20 15:08:57 +000058 if os.path.isdir(self.build_dir):
Greg Ward7b87c0e2000-09-23 01:10:10 +000059 outfiles = self.copy_tree(self.build_dir, self.install_dir)
Greg Wardf355d472000-05-20 15:08:57 +000060 else:
61 self.warn("'%s' does not exist -- no Python modules to install" %
62 self.build_dir)
63 return
Greg Warde5dfba52000-03-29 02:17:42 +000064
Greg Ward0f726951999-05-02 21:39:13 +000065 # (Optionally) compile .py to .pyc
66 # XXX hey! we can't control whether we optimize or not; that's up
67 # to the invocation of the current Python interpreter (at least
68 # according to the py_compile docs). That sucks.
69
70 if self.compile:
71 from py_compile import compile
72
73 for f in outfiles:
Greg Ward440e2f51999-08-29 18:19:37 +000074 # only compile the file if it is actually a .py file
75 if f[-3:] == '.py':
Greg Warded8a0e02000-03-29 03:29:34 +000076 out_fn = f + (__debug__ and "c" or "o")
77 compile_msg = "byte-compiling %s to %s" % \
Greg Ward7b87c0e2000-09-23 01:10:10 +000078 (f, os.path.basename(out_fn))
Greg Ward90c74cc2000-08-02 01:34:18 +000079 skip_msg = "skipping byte-compilation of %s" % f
Greg Ward7b87c0e2000-09-23 01:10:10 +000080 self.make_file(f, out_fn, compile, (f,),
81 compile_msg, skip_msg)
Greg Ward13ae1c81999-03-22 14:55:25 +000082 # run ()
83
Greg Warde5dfba52000-03-29 02:17:42 +000084
85 def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
86
87 if not has_any:
88 return []
89
Greg Ward7b87c0e2000-09-23 01:10:10 +000090 build_cmd = self.get_finalized_command(build_cmd)
Greg Warde5dfba52000-03-29 02:17:42 +000091 build_files = build_cmd.get_outputs()
Greg Ward7b87c0e2000-09-23 01:10:10 +000092 build_dir = getattr(build_cmd, cmd_option)
Greg Warde5dfba52000-03-29 02:17:42 +000093
Greg Ward7b87c0e2000-09-23 01:10:10 +000094 prefix_len = len(build_dir) + len(os.sep)
Greg Warde5dfba52000-03-29 02:17:42 +000095 outputs = []
96 for file in build_files:
Greg Ward7b87c0e2000-09-23 01:10:10 +000097 outputs.append(os.path.join(output_dir, file[prefix_len:]))
Greg Warde5dfba52000-03-29 02:17:42 +000098
99 return outputs
100
101 # _mutate_outputs ()
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000102
103 def _bytecode_filenames (self, py_filenames):
104 bytecode_files = []
105 for py_file in py_filenames:
106 bytecode = py_file + (__debug__ and "c" or "o")
107 bytecode_files.append(bytecode)
108
109 return bytecode_files
Greg Warde5dfba52000-03-29 02:17:42 +0000110
111 def get_outputs (self):
112 """Return the list of files that would be installed if this command
113 were actually run. Not affected by the "dry-run" flag or whether
Greg Ward7b87c0e2000-09-23 01:10:10 +0000114 modules have actually been built yet.
115 """
Greg Warde5dfba52000-03-29 02:17:42 +0000116 pure_outputs = \
Greg Ward7b87c0e2000-09-23 01:10:10 +0000117 self._mutate_outputs(self.distribution.has_pure_modules(),
118 'build_py', 'build_lib',
119 self.install_dir)
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000120 if self.compile:
121 bytecode_outputs = self._bytecode_filenames(pure_outputs)
122 else:
123 bytecode_outputs = []
Greg Warde5dfba52000-03-29 02:17:42 +0000124
125 ext_outputs = \
Greg Ward7b87c0e2000-09-23 01:10:10 +0000126 self._mutate_outputs(self.distribution.has_ext_modules(),
127 'build_ext', 'build_lib',
128 self.install_dir)
Greg Warde5dfba52000-03-29 02:17:42 +0000129
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000130 return pure_outputs + bytecode_outputs + ext_outputs
Greg Warde5dfba52000-03-29 02:17:42 +0000131
132 # get_outputs ()
133
Greg Ward1aab6e92000-03-31 02:53:07 +0000134 def get_inputs (self):
135 """Get the list of files that are input to this command, ie. the
136 files that get installed as they are named in the build tree.
137 The files in this list correspond one-to-one to the output
Greg Ward7b87c0e2000-09-23 01:10:10 +0000138 filenames returned by 'get_outputs()'.
139 """
Greg Ward1aab6e92000-03-31 02:53:07 +0000140 inputs = []
141
142 if self.distribution.has_pure_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +0000143 build_py = self.get_finalized_command('build_py')
144 inputs.extend(build_py.get_outputs())
Greg Ward1aab6e92000-03-31 02:53:07 +0000145
146 if self.distribution.has_ext_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +0000147 build_ext = self.get_finalized_command('build_ext')
148 inputs.extend(build_ext.get_outputs())
Greg Ward1aab6e92000-03-31 02:53:07 +0000149
150 return inputs
Greg Ward1aab6e92000-03-31 02:53:07 +0000151
Greg Warde5dfba52000-03-29 02:17:42 +0000152# class install_lib