Configure.py :  » Installer » PyInstaller » trunk » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Installer » PyInstaller 
PyInstaller » trunk » Configure.py
#! /usr/bin/env python
#
# Configure PyInstaller for the current Python installation.
#
# Copyright (C) 2005, Giovanni Bajo
# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

import os
import sys
import string
import shutil
import pprint
import re
import glob

import platform
import mf
import bindepend
import Build

HOME = os.path.dirname(sys.argv[0])

iswin = sys.platform[:3] == 'win'
is24 = hasattr(sys, "version_info") and sys.version_info[:2] >= (2,4)
is26 = hasattr(sys, "version_info") and sys.version_info[:2] >= (2,6)
cygwin = sys.platform == 'cygwin'

if iswin and platform.architecture()[0] != "32bit":
    print "ERROR: PyInstaller does not support Windows 64-bit"
    print "Subscribe to this ticket for more information:"
    print "    http://www.pyinstaller.org/ticket/25"
    sys.exit(2)

def find_EXE_dependencies(config):
    global target_platform, target_iswin
    print "I: computing EXE_dependencies"
    python = opts.executable or sys.executable
    target_platform = opts.target_platform or sys.platform
    config['python'] = python
    config['target_platform'] = target_platform
    target_iswin = target_platform[:3] == 'win'

    xtrapath = []
    if target_iswin and not iswin:
        # try to find a mounted Windows system
        xtrapath = glob.glob('/mnt/*/WINDOWS/system32/')
        if not xtrapath:
            print "E: Can not find a mounted Windows system"
            print "W: Please set 'xtrpath' in the config file yourself"

    xtrapath = config.get('xtrapath') or xtrapath
    config['xtrapath'] = xtrapath


_useTK = """\
# Generated by Configure.py
# This file is public domain
import os, sys
try:
    basedir = os.environ['_MEIPASS2']
except KeyError:
    basedir = sys.path[0]
tcldir = os.path.join(basedir, '_MEI', 'tcl%s')
tkdir = os.path.join(basedir, '_MEI', 'tk%s')
os.environ["TCL_LIBRARY"] = tcldir
os.environ["TK_LIBRARY"] = tkdir
os.putenv("TCL_LIBRARY", tcldir)
os.putenv("TK_LIBRARY", tkdir)
"""

def test_TCL_TK(config):
    # TCL_root, TK_root and support/useTK.py
    print "I: Finding TCL/TK..."
    if not (target_iswin):
        saveexcludes = bindepend.excludes
        bindepend.excludes = {}
    pattern = [r'libtcl(\d\.\d)?\.(so|dylib)', r'(?i)tcl(\d\d)\.dll'][target_iswin]
    a = mf.ImportTracker()
    a.analyze_r('Tkinter')
    binaries = []
    for modnm, mod in a.modules.items():
        if isinstance(mod, mf.ExtensionModule):
            binaries.append((mod.__name__, mod.__file__, 'EXTENSION'))
    binaries.extend(bindepend.Dependencies(binaries))
    binaries.extend(bindepend.Dependencies([('', sys.executable, '')]))
    for nm, fnm, typ in binaries:
        mo = re.match(pattern, nm)
        if mo:
            ver = mo.group(1)
            tclbindir = os.path.dirname(fnm)
            if target_iswin:
                ver = ver[0] + '.' + ver[1:]
            elif ver is None:
                # we found "libtcl.so.0" so we need to get the version from the lib directory
                for name in os.listdir(tclbindir):
                    mo = re.match(r'tcl(\d.\d)', name)
                    if mo:
                        ver = mo.group(1)
            print "I: found TCL/TK version %s" % ver
            open(os.path.join(HOME, 'support', 'useTK.py'), 'w').write(_useTK % (ver, ver))
            tclnm = 'tcl%s' % ver
            tknm = 'tk%s' % ver
            # Linux: /usr/lib with the .tcl files in /usr/lib/tcl8.3 and /usr/lib/tk8.3
            # Windows: Python21/DLLs with the .tcl files in Python21/tcl/tcl8.3 and Python21/tcl/tk8.3
            #      or  D:/Programs/Tcl/bin with the .tcl files in D:/Programs/Tcl/lib/tcl8.0 and D:/Programs/Tcl/lib/tk8.0
            if target_iswin:
                for attempt in ['../tcl', '../lib']:
                    if os.path.exists(os.path.join(tclbindir, attempt, tclnm)):
                        config['TCL_root'] = os.path.join(tclbindir, attempt, tclnm)
                        config['TK_root'] = os.path.join(tclbindir, attempt, tknm)
                        break
            else:
                config['TCL_root'] = os.path.join(tclbindir, tclnm)
                config['TK_root'] = os.path.join(tclbindir, tknm)
            break
    else:
        print "I: could not find TCL/TK"
    if not target_iswin:
        bindepend.excludes = saveexcludes

def test_Crypt(config):
    # TODO: disabled for now
    config["useCrypt"] = 0
    return 

    #Crypt support. We need to build the AES module and we'll use distutils
    # for that. FIXME: the day we'll use distutils for everything this will be
    # a solved problem.
    print "I: trying to build crypt support..."
    from distutils.core import run_setup
    cwd = os.getcwd()
    try:
        os.chdir(os.path.join(HOME, "source", "crypto"))
        dist = run_setup("setup.py", ["install"])
        if dist.have_run.get("install", 0):
            config["useCrypt"] = 1
            print "I: ... crypto support available"
        else:
            config["useCrypt"] = 0
            print "I: ... error building crypto support"
    finally:
        os.chdir(cwd)

