Merged wxPython 2.4.x to the 2.5 branch (Finally!!!)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19793 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		
							
								
								
									
										242
									
								
								wxPython/distutils/command/bdist_wininst.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								wxPython/distutils/command/bdist_wininst.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,242 @@
 | 
			
		||||
"""distutils.command.bdist_wininst
 | 
			
		||||
 | 
			
		||||
Implements the Distutils 'bdist_wininst' command: create a windows installer
 | 
			
		||||
exe-program."""
 | 
			
		||||
 | 
			
		||||
# This module should be kept compatible with Python 1.5.2.
 | 
			
		||||
 | 
			
		||||
__revision__ = "$Id$"
 | 
			
		||||
 | 
			
		||||
import sys, os, string
 | 
			
		||||
from distutils.core import Command
 | 
			
		||||
from distutils.util import get_platform
 | 
			
		||||
from distutils.dir_util import create_tree, remove_tree
 | 
			
		||||
from distutils.errors import *
 | 
			
		||||
from distutils.sysconfig import get_python_version
 | 
			
		||||
from distutils import log
 | 
			
		||||
 | 
			
		||||
class bdist_wininst (Command):
 | 
			
		||||
 | 
			
		||||
    description = "create an executable installer for MS Windows"
 | 
			
		||||
 | 
			
		||||
    user_options = [('bdist-dir=', None,
 | 
			
		||||
                     "temporary directory for creating the distribution"),
 | 
			
		||||
                    ('keep-temp', 'k',
 | 
			
		||||
                     "keep the pseudo-installation tree around after " +
 | 
			
		||||
                     "creating the distribution archive"),
 | 
			
		||||
                    ('target-version=', 'v',
 | 
			
		||||
                     "require a specific python version" +
 | 
			
		||||
                     " on the target system"),
 | 
			
		||||
                    ('no-target-compile', 'c',
 | 
			
		||||
                     "do not compile .py to .pyc on the target system"),
 | 
			
		||||
                    ('no-target-optimize', 'o',
 | 
			
		||||
                     "do not compile .py to .pyo (optimized)"
 | 
			
		||||
                     "on the target system"),
 | 
			
		||||
                    ('dist-dir=', 'd',
 | 
			
		||||
                     "directory to put final built distributions in"),
 | 
			
		||||
                    ('bitmap=', 'b',
 | 
			
		||||
                     "bitmap to use for the installer instead of python-powered logo"),
 | 
			
		||||
                    ('title=', 't',
 | 
			
		||||
                     "title to display on the installer background instead of default"),
 | 
			
		||||
                    ('skip-build', None,
 | 
			
		||||
                     "skip rebuilding everything (for testing/debugging)"),
 | 
			
		||||
                    ('install-script=', None,
 | 
			
		||||
                     "basename of installation script to be run after"
 | 
			
		||||
                     "installation or before deinstallation"),
 | 
			
		||||
                   ]
 | 
			
		||||
 | 
			
		||||
    boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
 | 
			
		||||
                       'skip-build']
 | 
			
		||||
 | 
			
		||||
    def initialize_options (self):
 | 
			
		||||
        self.bdist_dir = None
 | 
			
		||||
        self.keep_temp = 0
 | 
			
		||||
        self.no_target_compile = 0
 | 
			
		||||
        self.no_target_optimize = 0
 | 
			
		||||
        self.target_version = None
 | 
			
		||||
        self.dist_dir = None
 | 
			
		||||
        self.bitmap = None
 | 
			
		||||
        self.title = None
 | 
			
		||||
        self.skip_build = 0
 | 
			
		||||
        self.install_script = None
 | 
			
		||||
 | 
			
		||||
    # initialize_options()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def finalize_options (self):
 | 
			
		||||
        if self.bdist_dir is None:
 | 
			
		||||
            bdist_base = self.get_finalized_command('bdist').bdist_base
 | 
			
		||||
            self.bdist_dir = os.path.join(bdist_base, 'wininst')
 | 
			
		||||
        if not self.target_version:
 | 
			
		||||
            self.target_version = ""
 | 
			
		||||
        if self.distribution.has_ext_modules():
 | 
			
		||||
            short_version = get_python_version()
 | 
			
		||||
            if self.target_version and self.target_version != short_version:
 | 
			
		||||
                raise DistutilsOptionError, \
 | 
			
		||||
                      "target version can only be" + short_version
 | 
			
		||||
            self.target_version = short_version
 | 
			
		||||
 | 
			
		||||
        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
 | 
			
		||||
 | 
			
		||||
        if self.install_script:
 | 
			
		||||
            for script in self.distribution.scripts:
 | 
			
		||||
                if self.install_script == os.path.basename(script):
 | 
			
		||||
                    break
 | 
			
		||||
            else:
 | 
			
		||||
                raise DistutilsOptionError, \
 | 
			
		||||
                      "install_script '%s' not found in scripts" % \
 | 
			
		||||
                      self.install_script
 | 
			
		||||
    # finalize_options()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def run (self):
 | 
			
		||||
        if (sys.platform != "win32" and
 | 
			
		||||
            (self.distribution.has_ext_modules() or
 | 
			
		||||
             self.distribution.has_c_libraries())):
 | 
			
		||||
            raise DistutilsPlatformError \
 | 
			
		||||
                  ("distribution contains extensions and/or C libraries; "
 | 
			
		||||
                   "must be compiled on a Windows 32 platform")
 | 
			
		||||
 | 
			
		||||
        if not self.skip_build:
 | 
			
		||||
            self.run_command('build')
 | 
			
		||||
 | 
			
		||||
        install = self.reinitialize_command('install')
 | 
			
		||||
        install.root = self.bdist_dir
 | 
			
		||||
        install.skip_build = self.skip_build
 | 
			
		||||
        install.warn_dir = 0
 | 
			
		||||
 | 
			
		||||
        install_lib = self.reinitialize_command('install_lib')
 | 
			
		||||
        # we do not want to include pyc or pyo files
 | 
			
		||||
        install_lib.compile = 0
 | 
			
		||||
        install_lib.optimize = 0
 | 
			
		||||
 | 
			
		||||
        # Use a custom scheme for the zip-file, because we have to decide
 | 
			
		||||
        # at installation time which scheme to use.
 | 
			
		||||
        for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'):
 | 
			
		||||
            value = string.upper(key)
 | 
			
		||||
            if key == 'headers':
 | 
			
		||||
                value = value + '/Include/$dist_name'
 | 
			
		||||
            setattr(install,
 | 
			
		||||
                    'install_' + key,
 | 
			
		||||
                    value)
 | 
			
		||||
 | 
			
		||||
        log.info("installing to %s", self.bdist_dir)
 | 
			
		||||
        install.ensure_finalized()
 | 
			
		||||
 | 
			
		||||
        # avoid warning of 'install_lib' about installing
 | 
			
		||||
        # into a directory not in sys.path
 | 
			
		||||
        sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
 | 
			
		||||
 | 
			
		||||
        install.run()
 | 
			
		||||
 | 
			
		||||
        del sys.path[0]
 | 
			
		||||
 | 
			
		||||
        # And make an archive relative to the root of the
 | 
			
		||||
        # pseudo-installation tree.
 | 
			
		||||
        from tempfile import mktemp
 | 
			
		||||
        archive_basename = mktemp()
 | 
			
		||||
        fullname = self.distribution.get_fullname()
 | 
			
		||||
        arcname = self.make_archive(archive_basename, "zip",
 | 
			
		||||
                                    root_dir=self.bdist_dir)
 | 
			
		||||
        # create an exe containing the zip-file
 | 
			
		||||
        self.create_exe(arcname, fullname, self.bitmap)
 | 
			
		||||
        # remove the zip-file again
 | 
			
		||||
        log.debug("removing temporary file '%s'", arcname)
 | 
			
		||||
        os.remove(arcname)
 | 
			
		||||
 | 
			
		||||
        if not self.keep_temp:
 | 
			
		||||
            remove_tree(self.bdist_dir, dry_run=self.dry_run)
 | 
			
		||||
 | 
			
		||||
    # run()
 | 
			
		||||
 | 
			
		||||
    def get_inidata (self):
 | 
			
		||||
        # Return data describing the installation.
 | 
			
		||||
 | 
			
		||||
        lines = []
 | 
			
		||||
        metadata = self.distribution.metadata
 | 
			
		||||
 | 
			
		||||
        # Write the [metadata] section.  Values are written with
 | 
			
		||||
        # repr()[1:-1], so they do not contain unprintable characters, and
 | 
			
		||||
        # are not surrounded by quote chars.
 | 
			
		||||
        lines.append("[metadata]")
 | 
			
		||||
 | 
			
		||||
        # 'info' will be displayed in the installer's dialog box,
 | 
			
		||||
        # describing the items to be installed.
 | 
			
		||||
        info = (metadata.long_description or '') + '\n'
 | 
			
		||||
 | 
			
		||||
        for name in ["author", "author_email", "description", "maintainer",
 | 
			
		||||
                     "maintainer_email", "name", "url", "version"]:
 | 
			
		||||
            data = getattr(metadata, name, "")
 | 
			
		||||
            if data:
 | 
			
		||||
                info = info + ("\n    %s: %s" % \
 | 
			
		||||
                               (string.capitalize(name), data))
 | 
			
		||||
                lines.append("%s=%s" % (name, repr(data)[1:-1]))
 | 
			
		||||
 | 
			
		||||
        # The [setup] section contains entries controlling
 | 
			
		||||
        # the installer runtime.
 | 
			
		||||
        lines.append("\n[Setup]")
 | 
			
		||||
        if self.install_script:
 | 
			
		||||
            lines.append("install_script=%s" % self.install_script)
 | 
			
		||||
        lines.append("info=%s" % repr(info)[1:-1])
 | 
			
		||||
        lines.append("target_compile=%d" % (not self.no_target_compile))
 | 
			
		||||
        lines.append("target_optimize=%d" % (not self.no_target_optimize))
 | 
			
		||||
        if self.target_version:
 | 
			
		||||
            lines.append("target_version=%s" % self.target_version)
 | 
			
		||||
 | 
			
		||||
        title = self.title or self.distribution.get_fullname()
 | 
			
		||||
        lines.append("title=%s" % repr(title)[1:-1])
 | 
			
		||||
        import time
 | 
			
		||||
        import distutils
 | 
			
		||||
        build_info = "Build %s with distutils-%s" % \
 | 
			
		||||
                     (time.ctime(time.time()), distutils.__version__)
 | 
			
		||||
        lines.append("build_info=%s" % build_info)
 | 
			
		||||
        return string.join(lines, "\n")
 | 
			
		||||
 | 
			
		||||
    # get_inidata()
 | 
			
		||||
 | 
			
		||||
    def create_exe (self, arcname, fullname, bitmap=None):
 | 
			
		||||
        import struct
 | 
			
		||||
 | 
			
		||||
        self.mkpath(self.dist_dir)
 | 
			
		||||
 | 
			
		||||
        cfgdata = self.get_inidata()
 | 
			
		||||
 | 
			
		||||
        if self.target_version:
 | 
			
		||||
            # if we create an installer for a specific python version,
 | 
			
		||||
            # it's better to include this in the name
 | 
			
		||||
            installer_name = os.path.join(self.dist_dir,
 | 
			
		||||
                                          "%s.win32-py%s.exe" %
 | 
			
		||||
                                           (fullname, self.target_version))
 | 
			
		||||
        else:
 | 
			
		||||
            installer_name = os.path.join(self.dist_dir,
 | 
			
		||||
                                          "%s.win32.exe" % fullname)
 | 
			
		||||
        self.announce("creating %s" % installer_name)
 | 
			
		||||
 | 
			
		||||
        if bitmap:
 | 
			
		||||
            bitmapdata = open(bitmap, "rb").read()
 | 
			
		||||
            bitmaplen = len(bitmapdata)
 | 
			
		||||
        else:
 | 
			
		||||
            bitmaplen = 0
 | 
			
		||||
 | 
			
		||||
        file = open(installer_name, "wb")
 | 
			
		||||
        file.write(self.get_exe_bytes())
 | 
			
		||||
        if bitmap:
 | 
			
		||||
            file.write(bitmapdata)
 | 
			
		||||
 | 
			
		||||
        file.write(cfgdata)
 | 
			
		||||
        header = struct.pack("<iii",
 | 
			
		||||
                             0x1234567A,       # tag
 | 
			
		||||
                             len(cfgdata),     # length
 | 
			
		||||
                             bitmaplen,        # number of bytes in bitmap
 | 
			
		||||
                             )
 | 
			
		||||
        file.write(header)
 | 
			
		||||
        file.write(open(arcname, "rb").read())
 | 
			
		||||
 | 
			
		||||
    # create_exe()
 | 
			
		||||
 | 
			
		||||
    def get_exe_bytes (self):
 | 
			
		||||
        # wininst.exe is in the same directory as this file
 | 
			
		||||
        directory = os.path.dirname(__file__)
 | 
			
		||||
        filename = os.path.join(directory, "wininst.exe")
 | 
			
		||||
        return open(filename, "rb").read()
 | 
			
		||||
# class bdist_wininst
 | 
			
		||||
		Reference in New Issue
	
	Block a user