blob: b104fa9cfcca0a472238c2e1dc00feb55c9088ca [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
Greg Wardf84fb662000-09-23 01:20:19 +000049 self.build()
50
51 # Install everything: simply dump the entire contents of the build
52 # directory to the installation directory (that's the beauty of
53 # having a build directory!)
54 outfiles = self.install()
55
56 # (Optionally) compile .py to .pyc
57 self.bytecompile(outfiles)
58
59 # run ()
60
61
62 # -- Top-level worker functions ------------------------------------
63 # (called from 'run()')
64
65 def build (self):
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000066 if not self.skip_build:
67 if self.distribution.has_pure_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +000068 self.run_command('build_py')
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000069 if self.distribution.has_ext_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +000070 self.run_command('build_ext')
Greg Wardf84fb662000-09-23 01:20:19 +000071
72 def install (self):
Greg Wardf355d472000-05-20 15:08:57 +000073 if os.path.isdir(self.build_dir):
Greg Ward7b87c0e2000-09-23 01:10:10 +000074 outfiles = self.copy_tree(self.build_dir, self.install_dir)
Greg Wardf355d472000-05-20 15:08:57 +000075 else:
76 self.warn("'%s' does not exist -- no Python modules to install" %
77 self.build_dir)
78 return
Greg Wardf84fb662000-09-23 01:20:19 +000079 return outfiles
Greg Warde5dfba52000-03-29 02:17:42 +000080
Greg Wardf84fb662000-09-23 01:20:19 +000081 def bytecompile (self, files):
Greg Ward0f726951999-05-02 21:39:13 +000082 # XXX hey! we can't control whether we optimize or not; that's up
83 # to the invocation of the current Python interpreter (at least
84 # according to the py_compile docs). That sucks.
Greg Ward0f726951999-05-02 21:39:13 +000085 if self.compile:
86 from py_compile import compile
87
Greg Wardf84fb662000-09-23 01:20:19 +000088 for f in files:
Greg Ward440e2f51999-08-29 18:19:37 +000089 # only compile the file if it is actually a .py file
90 if f[-3:] == '.py':
Greg Warded8a0e02000-03-29 03:29:34 +000091 out_fn = f + (__debug__ and "c" or "o")
92 compile_msg = "byte-compiling %s to %s" % \
Greg Ward7b87c0e2000-09-23 01:10:10 +000093 (f, os.path.basename(out_fn))
Greg Ward90c74cc2000-08-02 01:34:18 +000094 skip_msg = "skipping byte-compilation of %s" % f
Greg Ward7b87c0e2000-09-23 01:10:10 +000095 self.make_file(f, out_fn, compile, (f,),
96 compile_msg, skip_msg)
Greg Ward13ae1c81999-03-22 14:55:25 +000097
Greg Warde5dfba52000-03-29 02:17:42 +000098
Greg Wardf84fb662000-09-23 01:20:19 +000099 # -- Utility methods -----------------------------------------------
100
Greg Warde5dfba52000-03-29 02:17:42 +0000101 def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
102
103 if not has_any:
104 return []
105
Greg Ward7b87c0e2000-09-23 01:10:10 +0000106 build_cmd = self.get_finalized_command(build_cmd)
Greg Warde5dfba52000-03-29 02:17:42 +0000107 build_files = build_cmd.get_outputs()
Greg Ward7b87c0e2000-09-23 01:10:10 +0000108 build_dir = getattr(build_cmd, cmd_option)
Greg Warde5dfba52000-03-29 02:17:42 +0000109
Greg Ward7b87c0e2000-09-23 01:10:10 +0000110 prefix_len = len(build_dir) + len(os.sep)
Greg Warde5dfba52000-03-29 02:17:42 +0000111 outputs = []
112 for file in build_files:
Greg Ward7b87c0e2000-09-23 01:10:10 +0000113 outputs.append(os.path.join(output_dir, file[prefix_len:]))
Greg Warde5dfba52000-03-29 02:17:42 +0000114
115 return outputs
116
117 # _mutate_outputs ()
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000118
119 def _bytecode_filenames (self, py_filenames):
120 bytecode_files = []
121 for py_file in py_filenames:
122 bytecode = py_file + (__debug__ and "c" or "o")
123 bytecode_files.append(bytecode)
124
125 return bytecode_files
Greg Warde5dfba52000-03-29 02:17:42 +0000126
Greg Wardf84fb662000-09-23 01:20:19 +0000127
128 # -- External interface --------------------------------------------
129 # (called by outsiders)
130
Greg Warde5dfba52000-03-29 02:17:42 +0000131 def get_outputs (self):
132 """Return the list of files that would be installed if this command
133 were actually run. Not affected by the "dry-run" flag or whether
Greg Ward7b87c0e2000-09-23 01:10:10 +0000134 modules have actually been built yet.
135 """
Greg Warde5dfba52000-03-29 02:17:42 +0000136 pure_outputs = \
Greg Ward7b87c0e2000-09-23 01:10:10 +0000137 self._mutate_outputs(self.distribution.has_pure_modules(),
138 'build_py', 'build_lib',
139 self.install_dir)
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000140 if self.compile:
141 bytecode_outputs = self._bytecode_filenames(pure_outputs)
142 else:
143 bytecode_outputs = []
Greg Warde5dfba52000-03-29 02:17:42 +0000144
145 ext_outputs = \
Greg Ward7b87c0e2000-09-23 01:10:10 +0000146 self._mutate_outputs(self.distribution.has_ext_modules(),
147 'build_ext', 'build_lib',
148 self.install_dir)
Greg Warde5dfba52000-03-29 02:17:42 +0000149
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000150 return pure_outputs + bytecode_outputs + ext_outputs
Greg Warde5dfba52000-03-29 02:17:42 +0000151
152 # get_outputs ()
153
Greg Ward1aab6e92000-03-31 02:53:07 +0000154 def get_inputs (self):
155 """Get the list of files that are input to this command, ie. the
156 files that get installed as they are named in the build tree.
157 The files in this list correspond one-to-one to the output
Greg Ward7b87c0e2000-09-23 01:10:10 +0000158 filenames returned by 'get_outputs()'.
159 """
Greg Ward1aab6e92000-03-31 02:53:07 +0000160 inputs = []
161
162 if self.distribution.has_pure_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +0000163 build_py = self.get_finalized_command('build_py')
164 inputs.extend(build_py.get_outputs())
Greg Ward1aab6e92000-03-31 02:53:07 +0000165
166 if self.distribution.has_ext_modules():
Greg Ward7b87c0e2000-09-23 01:10:10 +0000167 build_ext = self.get_finalized_command('build_ext')
168 inputs.extend(build_ext.get_outputs())
Greg Ward1aab6e92000-03-31 02:53:07 +0000169
170 return inputs
Greg Ward1aab6e92000-03-31 02:53:07 +0000171
Greg Warde5dfba52000-03-29 02:17:42 +0000172# class install_lib