Makespec.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 » Makespec.py
#!/usr/bin/env python
#
# Automatically build spec files containing a description of the project
#
# 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 sys, os, string

# For Python 1.5 compatibility
try:
    True, False
except:
    True  = 1 == 1
    False = not True

freezetmplt = """# -*- mode: python -*-
a = Analysis(%(scripts)s,
             pathex=%(pathex)s)
pyz = PYZ(a.pure)
exe = EXE(%(tkpkg)s pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join(%(distdir)s, '%(exename)s'),
          debug=%(debug)s,
          strip=%(strip)s,
          upx=%(upx)s,
          console=%(console)s %(exe_options)s)
""" # pathex scripts exename tkpkg debug console distdir

collecttmplt = """# -*- mode: python -*-
a = Analysis(%(scripts)s,
             pathex=%(pathex)s)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=1,
          name=os.path.join(%(builddir)s, '%(exename)s'),
          debug=%(debug)s,
          strip=%(strip)s,
          upx=%(upx)s,
          console=%(console)s %(exe_options)s)
coll = COLLECT(%(tktree)s exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=%(strip)s,
               upx=%(upx)s,
               name=os.path.join(%(distdir)s, '%(name)s'))
""" # scripts pathex, exename, debug, console tktree distdir name

comsrvrtmplt = """# -*- mode: python -*-
a = Analysis(%(scripts)s,
             pathex=%(pathex)s)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=1,
          name=os.path.join(%(builddir)s, '%(exename)s'),
          debug=%(debug)s,
          strip=%(strip)s,
          upx=%(upx)s,
          console=%(console)s %(exe_options)s)
dll = DLL(pyz,
          a.scripts,
          exclude_binaries=1,
          name=os.path.join(%(builddir)s, '%(dllname)s'),
          debug=%(debug)s)
coll = COLLECT(exe, dll,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=%(strip)s,
               upx=%(upx)s,
               name=os.path.join(%(distdir)s, '%(name)s'))
""" # scripts pathex, exename, debug, console tktree distdir name

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

def quote_win_filepath( path ):
    # quote all \ with another \ after using normpath to clean up the path
    return string.join( string.split( os.path.normpath( path ), '\\' ), '\\\\' )

# Support for trying to avoid hard-coded paths in the .spec files.
# Eg, all files rooted in the Installer directory tree will be
# written using "HOMEPATH", thus allowing this spec file to
# be used with any Installer installation.
# Same thing could be done for other paths too.
path_conversions = (
    (HOME, "HOMEPATH"),
    # Add Tk etc?
    )

def make_variable_path(filename, conversions = path_conversions):
    for (from_path, to_name) in conversions:
        assert os.path.abspath(from_path)==from_path, \
            "path '%s' should already be absolute" % (from_path,)
        if filename[:len(from_path)] == from_path:
            rest = filename[len(from_path):]
            if rest[0] in "\\/":
                rest = rest[1:]
            return to_name, rest
    return None, filename

# An object used in place of a "path string" which knows how to repr()
# itself using variable names instead of hard-coded paths.
class Path:
    def __init__(self, *parts):
        self.path = apply(os.path.join, parts)
        self.variable_prefix = self.filename_suffix = None
    def __repr__(self):
        if self.filename_suffix is None:
            self.variable_prefix, self.filename_suffix = make_variable_path(self.path)
        if self.variable_prefix is None:
            return repr(self.path)
        return "os.path.join(" + self.variable_prefix + "," + repr(self.filename_suffix) + ")"


def main(scripts, configfile=None, name=None, tk=0, freeze=0, console=1, debug=0,
         strip=0, upx=0, comserver=0, ascii=0, workdir=None,
         pathex=[], version_file=None, icon_file=None, manifest=None, resources=[], crypt=None):

    try:
        config = eval(open(configfile, 'r').read())
    except IOError:
        raise SystemExit("Configfile is missing or unreadable. Please run Configure.py before building!")

    if config['pythonVersion'] != sys.version:
        print "The current version of Python is not the same with which PyInstaller was configured."
        print "Please re-run Configure.py with this version."
        raise SystemExit(1)

    if not name:
        name = os.path.splitext(os.path.basename(scripts[0]))[0]

    distdir = "dist"
    builddir = os.path.join('build', 'pyi.' + config['target_platform'], name)

    pathex = pathex[:]
    if workdir is None:
        workdir = os.getcwd()
        pathex.append(workdir)
    else:
        pathex.append(os.getcwd())
    if workdir == HOME:
        workdir = os.path.join(HOME, name)
    if not os.path.exists(workdir):
        os.makedirs(workdir)
    exe_options = ''
    if version_file:
        exe_options = "%s, version='%s'" % (exe_options, quote_win_filepath(version_file))
    if icon_file:
        exe_options = "%s, icon='%s'" % (exe_options, quote_win_filepath(icon_file))
    if manifest:
    if "<" in manifest:
      # Assume XML string
      exe_options = "%s, manifest='%s'" % (exe_options, manifest.replace("'", "\\'"))
    else:
      # Assume filename
      exe_options = "%s, manifest='%s'" % (exe_options, quote_win_filepath(manifest))
    if resources:
        for i in range(len(resources)):
            resources[i] = quote_win_filepath(resources[i])
        exe_options = "%s, resources=%s" % (exe_options, repr(resources))
    if not ascii and config['hasUnicode']:
        scripts.insert(0, os.path.join(HOME, 'support', 'useUnicode.py'))
    for i in range(len(scripts)):
        scripts[i] = Path(scripts[i]) # Use relative path in specfiles

    d = {'tktree':'',
         'tkpkg' :'',
         'scripts':scripts,
         'pathex' :pathex,
         #'exename': '',
         'name': name,
         'distdir': repr(distdir),
         'builddir': repr(builddir),
         'debug': debug,
         'strip': strip,
         'upx' : upx,
         'crypt' : repr(crypt),
         'crypted': crypt is not None,
         'console': console or debug,
         'exe_options': exe_options}
    if tk:
        d['tktree'] = "TkTree(),"
        if freeze:
            scripts.insert(0, Path(HOME, 'support', 'useTK.py'))
            scripts.insert(0, Path(HOME, 'support', 'unpackTK.py'))
            scripts.append(Path(HOME, 'support', 'removeTK.py'))
            d['tkpkg'] = "TkPKG(),"
        else:
            scripts.insert(0, Path(HOME, 'support', 'useTK.py'))
    scripts.insert(0, Path(HOME, 'support', '_mountzlib.py'))
    if config['target_platform'][:3] == "win" or \
       config['target_platform'] == 'cygwin':
        d['exename'] = name+'.exe'
        d['dllname'] = name+'.dll'
    else:
        d['exename'] = name
        d['console'] = 1
    specfnm = os.path.join(workdir, name+'.spec')
    specfile = open(specfnm, 'w')
    if freeze:
        specfile.write(freezetmplt % d)
    elif comserver:
        specfile.write(comsrvrtmplt % d)
    else:
        specfile.write(collecttmplt % d)
    specfile.close()
    return specfnm


