blob: 1c15db14945d4dd1744c02c5dd25959d7be6716c [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
7from distutils.util import copy_tree
8
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)"),
16 ('compile', 'c', "compile .py to .pyc"),
17 ('optimize', 'o', "compile .py to .pyo (optimized)"),
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000018 ('skip-build', None, "skip the build steps"),
Greg Wardbbeceea2000-02-18 00:25:39 +000019 ]
Greg Ward0f726951999-05-02 21:39:13 +000020
Greg Ward13ae1c81999-03-22 14:55:25 +000021
Greg Warde01149c2000-02-18 00:35:22 +000022 def initialize_options (self):
Greg Ward13ae1c81999-03-22 14:55:25 +000023 # let the 'install' command dictate our installation directory
Greg Warde6ac2fc1999-09-29 12:38:18 +000024 self.install_dir = None
Greg Ward13ae1c81999-03-22 14:55:25 +000025 self.build_dir = None
Greg Ward0f726951999-05-02 21:39:13 +000026 self.compile = 1
27 self.optimize = 1
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000028 self.skip_build = None
Greg Ward13ae1c81999-03-22 14:55:25 +000029
Greg Warde01149c2000-02-18 00:35:22 +000030 def finalize_options (self):
Greg Ward13ae1c81999-03-22 14:55:25 +000031
Greg Wardfa4eb181999-09-13 13:58:34 +000032 # Get all the information we need to install pure Python modules
33 # from the umbrella 'install' command -- build (source) directory,
34 # install (target) directory, and whether to compile .py files.
Greg Ward13ae1c81999-03-22 14:55:25 +000035 self.set_undefined_options ('install',
36 ('build_lib', 'build_dir'),
Greg Ward4f08e4f2000-02-26 00:49:04 +000037 ('install_lib', 'install_dir'),
Greg Ward0f726951999-05-02 21:39:13 +000038 ('compile_py', 'compile'),
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000039 ('optimize_py', 'optimize'),
40 ('skip_build', 'skip_build'),
41 )
Greg Ward0f726951999-05-02 21:39:13 +000042
Greg Ward13ae1c81999-03-22 14:55:25 +000043
44 def run (self):
45
Greg Warde5dfba52000-03-29 02:17:42 +000046 # Make sure we have built everything we need first
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000047 if not self.skip_build:
48 if self.distribution.has_pure_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +000049 self.run_command ('build_py')
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000050 if self.distribution.has_ext_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +000051 self.run_command ('build_ext')
Greg Ward7478a482000-01-30 15:07:56 +000052
Greg Ward4f08e4f2000-02-26 00:49:04 +000053 # Install everything: simply dump the entire contents of the build
54 # directory to the installation directory (that's the beauty of
55 # having a build directory!)
Greg Wardf355d472000-05-20 15:08:57 +000056 if os.path.isdir(self.build_dir):
57 outfiles = self.copy_tree (self.build_dir, self.install_dir)
58 else:
59 self.warn("'%s' does not exist -- no Python modules to install" %
60 self.build_dir)
61 return
Greg Warde5dfba52000-03-29 02:17:42 +000062
Greg Ward0f726951999-05-02 21:39:13 +000063 # (Optionally) compile .py to .pyc
64 # XXX hey! we can't control whether we optimize or not; that's up
65 # to the invocation of the current Python interpreter (at least
66 # according to the py_compile docs). That sucks.
67
68 if self.compile:
69 from py_compile import compile
70
71 for f in outfiles:
Greg Ward440e2f51999-08-29 18:19:37 +000072 # only compile the file if it is actually a .py file
73 if f[-3:] == '.py':
Greg Warded8a0e02000-03-29 03:29:34 +000074 out_fn = f + (__debug__ and "c" or "o")
75 compile_msg = "byte-compiling %s to %s" % \
76 (f, os.path.basename (out_fn))
Greg Ward90c74cc2000-08-02 01:34:18 +000077 skip_msg = "skipping byte-compilation of %s" % f
Greg Ward440e2f51999-08-29 18:19:37 +000078 self.make_file (f, out_fn, compile, (f,),
Greg Warded8a0e02000-03-29 03:29:34 +000079 compile_msg, skip_msg)
Greg Ward13ae1c81999-03-22 14:55:25 +000080 # run ()
81
Greg Warde5dfba52000-03-29 02:17:42 +000082
83 def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
84
85 if not has_any:
86 return []
87
Greg Ward4fb29e52000-05-27 17:27:23 +000088 build_cmd = self.get_finalized_command (build_cmd)
Greg Warde5dfba52000-03-29 02:17:42 +000089 build_files = build_cmd.get_outputs()
Greg Ward4779cdf2000-05-07 15:32:13 +000090 build_dir = getattr (build_cmd, cmd_option)
Greg Warde5dfba52000-03-29 02:17:42 +000091
92 prefix_len = len (build_dir) + len (os.sep)
93 outputs = []
94 for file in build_files:
95 outputs.append (os.path.join (output_dir, file[prefix_len:]))
96
97 return outputs
98
99 # _mutate_outputs ()
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000100
101 def _bytecode_filenames (self, py_filenames):
102 bytecode_files = []
103 for py_file in py_filenames:
104 bytecode = py_file + (__debug__ and "c" or "o")
105 bytecode_files.append(bytecode)
106
107 return bytecode_files
Greg Warde5dfba52000-03-29 02:17:42 +0000108
109 def get_outputs (self):
110 """Return the list of files that would be installed if this command
111 were actually run. Not affected by the "dry-run" flag or whether
112 modules have actually been built yet."""
113
114 pure_outputs = \
115 self._mutate_outputs (self.distribution.has_pure_modules(),
116 'build_py', 'build_lib',
117 self.install_dir)
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000118 if self.compile:
119 bytecode_outputs = self._bytecode_filenames(pure_outputs)
120 else:
121 bytecode_outputs = []
Greg Warde5dfba52000-03-29 02:17:42 +0000122
123 ext_outputs = \
124 self._mutate_outputs (self.distribution.has_ext_modules(),
125 'build_ext', 'build_lib',
126 self.install_dir)
127
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000128 return pure_outputs + bytecode_outputs + ext_outputs
Greg Warde5dfba52000-03-29 02:17:42 +0000129
130 # get_outputs ()
131
Greg Ward1aab6e92000-03-31 02:53:07 +0000132 def get_inputs (self):
133 """Get the list of files that are input to this command, ie. the
134 files that get installed as they are named in the build tree.
135 The files in this list correspond one-to-one to the output
136 filenames returned by 'get_outputs()'."""
137
138 inputs = []
139
140 if self.distribution.has_pure_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +0000141 build_py = self.get_finalized_command ('build_py')
Greg Ward1aab6e92000-03-31 02:53:07 +0000142 inputs.extend (build_py.get_outputs())
143
144 if self.distribution.has_ext_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +0000145 build_ext = self.get_finalized_command ('build_ext')
Greg Ward1aab6e92000-03-31 02:53:07 +0000146 inputs.extend (build_ext.get_outputs())
147
148 return inputs
149
150
151
Greg Warde5dfba52000-03-29 02:17:42 +0000152# class install_lib