srcanamdw/codescanner/pyinstaller/Makespec.py
changeset 1 22878952f6e2
equal deleted inserted replaced
0:509e4801c378 1:22878952f6e2
       
     1 #! /usr/bin/env/python
       
     2 # Automatically build spec files containing a description of the project
       
     3 # Copyright (C) 2005, Giovanni Bajo
       
     4 # Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
       
     5 #
       
     6 # This program is free software; you can redistribute it and/or
       
     7 # modify it under the terms of the GNU General Public License
       
     8 # as published by the Free Software Foundation; either version 2
       
     9 # of the License, or (at your option) any later version.
       
    10 #
       
    11 # This program is distributed in the hope that it will be useful,
       
    12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    14 # GNU General Public License for more details.
       
    15 #
       
    16 # You should have received a copy of the GNU General Public License
       
    17 # along with this program; if not, write to the Free Software
       
    18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
       
    19 
       
    20 import sys, os, string
       
    21 
       
    22 # For Python 1.5 compatibility
       
    23 try:
       
    24     True
       
    25 except:
       
    26     True,False = 1,0
       
    27 
       
    28 freezetmplt = """\
       
    29 a = Analysis(%(scripts)s,
       
    30              pathex=%(pathex)s)
       
    31 pyz = PYZ(a.pure)
       
    32 exe = EXE(%(tkpkg)s pyz,
       
    33           a.scripts,
       
    34           a.binaries,
       
    35           name='%(exename)s',
       
    36           debug=%(debug)s,
       
    37           strip=%(strip)s,
       
    38           upx=%(upx)s,
       
    39           console=%(console)s %(exe_options)s)
       
    40 """ # pathex scripts exename tkpkg debug console
       
    41 
       
    42 collecttmplt = """\
       
    43 a = Analysis(%(scripts)s,
       
    44              pathex=%(pathex)s)
       
    45 pyz = PYZ(a.pure)
       
    46 exe = EXE(pyz,
       
    47           a.scripts,
       
    48           exclude_binaries=1,
       
    49           name='%(builddir)s/%(exename)s',
       
    50           debug=%(debug)s,
       
    51           strip=%(strip)s,
       
    52           upx=%(upx)s,
       
    53           console=%(console)s %(exe_options)s)
       
    54 coll = COLLECT(%(tktree)s exe,
       
    55                a.binaries,
       
    56                strip=%(strip)s,
       
    57                upx=%(upx)s,
       
    58                name='%(distdir)s')
       
    59 """ # scripts pathex, exename, debug, console tktree distdir
       
    60 
       
    61 comsrvrtmplt = """\
       
    62 a = Analysis(%(scripts)s,
       
    63              pathex=%(pathex)s)
       
    64 pyz = PYZ(a.pure)
       
    65 exe = EXE(pyz,
       
    66           a.scripts,
       
    67           exclude_binaries=1,
       
    68           name='%(builddir)s/%(exename)s',
       
    69           debug=%(debug)s,
       
    70           strip=%(strip)s,
       
    71           upx=%(upx)s,
       
    72           console=%(console)s %(exe_options)s)
       
    73 dll = DLL(pyz,
       
    74           a.scripts,
       
    75           exclude_binaries=1,
       
    76           name='%(builddir)s/%(dllname)s',
       
    77           debug=%(debug)s)
       
    78 coll = COLLECT(exe, dll,
       
    79                a.binaries,
       
    80                strip=%(strip)s,
       
    81                upx=%(upx)s,
       
    82                name='%(distdir)s')
       
    83 """ # scripts pathex, exename, debug, console tktree distdir
       
    84 HOME = os.path.dirname(sys.argv[0])
       
    85 if HOME == '':
       
    86     HOME = os.getcwd()
       
    87 if not os.path.isabs(HOME):
       
    88     HOME = os.path.abspath(HOME)
       
    89 iswin = sys.platform[:3] == "win"
       
    90 cygwin = sys.platform == "cygwin"
       
    91 try:
       
    92     config = eval(open(os.path.join(HOME, 'config.dat'), 'r').read())
       
    93 except IOError:
       
    94     print "You must run Configure.py before building!"
       
    95     sys.exit(1)
       
    96 
       
    97 if config['pythonVersion'] != sys.version:
       
    98     print "The current version of Python is not the same with which PyInstaller was configured."
       
    99     print "Please re-run Configure.py with this version."
       
   100     sys.exit(1)
       
   101 
       
   102 def quote_win_filepath( path ):
       
   103     # quote all \ with another \ after using normpath to clean up the path
       
   104     return string.join( string.split( os.path.normpath( path ), '\\' ), '\\\\' )
       
   105 
       
   106 # Support for trying to avoid hard-coded paths in the .spec files.
       
   107 # Eg, all files rooted in the Installer directory tree will be
       
   108 # written using "HOMEPATH", thus allowing this spec file to
       
   109 # be used with any Installer installation.
       
   110 # Same thing could be done for other paths too.
       
   111 path_conversions = (
       
   112     (HOME, "HOMEPATH"),
       
   113     # Add Tk etc?
       
   114     )
       
   115 
       
   116 def make_variable_path(filename, conversions = path_conversions):
       
   117     for (from_path, to_name) in conversions:
       
   118         assert os.path.abspath(from_path)==from_path, \
       
   119             "path '%s' should already be absolute" % (from_path,)
       
   120         if filename[:len(from_path)] == from_path:
       
   121             rest = filename[len(from_path):]
       
   122             if rest[0] in "\\/":
       
   123                 rest = rest[1:]
       
   124             return to_name, rest
       
   125     return None, filename
       
   126 
       
   127 # An object used in place of a "path string" which knows how to repr()
       
   128 # itself using variable names instead of hard-coded paths.
       
   129 class Path:
       
   130     def __init__(self, *parts):
       
   131         self.path = apply(os.path.join, parts)
       
   132         self.variable_prefix = self.filename_suffix = None
       
   133     def __repr__(self):
       
   134         if self.filename_suffix is None:
       
   135             self.variable_prefix, self.filename_suffix = make_variable_path(self.path)
       
   136         if self.variable_prefix is None:
       
   137             return repr(self.path)
       
   138         return "os.path.join(" + self.variable_prefix + "," + repr(self.filename_suffix) + ")"
       
   139 
       
   140 def main(scripts, name=None, tk=0, freeze=0, console=1, debug=0, strip=0, upx=0,
       
   141          comserver=0, ascii=0, workdir=None, pathex=[], version_file=None, icon_file=None):
       
   142     if name is None:
       
   143         name = os.path.splitext(os.path.basename(scripts[0]))[0]
       
   144     distdir = "dist%s" % name
       
   145     builddir = "build%s" % name
       
   146     pathex = pathex[:]
       
   147     if workdir is None:
       
   148         workdir = os.getcwd()
       
   149         pathex.append(workdir)
       
   150     else:
       
   151         pathex.append(os.getcwd())
       
   152     if workdir == HOME:
       
   153         workdir = os.path.join(HOME, name)
       
   154     if not os.path.exists(workdir):
       
   155         os.makedirs(workdir)
       
   156     exe_options = ''
       
   157     if version_file:
       
   158         exe_options = "%s, version='%s'" % (exe_options, quote_win_filepath(version_file))
       
   159     if icon_file:
       
   160         exe_options = "%s, icon='%s'" % (exe_options, quote_win_filepath(icon_file))
       
   161     if not ascii and config['hasUnicode']:
       
   162         scripts.insert(0, os.path.join(HOME, 'support', 'useUnicode.py'))
       
   163     for i in range(len(scripts)):
       
   164         scripts[i] = Path(scripts[i]) # Use relative path in specfiles
       
   165 
       
   166     d = {'tktree':'',
       
   167          'tkpkg' :'',
       
   168          'scripts':scripts,
       
   169          'pathex' :pathex,
       
   170          'exename': '',
       
   171          'distdir': distdir,
       
   172          'builddir': builddir,
       
   173          'debug': debug,
       
   174          'strip': strip,
       
   175          'upx' : upx,
       
   176          'console': console or debug,
       
   177          'exe_options': exe_options}
       
   178     if tk:
       
   179         d['tktree'] = "TkTree(),"
       
   180         if freeze:
       
   181             scripts.insert(0, Path(HOME, 'support', 'useTK.py'))
       
   182             scripts.insert(0, Path(HOME, 'support', 'unpackTK.py'))
       
   183             scripts.append(Path(HOME, 'support', 'removeTK.py'))
       
   184             d['tkpkg'] = "TkPKG(),"
       
   185         else:
       
   186             scripts.insert(0, Path(HOME, 'support', 'useTK.py'))
       
   187     scripts.insert(0, Path(HOME, 'support', '_mountzlib.py'))
       
   188     if iswin or cygwin:
       
   189         d['exename'] = name+'.exe'
       
   190         d['dllname'] = name+'.dll'
       
   191     else:
       
   192         d['exename'] = name
       
   193         d['console'] = 1
       
   194     specfnm = os.path.join(workdir, name+'.spec')
       
   195     specfile = open(specfnm, 'w')
       
   196     if freeze:
       
   197         specfile.write(freezetmplt % d)
       
   198     elif comserver:
       
   199         specfile.write(comsrvrtmplt % d)
       
   200     else:
       
   201         specfile.write(collecttmplt % d)
       
   202     specfile.close()
       
   203     return specfnm
       
   204 
       
   205 if __name__ == '__main__':
       
   206     import optparse
       
   207     p = optparse.OptionParser(
       
   208         usage="python %prog [opts] <scriptname> [<scriptname> ...]"
       
   209     )
       
   210     p.add_option("-F", "--onefile", dest="freeze",
       
   211                  action="store_true", default=False,
       
   212                  help="create a single file deployment")
       
   213     p.add_option("-D", "--onedir", dest="freeze", action="store_false",
       
   214                  help="create a single directory deployment (default)")
       
   215     p.add_option("-w", "--windowed", "--noconsole", dest="console",
       
   216                  action="store_false", default=True,
       
   217                  help="use a Windows subsystem executable (Windows only)")
       
   218     p.add_option("-c", "--nowindowed", "--console", dest="console",
       
   219                  action="store_true",
       
   220                  help="use a console subsystem executable (Windows only) "
       
   221                       "(default)")
       
   222     p.add_option("-a", "--ascii", action="store_true", default=False,
       
   223                  help="do NOT include unicode encodings "
       
   224                       "(default: included if available)")
       
   225     p.add_option("-d", "--debug", action="store_true", default=False,
       
   226                  help="use the debug (verbose) build of the executable")
       
   227     p.add_option("-s", "--strip", action="store_true", default=False,
       
   228                  help="strip the exe and shared libs "
       
   229                       "(don't try this on Windows)")
       
   230     p.add_option("-X", "--upx", action="store_true", default=False,
       
   231                  help="use UPX if available (works differently between "
       
   232                       "Windows and *nix)")
       
   233     p.add_option("-K", "--tk", default=False, action="store_true",
       
   234                  help="include TCL/TK in the deployment")
       
   235     p.add_option("-o", "--out", type="string", default=None,
       
   236                  dest="workdir", metavar="DIR",
       
   237                  help="generate the spec file in the specified directory")
       
   238     p.add_option("-n", "--name", type="string", default=None,
       
   239                  help="name to assign to the project, from which the spec file "
       
   240                       "name is generated. (default: use the basename of the "
       
   241                       "(first) script)")
       
   242     p.add_option("-p", "--paths", type="string", default=[], dest="pathex",
       
   243                  metavar="DIR", action="append",
       
   244                  help="set base path for import (like using PYTHONPATH). "
       
   245                       "Multiple directories are allowed, separating them "
       
   246                       "with %s, or using this option multiple times"
       
   247                       % repr(os.pathsep))
       
   248     p.add_option("-v", "--version", type="string",
       
   249                  dest="version_file", metavar="FILE",
       
   250                  help="add a version resource from FILE to the exe "
       
   251                       "(Windows only)")
       
   252     p.add_option("--icon", type="string", dest="icon_file",
       
   253                  metavar="FILE.ICO or FILE.EXE,ID",
       
   254                  help="If FILE is an .ico file, add the icon to the final "
       
   255                       "executable. Otherwise, the syntax 'file.exe,id' to "
       
   256                       "extract the icon with the specified id "
       
   257                       "from file.exe and add it to the final executable")
       
   258 
       
   259     opts,args = p.parse_args()
       
   260 
       
   261     # Split pathex by using the path separator
       
   262     temppaths = opts.pathex[:]
       
   263     opts.pathex = []
       
   264     for p in temppaths:
       
   265         opts.pathex.extend(string.split(p, os.pathsep))
       
   266 
       
   267     if not args:
       
   268         p.print_help()
       
   269         sys.exit(1)
       
   270 
       
   271     nm = apply(main, (args,), opts.__dict__)
       
   272     print "wrote %s" % nm
       
   273     print "now run Build.py to build the executable"