blob: 2d19e5b96a300757e7a1b0538a0b2af71242631c [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 Ward13ae1c81999-03-22 14:55:25 +000037 self.set_undefined_options ('install',
38 ('build_lib', 'build_dir'),
Greg Ward4f08e4f2000-02-26 00:49:04 +000039 ('install_lib', 'install_dir'),
Greg Ward3a0310a2000-09-13 01:02:25 +000040 ('force', 'force'),
Greg Ward0f726951999-05-02 21:39:13 +000041 ('compile_py', 'compile'),
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000042 ('optimize_py', 'optimize'),
43 ('skip_build', 'skip_build'),
44 )
Greg Ward0f726951999-05-02 21:39:13 +000045
Greg Ward13ae1c81999-03-22 14:55:25 +000046
47 def run (self):
48
Greg Warde5dfba52000-03-29 02:17:42 +000049 # Make sure we have built everything we need first
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000050 if not self.skip_build:
51 if self.distribution.has_pure_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +000052 self.run_command ('build_py')
Gregory P. Smith74ead8f2000-05-12 01:46:47 +000053 if self.distribution.has_ext_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +000054 self.run_command ('build_ext')
Greg Ward7478a482000-01-30 15:07:56 +000055
Greg Ward4f08e4f2000-02-26 00:49:04 +000056 # Install everything: simply dump the entire contents of the build
57 # directory to the installation directory (that's the beauty of
58 # having a build directory!)
Greg Wardf355d472000-05-20 15:08:57 +000059 if os.path.isdir(self.build_dir):
60 outfiles = self.copy_tree (self.build_dir, self.install_dir)
61 else:
62 self.warn("'%s' does not exist -- no Python modules to install" %
63 self.build_dir)
64 return
Greg Warde5dfba52000-03-29 02:17:42 +000065
Greg Ward0f726951999-05-02 21:39:13 +000066 # (Optionally) compile .py to .pyc
67 # XXX hey! we can't control whether we optimize or not; that's up
68 # to the invocation of the current Python interpreter (at least
69 # according to the py_compile docs). That sucks.
70
71 if self.compile:
72 from py_compile import compile
73
74 for f in outfiles:
Greg Ward440e2f51999-08-29 18:19:37 +000075 # only compile the file if it is actually a .py file
76 if f[-3:] == '.py':
Greg Warded8a0e02000-03-29 03:29:34 +000077 out_fn = f + (__debug__ and "c" or "o")
78 compile_msg = "byte-compiling %s to %s" % \
79 (f, os.path.basename (out_fn))
Greg Ward90c74cc2000-08-02 01:34:18 +000080 skip_msg = "skipping byte-compilation of %s" % f
Greg Ward440e2f51999-08-29 18:19:37 +000081 self.make_file (f, out_fn, compile, (f,),
Greg Warded8a0e02000-03-29 03:29:34 +000082 compile_msg, skip_msg)
Greg Ward13ae1c81999-03-22 14:55:25 +000083 # run ()
84
Greg Warde5dfba52000-03-29 02:17:42 +000085
86 def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir):
87
88 if not has_any:
89 return []
90
Greg Ward4fb29e52000-05-27 17:27:23 +000091 build_cmd = self.get_finalized_command (build_cmd)
Greg Warde5dfba52000-03-29 02:17:42 +000092 build_files = build_cmd.get_outputs()
Greg Ward4779cdf2000-05-07 15:32:13 +000093 build_dir = getattr (build_cmd, cmd_option)
Greg Warde5dfba52000-03-29 02:17:42 +000094
95 prefix_len = len (build_dir) + len (os.sep)
96 outputs = []
97 for file in build_files:
98 outputs.append (os.path.join (output_dir, file[prefix_len:]))
99
100 return outputs
101
102 # _mutate_outputs ()
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000103
104 def _bytecode_filenames (self, py_filenames):
105 bytecode_files = []
106 for py_file in py_filenames:
107 bytecode = py_file + (__debug__ and "c" or "o")
108 bytecode_files.append(bytecode)
109
110 return bytecode_files
Greg Warde5dfba52000-03-29 02:17:42 +0000111
112 def get_outputs (self):
113 """Return the list of files that would be installed if this command
114 were actually run. Not affected by the "dry-run" flag or whether
115 modules have actually been built yet."""
116
117 pure_outputs = \
118 self._mutate_outputs (self.distribution.has_pure_modules(),
119 'build_py', 'build_lib',
120 self.install_dir)
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000121 if self.compile:
122 bytecode_outputs = self._bytecode_filenames(pure_outputs)
123 else:
124 bytecode_outputs = []
Greg Warde5dfba52000-03-29 02:17:42 +0000125
126 ext_outputs = \
127 self._mutate_outputs (self.distribution.has_ext_modules(),
128 'build_ext', 'build_lib',
129 self.install_dir)
130
Gregory P. Smith11fb7832000-05-13 02:11:10 +0000131 return pure_outputs + bytecode_outputs + ext_outputs
Greg Warde5dfba52000-03-29 02:17:42 +0000132
133 # get_outputs ()
134
Greg Ward1aab6e92000-03-31 02:53:07 +0000135 def get_inputs (self):
136 """Get the list of files that are input to this command, ie. the
137 files that get installed as they are named in the build tree.
138 The files in this list correspond one-to-one to the output
139 filenames returned by 'get_outputs()'."""
140
141 inputs = []
142
143 if self.distribution.has_pure_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +0000144 build_py = self.get_finalized_command ('build_py')
Greg Ward1aab6e92000-03-31 02:53:07 +0000145 inputs.extend (build_py.get_outputs())
146
147 if self.distribution.has_ext_modules():
Greg Ward4fb29e52000-05-27 17:27:23 +0000148 build_ext = self.get_finalized_command ('build_ext')
Greg Ward1aab6e92000-03-31 02:53:07 +0000149 inputs.extend (build_ext.get_outputs())
150
151 return inputs
152
153
154
Greg Warde5dfba52000-03-29 02:17:42 +0000155# class install_lib