1 | n/a | """distutils.command.install |
---|
2 | n/a | |
---|
3 | n/a | Implements the Distutils 'install' command.""" |
---|
4 | n/a | |
---|
5 | n/a | import sys |
---|
6 | n/a | import os |
---|
7 | n/a | |
---|
8 | n/a | from distutils import log |
---|
9 | n/a | from distutils.core import Command |
---|
10 | n/a | from distutils.debug import DEBUG |
---|
11 | n/a | from distutils.sysconfig import get_config_vars |
---|
12 | n/a | from distutils.errors import DistutilsPlatformError |
---|
13 | n/a | from distutils.file_util import write_file |
---|
14 | n/a | from distutils.util import convert_path, subst_vars, change_root |
---|
15 | n/a | from distutils.util import get_platform |
---|
16 | n/a | from distutils.errors import DistutilsOptionError |
---|
17 | n/a | |
---|
18 | n/a | from site import USER_BASE |
---|
19 | n/a | from site import USER_SITE |
---|
20 | n/a | HAS_USER_SITE = True |
---|
21 | n/a | |
---|
22 | n/a | WINDOWS_SCHEME = { |
---|
23 | n/a | 'purelib': '$base/Lib/site-packages', |
---|
24 | n/a | 'platlib': '$base/Lib/site-packages', |
---|
25 | n/a | 'headers': '$base/Include/$dist_name', |
---|
26 | n/a | 'scripts': '$base/Scripts', |
---|
27 | n/a | 'data' : '$base', |
---|
28 | n/a | } |
---|
29 | n/a | |
---|
30 | n/a | INSTALL_SCHEMES = { |
---|
31 | n/a | 'unix_prefix': { |
---|
32 | n/a | 'purelib': '$base/lib/python$py_version_short/site-packages', |
---|
33 | n/a | 'platlib': '$platbase/lib/python$py_version_short/site-packages', |
---|
34 | n/a | 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', |
---|
35 | n/a | 'scripts': '$base/bin', |
---|
36 | n/a | 'data' : '$base', |
---|
37 | n/a | }, |
---|
38 | n/a | 'unix_home': { |
---|
39 | n/a | 'purelib': '$base/lib/python', |
---|
40 | n/a | 'platlib': '$base/lib/python', |
---|
41 | n/a | 'headers': '$base/include/python/$dist_name', |
---|
42 | n/a | 'scripts': '$base/bin', |
---|
43 | n/a | 'data' : '$base', |
---|
44 | n/a | }, |
---|
45 | n/a | 'nt': WINDOWS_SCHEME, |
---|
46 | n/a | } |
---|
47 | n/a | |
---|
48 | n/a | # user site schemes |
---|
49 | n/a | if HAS_USER_SITE: |
---|
50 | n/a | INSTALL_SCHEMES['nt_user'] = { |
---|
51 | n/a | 'purelib': '$usersite', |
---|
52 | n/a | 'platlib': '$usersite', |
---|
53 | n/a | 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', |
---|
54 | n/a | 'scripts': '$userbase/Python$py_version_nodot/Scripts', |
---|
55 | n/a | 'data' : '$userbase', |
---|
56 | n/a | } |
---|
57 | n/a | |
---|
58 | n/a | INSTALL_SCHEMES['unix_user'] = { |
---|
59 | n/a | 'purelib': '$usersite', |
---|
60 | n/a | 'platlib': '$usersite', |
---|
61 | n/a | 'headers': |
---|
62 | n/a | '$userbase/include/python$py_version_short$abiflags/$dist_name', |
---|
63 | n/a | 'scripts': '$userbase/bin', |
---|
64 | n/a | 'data' : '$userbase', |
---|
65 | n/a | } |
---|
66 | n/a | |
---|
67 | n/a | # The keys to an installation scheme; if any new types of files are to be |
---|
68 | n/a | # installed, be sure to add an entry to every installation scheme above, |
---|
69 | n/a | # and to SCHEME_KEYS here. |
---|
70 | n/a | SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') |
---|
71 | n/a | |
---|
72 | n/a | |
---|
73 | n/a | class install(Command): |
---|
74 | n/a | |
---|
75 | n/a | description = "install everything from build directory" |
---|
76 | n/a | |
---|
77 | n/a | user_options = [ |
---|
78 | n/a | # Select installation scheme and set base director(y|ies) |
---|
79 | n/a | ('prefix=', None, |
---|
80 | n/a | "installation prefix"), |
---|
81 | n/a | ('exec-prefix=', None, |
---|
82 | n/a | "(Unix only) prefix for platform-specific files"), |
---|
83 | n/a | ('home=', None, |
---|
84 | n/a | "(Unix only) home directory to install under"), |
---|
85 | n/a | |
---|
86 | n/a | # Or, just set the base director(y|ies) |
---|
87 | n/a | ('install-base=', None, |
---|
88 | n/a | "base installation directory (instead of --prefix or --home)"), |
---|
89 | n/a | ('install-platbase=', None, |
---|
90 | n/a | "base installation directory for platform-specific files " + |
---|
91 | n/a | "(instead of --exec-prefix or --home)"), |
---|
92 | n/a | ('root=', None, |
---|
93 | n/a | "install everything relative to this alternate root directory"), |
---|
94 | n/a | |
---|
95 | n/a | # Or, explicitly set the installation scheme |
---|
96 | n/a | ('install-purelib=', None, |
---|
97 | n/a | "installation directory for pure Python module distributions"), |
---|
98 | n/a | ('install-platlib=', None, |
---|
99 | n/a | "installation directory for non-pure module distributions"), |
---|
100 | n/a | ('install-lib=', None, |
---|
101 | n/a | "installation directory for all module distributions " + |
---|
102 | n/a | "(overrides --install-purelib and --install-platlib)"), |
---|
103 | n/a | |
---|
104 | n/a | ('install-headers=', None, |
---|
105 | n/a | "installation directory for C/C++ headers"), |
---|
106 | n/a | ('install-scripts=', None, |
---|
107 | n/a | "installation directory for Python scripts"), |
---|
108 | n/a | ('install-data=', None, |
---|
109 | n/a | "installation directory for data files"), |
---|
110 | n/a | |
---|
111 | n/a | # Byte-compilation options -- see install_lib.py for details, as |
---|
112 | n/a | # these are duplicated from there (but only install_lib does |
---|
113 | n/a | # anything with them). |
---|
114 | n/a | ('compile', 'c', "compile .py to .pyc [default]"), |
---|
115 | n/a | ('no-compile', None, "don't compile .py files"), |
---|
116 | n/a | ('optimize=', 'O', |
---|
117 | n/a | "also compile with optimization: -O1 for \"python -O\", " |
---|
118 | n/a | "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), |
---|
119 | n/a | |
---|
120 | n/a | # Miscellaneous control options |
---|
121 | n/a | ('force', 'f', |
---|
122 | n/a | "force installation (overwrite any existing files)"), |
---|
123 | n/a | ('skip-build', None, |
---|
124 | n/a | "skip rebuilding everything (for testing/debugging)"), |
---|
125 | n/a | |
---|
126 | n/a | # Where to install documentation (eventually!) |
---|
127 | n/a | #('doc-format=', None, "format of documentation to generate"), |
---|
128 | n/a | #('install-man=', None, "directory for Unix man pages"), |
---|
129 | n/a | #('install-html=', None, "directory for HTML documentation"), |
---|
130 | n/a | #('install-info=', None, "directory for GNU info files"), |
---|
131 | n/a | |
---|
132 | n/a | ('record=', None, |
---|
133 | n/a | "filename in which to record list of installed files"), |
---|
134 | n/a | ] |
---|
135 | n/a | |
---|
136 | n/a | boolean_options = ['compile', 'force', 'skip-build'] |
---|
137 | n/a | |
---|
138 | n/a | if HAS_USER_SITE: |
---|
139 | n/a | user_options.append(('user', None, |
---|
140 | n/a | "install in user site-package '%s'" % USER_SITE)) |
---|
141 | n/a | boolean_options.append('user') |
---|
142 | n/a | |
---|
143 | n/a | negative_opt = {'no-compile' : 'compile'} |
---|
144 | n/a | |
---|
145 | n/a | |
---|
146 | n/a | def initialize_options(self): |
---|
147 | n/a | """Initializes options.""" |
---|
148 | n/a | # High-level options: these select both an installation base |
---|
149 | n/a | # and scheme. |
---|
150 | n/a | self.prefix = None |
---|
151 | n/a | self.exec_prefix = None |
---|
152 | n/a | self.home = None |
---|
153 | n/a | self.user = 0 |
---|
154 | n/a | |
---|
155 | n/a | # These select only the installation base; it's up to the user to |
---|
156 | n/a | # specify the installation scheme (currently, that means supplying |
---|
157 | n/a | # the --install-{platlib,purelib,scripts,data} options). |
---|
158 | n/a | self.install_base = None |
---|
159 | n/a | self.install_platbase = None |
---|
160 | n/a | self.root = None |
---|
161 | n/a | |
---|
162 | n/a | # These options are the actual installation directories; if not |
---|
163 | n/a | # supplied by the user, they are filled in using the installation |
---|
164 | n/a | # scheme implied by prefix/exec-prefix/home and the contents of |
---|
165 | n/a | # that installation scheme. |
---|
166 | n/a | self.install_purelib = None # for pure module distributions |
---|
167 | n/a | self.install_platlib = None # non-pure (dists w/ extensions) |
---|
168 | n/a | self.install_headers = None # for C/C++ headers |
---|
169 | n/a | self.install_lib = None # set to either purelib or platlib |
---|
170 | n/a | self.install_scripts = None |
---|
171 | n/a | self.install_data = None |
---|
172 | n/a | self.install_userbase = USER_BASE |
---|
173 | n/a | self.install_usersite = USER_SITE |
---|
174 | n/a | |
---|
175 | n/a | self.compile = None |
---|
176 | n/a | self.optimize = None |
---|
177 | n/a | |
---|
178 | n/a | # Deprecated |
---|
179 | n/a | # These two are for putting non-packagized distributions into their |
---|
180 | n/a | # own directory and creating a .pth file if it makes sense. |
---|
181 | n/a | # 'extra_path' comes from the setup file; 'install_path_file' can |
---|
182 | n/a | # be turned off if it makes no sense to install a .pth file. (But |
---|
183 | n/a | # better to install it uselessly than to guess wrong and not |
---|
184 | n/a | # install it when it's necessary and would be used!) Currently, |
---|
185 | n/a | # 'install_path_file' is always true unless some outsider meddles |
---|
186 | n/a | # with it. |
---|
187 | n/a | self.extra_path = None |
---|
188 | n/a | self.install_path_file = 1 |
---|
189 | n/a | |
---|
190 | n/a | # 'force' forces installation, even if target files are not |
---|
191 | n/a | # out-of-date. 'skip_build' skips running the "build" command, |
---|
192 | n/a | # handy if you know it's not necessary. 'warn_dir' (which is *not* |
---|
193 | n/a | # a user option, it's just there so the bdist_* commands can turn |
---|
194 | n/a | # it off) determines whether we warn about installing to a |
---|
195 | n/a | # directory not in sys.path. |
---|
196 | n/a | self.force = 0 |
---|
197 | n/a | self.skip_build = 0 |
---|
198 | n/a | self.warn_dir = 1 |
---|
199 | n/a | |
---|
200 | n/a | # These are only here as a conduit from the 'build' command to the |
---|
201 | n/a | # 'install_*' commands that do the real work. ('build_base' isn't |
---|
202 | n/a | # actually used anywhere, but it might be useful in future.) They |
---|
203 | n/a | # are not user options, because if the user told the install |
---|
204 | n/a | # command where the build directory is, that wouldn't affect the |
---|
205 | n/a | # build command. |
---|
206 | n/a | self.build_base = None |
---|
207 | n/a | self.build_lib = None |
---|
208 | n/a | |
---|
209 | n/a | # Not defined yet because we don't know anything about |
---|
210 | n/a | # documentation yet. |
---|
211 | n/a | #self.install_man = None |
---|
212 | n/a | #self.install_html = None |
---|
213 | n/a | #self.install_info = None |
---|
214 | n/a | |
---|
215 | n/a | self.record = None |
---|
216 | n/a | |
---|
217 | n/a | |
---|
218 | n/a | # -- Option finalizing methods ------------------------------------- |
---|
219 | n/a | # (This is rather more involved than for most commands, |
---|
220 | n/a | # because this is where the policy for installing third- |
---|
221 | n/a | # party Python modules on various platforms given a wide |
---|
222 | n/a | # array of user input is decided. Yes, it's quite complex!) |
---|
223 | n/a | |
---|
224 | n/a | def finalize_options(self): |
---|
225 | n/a | """Finalizes options.""" |
---|
226 | n/a | # This method (and its pliant slaves, like 'finalize_unix()', |
---|
227 | n/a | # 'finalize_other()', and 'select_scheme()') is where the default |
---|
228 | n/a | # installation directories for modules, extension modules, and |
---|
229 | n/a | # anything else we care to install from a Python module |
---|
230 | n/a | # distribution. Thus, this code makes a pretty important policy |
---|
231 | n/a | # statement about how third-party stuff is added to a Python |
---|
232 | n/a | # installation! Note that the actual work of installation is done |
---|
233 | n/a | # by the relatively simple 'install_*' commands; they just take |
---|
234 | n/a | # their orders from the installation directory options determined |
---|
235 | n/a | # here. |
---|
236 | n/a | |
---|
237 | n/a | # Check for errors/inconsistencies in the options; first, stuff |
---|
238 | n/a | # that's wrong on any platform. |
---|
239 | n/a | |
---|
240 | n/a | if ((self.prefix or self.exec_prefix or self.home) and |
---|
241 | n/a | (self.install_base or self.install_platbase)): |
---|
242 | n/a | raise DistutilsOptionError( |
---|
243 | n/a | "must supply either prefix/exec-prefix/home or " + |
---|
244 | n/a | "install-base/install-platbase -- not both") |
---|
245 | n/a | |
---|
246 | n/a | if self.home and (self.prefix or self.exec_prefix): |
---|
247 | n/a | raise DistutilsOptionError( |
---|
248 | n/a | "must supply either home or prefix/exec-prefix -- not both") |
---|
249 | n/a | |
---|
250 | n/a | if self.user and (self.prefix or self.exec_prefix or self.home or |
---|
251 | n/a | self.install_base or self.install_platbase): |
---|
252 | n/a | raise DistutilsOptionError("can't combine user with prefix, " |
---|
253 | n/a | "exec_prefix/home, or install_(plat)base") |
---|
254 | n/a | |
---|
255 | n/a | # Next, stuff that's wrong (or dubious) only on certain platforms. |
---|
256 | n/a | if os.name != "posix": |
---|
257 | n/a | if self.exec_prefix: |
---|
258 | n/a | self.warn("exec-prefix option ignored on this platform") |
---|
259 | n/a | self.exec_prefix = None |
---|
260 | n/a | |
---|
261 | n/a | # Now the interesting logic -- so interesting that we farm it out |
---|
262 | n/a | # to other methods. The goal of these methods is to set the final |
---|
263 | n/a | # values for the install_{lib,scripts,data,...} options, using as |
---|
264 | n/a | # input a heady brew of prefix, exec_prefix, home, install_base, |
---|
265 | n/a | # install_platbase, user-supplied versions of |
---|
266 | n/a | # install_{purelib,platlib,lib,scripts,data,...}, and the |
---|
267 | n/a | # INSTALL_SCHEME dictionary above. Phew! |
---|
268 | n/a | |
---|
269 | n/a | self.dump_dirs("pre-finalize_{unix,other}") |
---|
270 | n/a | |
---|
271 | n/a | if os.name == 'posix': |
---|
272 | n/a | self.finalize_unix() |
---|
273 | n/a | else: |
---|
274 | n/a | self.finalize_other() |
---|
275 | n/a | |
---|
276 | n/a | self.dump_dirs("post-finalize_{unix,other}()") |
---|
277 | n/a | |
---|
278 | n/a | # Expand configuration variables, tilde, etc. in self.install_base |
---|
279 | n/a | # and self.install_platbase -- that way, we can use $base or |
---|
280 | n/a | # $platbase in the other installation directories and not worry |
---|
281 | n/a | # about needing recursive variable expansion (shudder). |
---|
282 | n/a | |
---|
283 | n/a | py_version = sys.version.split()[0] |
---|
284 | n/a | (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') |
---|
285 | n/a | try: |
---|
286 | n/a | abiflags = sys.abiflags |
---|
287 | n/a | except AttributeError: |
---|
288 | n/a | # sys.abiflags may not be defined on all platforms. |
---|
289 | n/a | abiflags = '' |
---|
290 | n/a | self.config_vars = {'dist_name': self.distribution.get_name(), |
---|
291 | n/a | 'dist_version': self.distribution.get_version(), |
---|
292 | n/a | 'dist_fullname': self.distribution.get_fullname(), |
---|
293 | n/a | 'py_version': py_version, |
---|
294 | n/a | 'py_version_short': '%d.%d' % sys.version_info[:2], |
---|
295 | n/a | 'py_version_nodot': '%d%d' % sys.version_info[:2], |
---|
296 | n/a | 'sys_prefix': prefix, |
---|
297 | n/a | 'prefix': prefix, |
---|
298 | n/a | 'sys_exec_prefix': exec_prefix, |
---|
299 | n/a | 'exec_prefix': exec_prefix, |
---|
300 | n/a | 'abiflags': abiflags, |
---|
301 | n/a | } |
---|
302 | n/a | |
---|
303 | n/a | if HAS_USER_SITE: |
---|
304 | n/a | self.config_vars['userbase'] = self.install_userbase |
---|
305 | n/a | self.config_vars['usersite'] = self.install_usersite |
---|
306 | n/a | |
---|
307 | n/a | self.expand_basedirs() |
---|
308 | n/a | |
---|
309 | n/a | self.dump_dirs("post-expand_basedirs()") |
---|
310 | n/a | |
---|
311 | n/a | # Now define config vars for the base directories so we can expand |
---|
312 | n/a | # everything else. |
---|
313 | n/a | self.config_vars['base'] = self.install_base |
---|
314 | n/a | self.config_vars['platbase'] = self.install_platbase |
---|
315 | n/a | |
---|
316 | n/a | if DEBUG: |
---|
317 | n/a | from pprint import pprint |
---|
318 | n/a | print("config vars:") |
---|
319 | n/a | pprint(self.config_vars) |
---|
320 | n/a | |
---|
321 | n/a | # Expand "~" and configuration variables in the installation |
---|
322 | n/a | # directories. |
---|
323 | n/a | self.expand_dirs() |
---|
324 | n/a | |
---|
325 | n/a | self.dump_dirs("post-expand_dirs()") |
---|
326 | n/a | |
---|
327 | n/a | # Create directories in the home dir: |
---|
328 | n/a | if self.user: |
---|
329 | n/a | self.create_home_path() |
---|
330 | n/a | |
---|
331 | n/a | # Pick the actual directory to install all modules to: either |
---|
332 | n/a | # install_purelib or install_platlib, depending on whether this |
---|
333 | n/a | # module distribution is pure or not. Of course, if the user |
---|
334 | n/a | # already specified install_lib, use their selection. |
---|
335 | n/a | if self.install_lib is None: |
---|
336 | n/a | if self.distribution.ext_modules: # has extensions: non-pure |
---|
337 | n/a | self.install_lib = self.install_platlib |
---|
338 | n/a | else: |
---|
339 | n/a | self.install_lib = self.install_purelib |
---|
340 | n/a | |
---|
341 | n/a | |
---|
342 | n/a | # Convert directories from Unix /-separated syntax to the local |
---|
343 | n/a | # convention. |
---|
344 | n/a | self.convert_paths('lib', 'purelib', 'platlib', |
---|
345 | n/a | 'scripts', 'data', 'headers', |
---|
346 | n/a | 'userbase', 'usersite') |
---|
347 | n/a | |
---|
348 | n/a | # Deprecated |
---|
349 | n/a | # Well, we're not actually fully completely finalized yet: we still |
---|
350 | n/a | # have to deal with 'extra_path', which is the hack for allowing |
---|
351 | n/a | # non-packagized module distributions (hello, Numerical Python!) to |
---|
352 | n/a | # get their own directories. |
---|
353 | n/a | self.handle_extra_path() |
---|
354 | n/a | self.install_libbase = self.install_lib # needed for .pth file |
---|
355 | n/a | self.install_lib = os.path.join(self.install_lib, self.extra_dirs) |
---|
356 | n/a | |
---|
357 | n/a | # If a new root directory was supplied, make all the installation |
---|
358 | n/a | # dirs relative to it. |
---|
359 | n/a | if self.root is not None: |
---|
360 | n/a | self.change_roots('libbase', 'lib', 'purelib', 'platlib', |
---|
361 | n/a | 'scripts', 'data', 'headers') |
---|
362 | n/a | |
---|
363 | n/a | self.dump_dirs("after prepending root") |
---|
364 | n/a | |
---|
365 | n/a | # Find out the build directories, ie. where to install from. |
---|
366 | n/a | self.set_undefined_options('build', |
---|
367 | n/a | ('build_base', 'build_base'), |
---|
368 | n/a | ('build_lib', 'build_lib')) |
---|
369 | n/a | |
---|
370 | n/a | # Punt on doc directories for now -- after all, we're punting on |
---|
371 | n/a | # documentation completely! |
---|
372 | n/a | |
---|
373 | n/a | def dump_dirs(self, msg): |
---|
374 | n/a | """Dumps the list of user options.""" |
---|
375 | n/a | if not DEBUG: |
---|
376 | n/a | return |
---|
377 | n/a | from distutils.fancy_getopt import longopt_xlate |
---|
378 | n/a | log.debug(msg + ":") |
---|
379 | n/a | for opt in self.user_options: |
---|
380 | n/a | opt_name = opt[0] |
---|
381 | n/a | if opt_name[-1] == "=": |
---|
382 | n/a | opt_name = opt_name[0:-1] |
---|
383 | n/a | if opt_name in self.negative_opt: |
---|
384 | n/a | opt_name = self.negative_opt[opt_name] |
---|
385 | n/a | opt_name = opt_name.translate(longopt_xlate) |
---|
386 | n/a | val = not getattr(self, opt_name) |
---|
387 | n/a | else: |
---|
388 | n/a | opt_name = opt_name.translate(longopt_xlate) |
---|
389 | n/a | val = getattr(self, opt_name) |
---|
390 | n/a | log.debug(" %s: %s", opt_name, val) |
---|
391 | n/a | |
---|
392 | n/a | def finalize_unix(self): |
---|
393 | n/a | """Finalizes options for posix platforms.""" |
---|
394 | n/a | if self.install_base is not None or self.install_platbase is not None: |
---|
395 | n/a | if ((self.install_lib is None and |
---|
396 | n/a | self.install_purelib is None and |
---|
397 | n/a | self.install_platlib is None) or |
---|
398 | n/a | self.install_headers is None or |
---|
399 | n/a | self.install_scripts is None or |
---|
400 | n/a | self.install_data is None): |
---|
401 | n/a | raise DistutilsOptionError( |
---|
402 | n/a | "install-base or install-platbase supplied, but " |
---|
403 | n/a | "installation scheme is incomplete") |
---|
404 | n/a | return |
---|
405 | n/a | |
---|
406 | n/a | if self.user: |
---|
407 | n/a | if self.install_userbase is None: |
---|
408 | n/a | raise DistutilsPlatformError( |
---|
409 | n/a | "User base directory is not specified") |
---|
410 | n/a | self.install_base = self.install_platbase = self.install_userbase |
---|
411 | n/a | self.select_scheme("unix_user") |
---|
412 | n/a | elif self.home is not None: |
---|
413 | n/a | self.install_base = self.install_platbase = self.home |
---|
414 | n/a | self.select_scheme("unix_home") |
---|
415 | n/a | else: |
---|
416 | n/a | if self.prefix is None: |
---|
417 | n/a | if self.exec_prefix is not None: |
---|
418 | n/a | raise DistutilsOptionError( |
---|
419 | n/a | "must not supply exec-prefix without prefix") |
---|
420 | n/a | |
---|
421 | n/a | self.prefix = os.path.normpath(sys.prefix) |
---|
422 | n/a | self.exec_prefix = os.path.normpath(sys.exec_prefix) |
---|
423 | n/a | |
---|
424 | n/a | else: |
---|
425 | n/a | if self.exec_prefix is None: |
---|
426 | n/a | self.exec_prefix = self.prefix |
---|
427 | n/a | |
---|
428 | n/a | self.install_base = self.prefix |
---|
429 | n/a | self.install_platbase = self.exec_prefix |
---|
430 | n/a | self.select_scheme("unix_prefix") |
---|
431 | n/a | |
---|
432 | n/a | def finalize_other(self): |
---|
433 | n/a | """Finalizes options for non-posix platforms""" |
---|
434 | n/a | if self.user: |
---|
435 | n/a | if self.install_userbase is None: |
---|
436 | n/a | raise DistutilsPlatformError( |
---|
437 | n/a | "User base directory is not specified") |
---|
438 | n/a | self.install_base = self.install_platbase = self.install_userbase |
---|
439 | n/a | self.select_scheme(os.name + "_user") |
---|
440 | n/a | elif self.home is not None: |
---|
441 | n/a | self.install_base = self.install_platbase = self.home |
---|
442 | n/a | self.select_scheme("unix_home") |
---|
443 | n/a | else: |
---|
444 | n/a | if self.prefix is None: |
---|
445 | n/a | self.prefix = os.path.normpath(sys.prefix) |
---|
446 | n/a | |
---|
447 | n/a | self.install_base = self.install_platbase = self.prefix |
---|
448 | n/a | try: |
---|
449 | n/a | self.select_scheme(os.name) |
---|
450 | n/a | except KeyError: |
---|
451 | n/a | raise DistutilsPlatformError( |
---|
452 | n/a | "I don't know how to install stuff on '%s'" % os.name) |
---|
453 | n/a | |
---|
454 | n/a | def select_scheme(self, name): |
---|
455 | n/a | """Sets the install directories by applying the install schemes.""" |
---|
456 | n/a | # it's the caller's problem if they supply a bad name! |
---|
457 | n/a | scheme = INSTALL_SCHEMES[name] |
---|
458 | n/a | for key in SCHEME_KEYS: |
---|
459 | n/a | attrname = 'install_' + key |
---|
460 | n/a | if getattr(self, attrname) is None: |
---|
461 | n/a | setattr(self, attrname, scheme[key]) |
---|
462 | n/a | |
---|
463 | n/a | def _expand_attrs(self, attrs): |
---|
464 | n/a | for attr in attrs: |
---|
465 | n/a | val = getattr(self, attr) |
---|
466 | n/a | if val is not None: |
---|
467 | n/a | if os.name == 'posix' or os.name == 'nt': |
---|
468 | n/a | val = os.path.expanduser(val) |
---|
469 | n/a | val = subst_vars(val, self.config_vars) |
---|
470 | n/a | setattr(self, attr, val) |
---|
471 | n/a | |
---|
472 | n/a | def expand_basedirs(self): |
---|
473 | n/a | """Calls `os.path.expanduser` on install_base, install_platbase and |
---|
474 | n/a | root.""" |
---|
475 | n/a | self._expand_attrs(['install_base', 'install_platbase', 'root']) |
---|
476 | n/a | |
---|
477 | n/a | def expand_dirs(self): |
---|
478 | n/a | """Calls `os.path.expanduser` on install dirs.""" |
---|
479 | n/a | self._expand_attrs(['install_purelib', 'install_platlib', |
---|
480 | n/a | 'install_lib', 'install_headers', |
---|
481 | n/a | 'install_scripts', 'install_data',]) |
---|
482 | n/a | |
---|
483 | n/a | def convert_paths(self, *names): |
---|
484 | n/a | """Call `convert_path` over `names`.""" |
---|
485 | n/a | for name in names: |
---|
486 | n/a | attr = "install_" + name |
---|
487 | n/a | setattr(self, attr, convert_path(getattr(self, attr))) |
---|
488 | n/a | |
---|
489 | n/a | def handle_extra_path(self): |
---|
490 | n/a | """Set `path_file` and `extra_dirs` using `extra_path`.""" |
---|
491 | n/a | if self.extra_path is None: |
---|
492 | n/a | self.extra_path = self.distribution.extra_path |
---|
493 | n/a | |
---|
494 | n/a | if self.extra_path is not None: |
---|
495 | n/a | log.warn( |
---|
496 | n/a | "Distribution option extra_path is deprecated. " |
---|
497 | n/a | "See issue27919 for details." |
---|
498 | n/a | ) |
---|
499 | n/a | if isinstance(self.extra_path, str): |
---|
500 | n/a | self.extra_path = self.extra_path.split(',') |
---|
501 | n/a | |
---|
502 | n/a | if len(self.extra_path) == 1: |
---|
503 | n/a | path_file = extra_dirs = self.extra_path[0] |
---|
504 | n/a | elif len(self.extra_path) == 2: |
---|
505 | n/a | path_file, extra_dirs = self.extra_path |
---|
506 | n/a | else: |
---|
507 | n/a | raise DistutilsOptionError( |
---|
508 | n/a | "'extra_path' option must be a list, tuple, or " |
---|
509 | n/a | "comma-separated string with 1 or 2 elements") |
---|
510 | n/a | |
---|
511 | n/a | # convert to local form in case Unix notation used (as it |
---|
512 | n/a | # should be in setup scripts) |
---|
513 | n/a | extra_dirs = convert_path(extra_dirs) |
---|
514 | n/a | else: |
---|
515 | n/a | path_file = None |
---|
516 | n/a | extra_dirs = '' |
---|
517 | n/a | |
---|
518 | n/a | # XXX should we warn if path_file and not extra_dirs? (in which |
---|
519 | n/a | # case the path file would be harmless but pointless) |
---|
520 | n/a | self.path_file = path_file |
---|
521 | n/a | self.extra_dirs = extra_dirs |
---|
522 | n/a | |
---|
523 | n/a | def change_roots(self, *names): |
---|
524 | n/a | """Change the install directories pointed by name using root.""" |
---|
525 | n/a | for name in names: |
---|
526 | n/a | attr = "install_" + name |
---|
527 | n/a | setattr(self, attr, change_root(self.root, getattr(self, attr))) |
---|
528 | n/a | |
---|
529 | n/a | def create_home_path(self): |
---|
530 | n/a | """Create directories under ~.""" |
---|
531 | n/a | if not self.user: |
---|
532 | n/a | return |
---|
533 | n/a | home = convert_path(os.path.expanduser("~")) |
---|
534 | n/a | for name, path in self.config_vars.items(): |
---|
535 | n/a | if path.startswith(home) and not os.path.isdir(path): |
---|
536 | n/a | self.debug_print("os.makedirs('%s', 0o700)" % path) |
---|
537 | n/a | os.makedirs(path, 0o700) |
---|
538 | n/a | |
---|
539 | n/a | # -- Command execution methods ------------------------------------- |
---|
540 | n/a | |
---|
541 | n/a | def run(self): |
---|
542 | n/a | """Runs the command.""" |
---|
543 | n/a | # Obviously have to build before we can install |
---|
544 | n/a | if not self.skip_build: |
---|
545 | n/a | self.run_command('build') |
---|
546 | n/a | # If we built for any other platform, we can't install. |
---|
547 | n/a | build_plat = self.distribution.get_command_obj('build').plat_name |
---|
548 | n/a | # check warn_dir - it is a clue that the 'install' is happening |
---|
549 | n/a | # internally, and not to sys.path, so we don't check the platform |
---|
550 | n/a | # matches what we are running. |
---|
551 | n/a | if self.warn_dir and build_plat != get_platform(): |
---|
552 | n/a | raise DistutilsPlatformError("Can't install when " |
---|
553 | n/a | "cross-compiling") |
---|
554 | n/a | |
---|
555 | n/a | # Run all sub-commands (at least those that need to be run) |
---|
556 | n/a | for cmd_name in self.get_sub_commands(): |
---|
557 | n/a | self.run_command(cmd_name) |
---|
558 | n/a | |
---|
559 | n/a | if self.path_file: |
---|
560 | n/a | self.create_path_file() |
---|
561 | n/a | |
---|
562 | n/a | # write list of installed files, if requested. |
---|
563 | n/a | if self.record: |
---|
564 | n/a | outputs = self.get_outputs() |
---|
565 | n/a | if self.root: # strip any package prefix |
---|
566 | n/a | root_len = len(self.root) |
---|
567 | n/a | for counter in range(len(outputs)): |
---|
568 | n/a | outputs[counter] = outputs[counter][root_len:] |
---|
569 | n/a | self.execute(write_file, |
---|
570 | n/a | (self.record, outputs), |
---|
571 | n/a | "writing list of installed files to '%s'" % |
---|
572 | n/a | self.record) |
---|
573 | n/a | |
---|
574 | n/a | sys_path = map(os.path.normpath, sys.path) |
---|
575 | n/a | sys_path = map(os.path.normcase, sys_path) |
---|
576 | n/a | install_lib = os.path.normcase(os.path.normpath(self.install_lib)) |
---|
577 | n/a | if (self.warn_dir and |
---|
578 | n/a | not (self.path_file and self.install_path_file) and |
---|
579 | n/a | install_lib not in sys_path): |
---|
580 | n/a | log.debug(("modules installed to '%s', which is not in " |
---|
581 | n/a | "Python's module search path (sys.path) -- " |
---|
582 | n/a | "you'll have to change the search path yourself"), |
---|
583 | n/a | self.install_lib) |
---|
584 | n/a | |
---|
585 | n/a | def create_path_file(self): |
---|
586 | n/a | """Creates the .pth file""" |
---|
587 | n/a | filename = os.path.join(self.install_libbase, |
---|
588 | n/a | self.path_file + ".pth") |
---|
589 | n/a | if self.install_path_file: |
---|
590 | n/a | self.execute(write_file, |
---|
591 | n/a | (filename, [self.extra_dirs]), |
---|
592 | n/a | "creating %s" % filename) |
---|
593 | n/a | else: |
---|
594 | n/a | self.warn("path file '%s' not created" % filename) |
---|
595 | n/a | |
---|
596 | n/a | |
---|
597 | n/a | # -- Reporting methods --------------------------------------------- |
---|
598 | n/a | |
---|
599 | n/a | def get_outputs(self): |
---|
600 | n/a | """Assembles the outputs of all the sub-commands.""" |
---|
601 | n/a | outputs = [] |
---|
602 | n/a | for cmd_name in self.get_sub_commands(): |
---|
603 | n/a | cmd = self.get_finalized_command(cmd_name) |
---|
604 | n/a | # Add the contents of cmd.get_outputs(), ensuring |
---|
605 | n/a | # that outputs doesn't contain duplicate entries |
---|
606 | n/a | for filename in cmd.get_outputs(): |
---|
607 | n/a | if filename not in outputs: |
---|
608 | n/a | outputs.append(filename) |
---|
609 | n/a | |
---|
610 | n/a | if self.path_file and self.install_path_file: |
---|
611 | n/a | outputs.append(os.path.join(self.install_libbase, |
---|
612 | n/a | self.path_file + ".pth")) |
---|
613 | n/a | |
---|
614 | n/a | return outputs |
---|
615 | n/a | |
---|
616 | n/a | def get_inputs(self): |
---|
617 | n/a | """Returns the inputs of all the sub-commands""" |
---|
618 | n/a | # XXX gee, this looks familiar ;-( |
---|
619 | n/a | inputs = [] |
---|
620 | n/a | for cmd_name in self.get_sub_commands(): |
---|
621 | n/a | cmd = self.get_finalized_command(cmd_name) |
---|
622 | n/a | inputs.extend(cmd.get_inputs()) |
---|
623 | n/a | |
---|
624 | n/a | return inputs |
---|
625 | n/a | |
---|
626 | n/a | # -- Predicates for sub-command list ------------------------------- |
---|
627 | n/a | |
---|
628 | n/a | def has_lib(self): |
---|
629 | n/a | """Returns true if the current distribution has any Python |
---|
630 | n/a | modules to install.""" |
---|
631 | n/a | return (self.distribution.has_pure_modules() or |
---|
632 | n/a | self.distribution.has_ext_modules()) |
---|
633 | n/a | |
---|
634 | n/a | def has_headers(self): |
---|
635 | n/a | """Returns true if the current distribution has any headers to |
---|
636 | n/a | install.""" |
---|
637 | n/a | return self.distribution.has_headers() |
---|
638 | n/a | |
---|
639 | n/a | def has_scripts(self): |
---|
640 | n/a | """Returns true if the current distribution has any scripts to. |
---|
641 | n/a | install.""" |
---|
642 | n/a | return self.distribution.has_scripts() |
---|
643 | n/a | |
---|
644 | n/a | def has_data(self): |
---|
645 | n/a | """Returns true if the current distribution has any data to. |
---|
646 | n/a | install.""" |
---|
647 | n/a | return self.distribution.has_data_files() |
---|
648 | n/a | |
---|
649 | n/a | # 'sub_commands': a list of commands this command might have to run to |
---|
650 | n/a | # get its work done. See cmd.py for more info. |
---|
651 | n/a | sub_commands = [('install_lib', has_lib), |
---|
652 | n/a | ('install_headers', has_headers), |
---|
653 | n/a | ('install_scripts', has_scripts), |
---|
654 | n/a | ('install_data', has_data), |
---|
655 | n/a | ('install_egg_info', lambda self:True), |
---|
656 | n/a | ] |
---|