if __name__ == '__main__':
    import pyi_optparse as optparse
    p = optparse.OptionParser(
        usage="python %prog [opts] <scriptname> [<scriptname> ...]"
    )
    p.add_option('-C', '--configfile',
                 default=os.path.join(HOME, 'config.dat'),
                 help='Name of configfile (default: %default)')

    g = p.add_option_group('What to generate')
    g.add_option("-F", "--onefile", dest="freeze",
                 action="store_true", default=False,
                 help="create a single file deployment")
    g.add_option("-D", "--onedir", dest="freeze", action="store_false",
                 help="create a single directory deployment (default)")
    g.add_option("-o", "--out", type="string", default=None,
                 dest="workdir", metavar="DIR",
                 help="generate the spec file in the specified directory "
                      "(default: current directory")
    g.add_option("-n", "--name", type="string", default=None,
                 metavar="NAME",
                 help="name to assign to the project "
                      "(default: first script's basename)")

    g = p.add_option_group('What to bundle, where to search')
    g.add_option("-p", "--paths", type="string", default=[], dest="pathex",
                 metavar="DIR", action="append",
                 help="set base path for import (like using PYTHONPATH). "
                      "Multiple directories are allowed, separating them "
                      "with %s, or using this option multiple times"
                      % repr(os.pathsep))
    g.add_option("-K", "--tk", default=False, action="store_true",
                 help="include TCL/TK in the deployment")
    g.add_option("-a", "--ascii", action="store_true", default=False,
                 help="do NOT include unicode encodings "
                      "(default: included if available)")

    g = p.add_option_group('How to generate')
    g.add_option("-d", "--debug", action="store_true", default=False,
                 help="use the debug (verbose) build of the executable")
    g.add_option("-s", "--strip", action="store_true", default=False,
                 help="strip the exe and shared libs "
                      "(don't try this on Windows)")
    g.add_option("-X", "--upx", action="store_true", default=True,
                 help="use UPX if available (works differently between "
                      "Windows and *nix)")
    #p.add_option("-Y", "--crypt", type="string", default=None, metavar="FILE",
    #             help="encrypt pyc/pyo files")

    g = p.add_option_group('Windows specific options')
    g.add_option("-c", "--console", "--nowindowed", dest="console",
                 action="store_true",
                 help="use a console subsystem executable (Windows only) "
                      "(default)")
    g.add_option("-w", "--windowed", "--noconsole", dest="console",
                 action="store_false", default=True,
                 help="use a Windows subsystem executable (Windows only)")
    g.add_option("-v", "--version", type="string",
                 dest="version_file", metavar="FILE",
                 help="add a version resource from FILE to the exe "
                      "(Windows only)")
    g.add_option("-i", "--icon", type="string", dest="icon_file",
                 metavar="FILE.ICO or FILE.EXE,ID",
                 help="If FILE is an .ico file, add the icon to the final "
                      "executable. Otherwise, the syntax 'file.exe,id' to "
                      "extract the icon with the specified id "
                      "from file.exe and add it to the final executable")
    g.add_option("-m", "--manifest", type="string",
                 dest="manifest", metavar="FILE or XML",
                 help="add manifest FILE or XML to the exe "
                      "(Windows only)")
    g.add_option("-r", "--resource", type="string", default=[], dest="resources",
                 metavar="FILE[,TYPE[,NAME[,LANGUAGE]]]", action="append",
                 help="add/update resource of the given type, name and language "
                      "from FILE to the final executable. FILE can be a "
                      "data file or an exe/dll. For data files, atleast "
                      "TYPE and NAME need to be specified, LANGUAGE defaults "
                      "to 0 or may be specified as wildcard * to update all "
                      "resources of the given TYPE and NAME. For exe/dll "
                      "files, all resources from FILE will be added/updated "
                      "to the final executable if TYPE, NAME and LANGUAGE "
                      "are omitted or specified as wildcard *."
                      "Multiple resources are allowed, using this option "
                      "multiple times.")

    opts,args = p.parse_args()

    # Split pathex by using the path separator
    temppaths = opts.pathex[:]
    opts.pathex = []
    for p in temppaths:
        opts.pathex.extend(string.split(p, os.pathsep))

    if not args:
        p.error('Requires at least one scriptname file')

    name = apply(main, (args,), opts.__dict__)
    print "wrote %s" % name
    print "now run Build.py to build the executable"
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.