| 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 | ] |
|---|