NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

bdist_wininst.py (9950B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\command\bdist_wininst.py
      2 __revision__ = '$Id: bdist_wininst.py 87602 2011-01-01 04:24:26Z richard.tew $'
      3 import sys
      4 import os
      5 import string
      6 from sysconfig import get_python_version
      7 from distutils.core import Command
      8 from distutils.dir_util import remove_tree
      9 from distutils.errors import DistutilsOptionError, DistutilsPlatformError
     10 from distutils import log
     11 from distutils.util import get_platform
     12 
     13 class bdist_wininst(Command):
     14     description = 'create an executable installer for MS Windows'
     15     user_options = [('bdist-dir=', None, 'temporary directory for creating the distribution'),
     16      ('plat-name=', 'p', 'platform name to embed in generated filenames (default: %s)' % get_platform()),
     17      ('keep-temp', 'k', 'keep the pseudo-installation tree around after ' + 'creating the distribution archive'),
     18      ('target-version=', None, 'require a specific python version' + ' on the target system'),
     19      ('no-target-compile', 'c', 'do not compile .py to .pyc on the target system'),
     20      ('no-target-optimize', 'o', 'do not compile .py to .pyo (optimized)on the target system'),
     21      ('dist-dir=', 'd', 'directory to put final built distributions in'),
     22      ('bitmap=', 'b', 'bitmap to use for the installer instead of python-powered logo'),
     23      ('title=', 't', 'title to display on the installer background instead of default'),
     24      ('skip-build', None, 'skip rebuilding everything (for testing/debugging)'),
     25      ('install-script=', None, 'basename of installation script to be run afterinstallation or before deinstallation'),
     26      ('pre-install-script=', None, 'Fully qualified filename of a script to be run before any files are installed.  This script need not be in the distribution'),
     27      ('user-access-control=', None, "specify Vista's UAC handling - 'none'/default=no handling, 'auto'=use UAC if target Python installed for all users, 'force'=always use UAC")]
     28     boolean_options = ['keep-temp',
     29      'no-target-compile',
     30      'no-target-optimize',
     31      'skip-build']
     32 
     33     def initialize_options(self):
     34         self.bdist_dir = None
     35         self.plat_name = None
     36         self.keep_temp = 0
     37         self.no_target_compile = 0
     38         self.no_target_optimize = 0
     39         self.target_version = None
     40         self.dist_dir = None
     41         self.bitmap = None
     42         self.title = None
     43         self.skip_build = 0
     44         self.install_script = None
     45         self.pre_install_script = None
     46         self.user_access_control = None
     47 
     48     def finalize_options(self):
     49         if self.bdist_dir is None:
     50             if self.skip_build and self.plat_name:
     51                 bdist = self.distribution.get_command_obj('bdist')
     52                 bdist.plat_name = self.plat_name
     53             bdist_base = self.get_finalized_command('bdist').bdist_base
     54             self.bdist_dir = os.path.join(bdist_base, 'wininst')
     55         if not self.target_version:
     56             self.target_version = ''
     57         if not self.skip_build and self.distribution.has_ext_modules():
     58             short_version = get_python_version()
     59             if self.target_version and self.target_version != short_version:
     60                 raise DistutilsOptionError, "target version can only be %s, or the '--skip-build' option must be specified" % (short_version,)
     61             self.target_version = short_version
     62         self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), ('plat_name', 'plat_name'))
     63         if self.install_script:
     64             for script in self.distribution.scripts:
     65                 if self.install_script == os.path.basename(script):
     66                     break
     67             else:
     68                 raise DistutilsOptionError, "install_script '%s' not found in scripts" % self.install_script
     69 
     70     def run(self):
     71         if sys.platform != 'win32' and (self.distribution.has_ext_modules() or self.distribution.has_c_libraries()):
     72             raise DistutilsPlatformError('distribution contains extensions and/or C libraries; must be compiled on a Windows 32 platform')
     73         if not self.skip_build:
     74             self.run_command('build')
     75         install = self.reinitialize_command('install', reinit_subcommands=1)
     76         install.root = self.bdist_dir
     77         install.skip_build = self.skip_build
     78         install.warn_dir = 0
     79         install.plat_name = self.plat_name
     80         install_lib = self.reinitialize_command('install_lib')
     81         install_lib.compile = 0
     82         install_lib.optimize = 0
     83         if self.distribution.has_ext_modules():
     84             target_version = self.target_version
     85             if not target_version:
     86                 target_version = sys.version[0:3]
     87             plat_specifier = '.%s-%s' % (self.plat_name, target_version)
     88             build = self.get_finalized_command('build')
     89             build.build_lib = os.path.join(build.build_base, 'lib' + plat_specifier)
     90         for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
     91             value = string.upper(key)
     92             if key == 'headers':
     93                 value = value + '/Include/$dist_name'
     94             setattr(install, 'install_' + key, value)
     95 
     96         log.info('installing to %s', self.bdist_dir)
     97         install.ensure_finalized()
     98         sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
     99         install.run()
    100         del sys.path[0]
    101         from tempfile import mktemp
    102         archive_basename = mktemp()
    103         fullname = self.distribution.get_fullname()
    104         arcname = self.make_archive(archive_basename, 'zip', root_dir=self.bdist_dir)
    105         self.create_exe(arcname, fullname, self.bitmap)
    106         if self.distribution.has_ext_modules():
    107             pyversion = get_python_version()
    108         else:
    109             pyversion = 'any'
    110         self.distribution.dist_files.append(('bdist_wininst', pyversion, self.get_installer_filename(fullname)))
    111         log.debug("removing temporary file '%s'", arcname)
    112         os.remove(arcname)
    113         if not self.keep_temp:
    114             remove_tree(self.bdist_dir, dry_run=self.dry_run)
    115 
    116     def get_inidata(self):
    117         lines = []
    118         metadata = self.distribution.metadata
    119         lines.append('[metadata]')
    120         info = (metadata.long_description or '') + '\n'
    121 
    122         def escape(s):
    123             return string.replace(s, '\n', '\\n')
    124 
    125         for name in ['author',
    126          'author_email',
    127          'description',
    128          'maintainer',
    129          'maintainer_email',
    130          'name',
    131          'url',
    132          'version']:
    133             data = getattr(metadata, name, '')
    134             if data:
    135                 info = info + '\n    %s: %s' % (string.capitalize(name), escape(data))
    136                 lines.append('%s=%s' % (name, escape(data)))
    137 
    138         lines.append('\n[Setup]')
    139         if self.install_script:
    140             lines.append('install_script=%s' % self.install_script)
    141         lines.append('info=%s' % escape(info))
    142         lines.append('target_compile=%d' % (not self.no_target_compile))
    143         lines.append('target_optimize=%d' % (not self.no_target_optimize))
    144         if self.target_version:
    145             lines.append('target_version=%s' % self.target_version)
    146         if self.user_access_control:
    147             lines.append('user_access_control=%s' % self.user_access_control)
    148         title = self.title or self.distribution.get_fullname()
    149         lines.append('title=%s' % escape(title))
    150         import time
    151         import distutils
    152         build_info = 'Built %s with distutils-%s' % (time.ctime(time.time()), distutils.__version__)
    153         lines.append('build_info=%s' % build_info)
    154         return string.join(lines, '\n')
    155 
    156     def create_exe(self, arcname, fullname, bitmap = None):
    157         import struct
    158         self.mkpath(self.dist_dir)
    159         cfgdata = self.get_inidata()
    160         installer_name = self.get_installer_filename(fullname)
    161         self.announce('creating %s' % installer_name)
    162         if bitmap:
    163             bitmapdata = open(bitmap, 'rb').read()
    164             bitmaplen = len(bitmapdata)
    165         else:
    166             bitmaplen = 0
    167         file = open(installer_name, 'wb')
    168         file.write(self.get_exe_bytes())
    169         if bitmap:
    170             file.write(bitmapdata)
    171         try:
    172             unicode
    173         except NameError:
    174             pass
    175         else:
    176             if isinstance(cfgdata, unicode):
    177                 cfgdata = cfgdata.encode('mbcs')
    178 
    179         cfgdata = cfgdata + '\x00'
    180         if self.pre_install_script:
    181             script_data = open(self.pre_install_script, 'r').read()
    182             cfgdata = cfgdata + script_data + '\n\x00'
    183         else:
    184             cfgdata = cfgdata + '\x00'
    185         file.write(cfgdata)
    186         header = struct.pack('<iii', 305419899, len(cfgdata), bitmaplen)
    187         file.write(header)
    188         file.write(open(arcname, 'rb').read())
    189 
    190     def get_installer_filename(self, fullname):
    191         if self.target_version:
    192             installer_name = os.path.join(self.dist_dir, '%s.%s-py%s.exe' % (fullname, self.plat_name, self.target_version))
    193         else:
    194             installer_name = os.path.join(self.dist_dir, '%s.%s.exe' % (fullname, self.plat_name))
    195         return installer_name
    196 
    197     def get_exe_bytes(self):
    198         from distutils.msvccompiler import get_build_version
    199         cur_version = get_python_version()
    200         if self.target_version and self.target_version != cur_version:
    201             if self.target_version > cur_version:
    202                 bv = get_build_version()
    203             elif self.target_version < '2.4':
    204                 bv = 6.0
    205             else:
    206                 bv = 7.1
    207         else:
    208             bv = get_build_version()
    209         directory = os.path.dirname(__file__)
    210         if self.plat_name != 'win32' and self.plat_name[:3] == 'win':
    211             sfix = self.plat_name[3:]
    212         else:
    213             sfix = ''
    214         filename = os.path.join(directory, 'wininst-%.1f%s.exe' % (bv, sfix))
    215         f = open(filename, 'rb')
    216         try:
    217             return f.read()
    218         finally:
    219             f.close()