def test_Zlib(config):
    #useZLIB
    print "I: testing for Zlib..."
    try:
        import zlib
        config['useZLIB'] = 1
        print 'I: ... Zlib available'
    except ImportError:
        config['useZLIB'] = 0
        print 'I: ... Zlib unavailable'

def test_RsrcUpdate(config):
    config['hasRsrcUpdate'] = 0
    if not iswin:
        return
    # only available on windows
    print "I: Testing for ability to set icons, version resources..."
    try:
        import win32api, icon, versionInfo
    except ImportError, detail:
        print 'I: ... resource update unavailable -', detail
        return
    
    test_exe = os.path.join(HOME, 'support', 'loader', 'run_7rw.exe')
    if not os.path.exists( test_exe ):
        config['hasRsrcUpdate'] = 0
        print 'E: ... resource update unavailable - %s not found' % test_exe
        return

    # The test_exe may be read-only
    # make a writable copy and test using that
    rw_test_exe = os.path.join( os.environ['TEMP'], 'me_test_exe.tmp' )
    shutil.copyfile( test_exe, rw_test_exe )
    try:
        hexe = win32api.BeginUpdateResource(rw_test_exe, 0)
    except:
        print 'I: ... resource update unavailable - win32api.BeginUpdateResource failed'
    else:
        win32api.EndUpdateResource(hexe, 1)
        config['hasRsrcUpdate'] = 1
        print 'I: ... resource update available'
    os.remove(rw_test_exe)


_useUnicode = """\
# Generated by Configure.py
# This file is public domain
import %s
"""

_useUnicodeFN = os.path.join(HOME, 'support', 'useUnicode.py')

def test_unicode(config):
    print 'I: Testing for Unicode support...'
    try:
        import codecs
        config['hasUnicode'] = 1
        try:
            import encodings
        except ImportError:
            module = "codecs"
        else:
            module = "encodings"
        open(_useUnicodeFN, 'w').write(_useUnicode % module)
        print 'I: ... Unicode available'
    except ImportError:
        try:
            os.remove(_useUnicodeFN)
        except OSError:
            pass
        config['hasUnicode'] = 0
        print 'I: ... Unicode NOT available'

def test_UPX(config):
    print 'I: testing for UPX...'
    cmd = "upx"
    if opts.upx_dir:
        cmd = '"' + os.path.normpath(os.path.join(opts.upx_dir, cmd)) + '"'

    hasUPX = 0
    try:
        vers = os.popen(cmd + ' -V').readlines()
        if vers:
            v = string.split(vers[0])[1]
            hasUPX = tuple(map(int, string.split(v, ".")))
            if iswin and is24 and hasUPX < (1,92):
                print 'E: UPX is too old! Python 2.4 under Windows requires UPX 1.92+'
                hasUPX = 0
        print 'I: ...UPX %s' % (('unavailable','available')[hasUPX != 0])
    except Exception, e:
        print 'I: ...exception result in testing for UPX'
        print e, e.args
    config['hasUPX'] = hasUPX
    config['upx_dir'] = opts.upx_dir


def find_PYZ_dependencies(config):
    print "I: computing PYZ dependencies..."
    a = mf.ImportTracker([os.path.join(HOME, 'support')])
    a.analyze_r('archive')
    mod = a.modules['archive']
    toc = Build.TOC([(mod.__name__, mod.__file__, 'PYMODULE')])
    for i in range(len(toc)):
        nm, fnm, typ = toc[i]
        mod = a.modules[nm]
        tmp = []
        for importednm, isdelayed, isconditional, level in mod.imports:
            if not isconditional:
                realnms = a.analyze_one(importednm, nm)
                for realnm in realnms:
                    imported = a.modules[realnm]
                    if not isinstance(imported, mf.BuiltinModule):
                        tmp.append((imported.__name__, imported.__file__, imported.typ))
        toc.extend(tmp)
    toc.reverse()
    config['PYZ_dependencies'] = toc.data


def main(configfilename):
    try:
        config = Build._load_data(configfilename)
        print 'I: read old config from', configfilename
    except IOError, SyntaxError:
        # IOerror: file not present/readable
        # SyntaxError: invalid file (platform change?)
        # if not set by Make.py we can assume Windows
        config = {'useELFEXE': 1}

    # Save Python version, to detect and avoid conflicts
    config["pythonVersion"] = sys.version
    config["pythonDebug"] = __debug__

    find_EXE_dependencies(config)
    test_TCL_TK(config)
    test_Zlib(config)
    test_Crypt(config)
    test_RsrcUpdate(config)
    test_unicode(config)
    test_UPX(config)
    find_PYZ_dependencies(config)

    Build._save_data(configfilename, config)
    print "I: done generating", configfilename


if __name__ == '__main__':
    from pyi_optparse import OptionParser
    parser = OptionParser(usage="%prog [options]")
    parser.add_option('--target-platform', default=None,
                      help='Target platform, required for cross-bundling '
                           '(default: current platform).')
    parser.add_option('--upx-dir', default=None,
                      help='Directory containing UPX.')
    parser.add_option('--executable', default=None,
                      help='Python executable to use. Required for '
                           'cross-bundling.')
    parser.add_option('-C', '--configfile',
                      default=os.path.join(HOME, 'config.dat'),
                      help='Name of generated configfile (default: %default)')

    opts, args = parser.parse_args()
    if args:
        parser.error('Does not expect any arguments')

    main(opts.configfile)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.