Commit 96c4dd95 authored by Guido van Rossum's avatar Guido van Rossum

OK, now it uses sys.[exec_]prefix and supports

a -o option to specify an output directory.  *Much* more convenient.
Removed a whole lot of hullabaloo from the README file, too.
parent 6498cad3
...@@ -69,63 +69,16 @@ to run.) ...@@ -69,63 +69,16 @@ to run.)
How do I use Freeze? How do I use Freeze?
-------------------- --------------------
Ideally, you should be able to use it as follows: Normally, you should be able to use it as follows:
python freeze.py hello.py python freeze.py hello.py
where hello.py is your program and freeze.py is the main file of where hello.py is your program and freeze.py is the main file of
Freeze (in actuality, you'll probably specify an absolute pathname Freeze (in actuality, you'll probably specify an absolute pathname
such as /ufs/guido/src/python/Tools/freeze/freeze.py). such as /usr/joe/python/Tools/freeze/freeze.py).
Unfortunately, this doesn't work. Well, it might, but somehow it's (With Python 1.4, freeze is much more likely to work "out of the box"
extremely unlikely that it'll work on the first try. (If it does, than before, provided Python has been installed properly.)
skip to the next section.) Most likely you'll get this error message:
needed directory /usr/local/lib/python/lib not found
The reason is that Freeze require that some files that are normally
kept inside the Python build tree are installed, and it searches for
it in the default install location. (The default install prefix is
/usr/local; these particular files are installed at lib/python/lib
under the install prefix.)
The particular set of files needed is installed only if you run "make
libainstall" (note: "liba", not "lib") in the Python build tree (which
is the tree where you build Python -- often, but not necessarily, this
is also the Python source tree). If you have in fact done a "make
libainstall" but used a different prefix, all you need to do is pass
that same prefix to Freeze with the -p option:
python freeze.py -p your-prefix hello.py
If you haven't run "make libainstall" yet, you should do it now
(perhaps figuring out first *where* you want everything to be
installed).
How do I configure Freeze?
--------------------------
It's a good idea to change the first line marked with XXX in freeze.py
(an assignment to variable PACK) to point to the absolute pathname of
the directory where Freeze lives (Tools/freeze in the Python source
tree.) This makes it possible to call Freeze from other directories.
You can also edit the assignment to variable PREFIX (also marked with
XXX) -- this saves a lot of -p options.
How do I use Freeze with extensions modules?
--------------------------------------------
XXX to be written. (In short: pass -e extensionbuilddir.)
How do I use Freeze with dynamically loaded extension modules?
--------------------------------------------------------------
XXX to be written. (In short: pass -e modulebuilddir -- this even
works if you built the modules in Python's own Modules directory.)
What do I do next? What do I do next?
...@@ -134,37 +87,22 @@ What do I do next? ...@@ -134,37 +87,22 @@ What do I do next?
Freeze creates three files: frozen.c, config.c and Makefile. To Freeze creates three files: frozen.c, config.c and Makefile. To
produce the frozen version of your program, you can simply type produce the frozen version of your program, you can simply type
"make". This should produce a binary file. If the filename argument "make". This should produce a binary file. If the filename argument
to Freeze was "hello.py", the binary will be called "hello". On the to Freeze was "hello.py", the binary will be called "hello".
other hand, if the argument was "hello", the binary will be called
"hello.bin". If you passed any other filename, all bets are off. :-) Note: you can use the -o option to freeze to specify an alternative
In any case, the name of the file will be printed as the last message directory where these files are created. This makes it easier to
from Freeze. clean up after you've shipped the frozen binary.
Troubleshooting Troubleshooting
--------------- ---------------
If you have trouble using Freeze for a large program, it's probably If you have trouble using Freeze for a large program, it's probably
best to start playing with a really simple program first (like the best to start playing with a really simple program first (like the file
file hello.py). If you can't get that to work there's something hello.py). If you can't get that to work there's something
fundamentally wrong -- read the text above to find out how to install fundamentally wrong -- perhaps you haven't installed Python. To do a
relevant parts of Python properly and how to configure Freeze to find proper install, you should do "make install" in the Python root
them. directory.
A common problem is having installed an old version -- rerunning "make
libainstall" often clears up problems with missing modules or
libraries at link time.
What is nfreeze.py?
-------------------
The script nfreeze.py is an unsupported variant on freeze.py which
creates all files in a temporary directory and runs "make" there. It
has the advantage that it doesn't overwrite files in the current
directory, but the disadvantage is that it removes all files when it
is finished.
--Guido van Rossum, CWI, Amsterdam <mailto:Guido.van.Rossum@cwi.nl> --Guido van Rossum (home page: http://www.python.org/~guido/)
<http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>
#! /usr/local/bin/python #! /usr/local/bin/python
# "Freeze" a Python script into a binary. """Freeze a Python script into a binary.
# Usage: see variable usage_msg below (before the imports!)
# HINTS: usage: freeze [options...] script.py [module]...
# - Edit the lines marked XXX below to localize.
# - Make sure the #! line above matches the localizations.
# - You must have done "make inclinstall libainstall" in the Python
# build directory.
# - The script name should end in ".py".
# - The script should not use dynamically loaded modules
# (*.so on most systems).
Options:
# Usage message -p prefix: This is the prefix used when you ran ``name install''
in the Python build directory.
usage_msg = """
usage: freeze [-p prefix] [-P exec_prefix] [-e extension] script.py [module]...
-p prefix: This is the prefix used when you ran
'Make inclinstall libainstall' in the Python build directory.
(If you never ran this, freeze won't work.) (If you never ran this, freeze won't work.)
The default is /usr/local. The default is whatever sys.prefix evaluates to.
-P exec_prefix: Like -p but this is the 'exec_prefix', used to -P exec_prefix: Like -p but this is the 'exec_prefix', used to
install objects etc. The default is the value for -p. install objects etc. The default is whatever sys.exec_prefix
evaluates to, or the -p argument if given.
-e extension: A directory containing additional .o files that -e extension: A directory containing additional .o files that
may be used to resolve modules. This directory may be used to resolve modules. This directory
should also have a Setup file describing the .o files. should also have a Setup file describing the .o files.
More than one -e option may be given. More than one -e option may be given.
-o dir: Directory where the output files are created; default '.'.
Arguments:
script.py: The Python script to be executed by the resulting binary. script.py: The Python script to be executed by the resulting binary.
It *must* end with a .py suffix! It *must* end with a .py suffix!
...@@ -43,22 +36,11 @@ NOTES: ...@@ -43,22 +36,11 @@ NOTES:
In order to use freeze successfully, you must have built Python and In order to use freeze successfully, you must have built Python and
installed it ("make install"). installed it ("make install").
The -p and -P options passed into the freeze script must correspond to The script should not use modules provided only as shared libraries;
the --prefix and --exec-prefix options passed into Python's configure if it does, the resulting binary is not self-contained.
script.
""" """
# XXX Change the following line to point to your Tools/freeze directory
PACK = '/home/guido/python/src/Tools/freeze'
# XXX Change the following line to point to your install prefix
PREFIX = '/usr/local'
# XXX Change the following line to point to your install exec_prefix
EXEC_PREFIX = None # If None, use -p option for default
# Import standard modules # Import standard modules
import cmp import cmp
...@@ -69,16 +51,6 @@ import sys ...@@ -69,16 +51,6 @@ import sys
import addpack import addpack
# Set the directory to look for the freeze-private modules
dir = os.path.dirname(sys.argv[0])
if dir:
pack = dir
else:
pack = PACK
addpack.addpack(pack)
# Import the freeze-private modules # Import the freeze-private modules
import checkextensions import checkextensions
...@@ -93,10 +65,11 @@ import parsesetup ...@@ -93,10 +65,11 @@ import parsesetup
def main(): def main():
# overridable context # overridable context
prefix = PREFIX # settable with -p option prefix = None # settable with -p option
exec_prefix = None # settable with -P option exec_prefix = None # settable with -P option
extensions = [] extensions = []
path = sys.path path = sys.path
odir = ''
# output files # output files
frozen_c = 'frozen.c' frozen_c = 'frozen.c'
...@@ -106,7 +79,7 @@ def main(): ...@@ -106,7 +79,7 @@ def main():
# parse command line # parse command line
try: try:
opts, args = getopt.getopt(sys.argv[1:], 'e:p:P:') opts, args = getopt.getopt(sys.argv[1:], 'e:o:p:P:')
except getopt.error, msg: except getopt.error, msg:
usage('getopt error: ' + str(msg)) usage('getopt error: ' + str(msg))
...@@ -114,20 +87,26 @@ def main(): ...@@ -114,20 +87,26 @@ def main():
for o, a in opts: for o, a in opts:
if o == '-e': if o == '-e':
extensions.append(a) extensions.append(a)
if o == '-o':
odir = a
if o == '-p': if o == '-p':
prefix = a prefix = a
if o == '-P': if o == '-P':
exec_prefix = a exec_prefix = a
# default exec_prefix # default prefix and exec_prefix
if exec_prefix is None: if not exec_prefix:
exec_prefix = EXEC_PREFIX if prefix:
if exec_prefix is None:
exec_prefix = prefix exec_prefix = prefix
else:
exec_prefix = sys.exec_prefix
if not prefix:
prefix = sys.prefix
# locations derived from options # locations derived from options
binlib = os.path.join(exec_prefix, 'lib/python1.4/config') version = sys.version[:3]
incldir = os.path.join(prefix, 'include/python1.4') binlib = os.path.join(exec_prefix, 'lib/python%s/config' % version)
incldir = os.path.join(prefix, 'include/python%s' % version)
config_c_in = os.path.join(binlib, 'config.c.in') config_c_in = os.path.join(binlib, 'config.c.in')
frozenmain_c = os.path.join(binlib, 'frozenmain.c') frozenmain_c = os.path.join(binlib, 'frozenmain.c')
getpath_c = os.path.join(binlib, 'getpath.c') getpath_c = os.path.join(binlib, 'getpath.c')
...@@ -181,6 +160,22 @@ def main(): ...@@ -181,6 +160,22 @@ def main():
target = base target = base
else: else:
target = base + '.bin' target = base + '.bin'
# handle -o option
base_frozen_c = frozen_c
base_config_c = config_c
base_target = target
if odir and not os.path.isdir(odir):
try:
os.mkdir(odir)
print "Created output directory", odir
except os.error, msg:
usage('%s: mkdir failed (%s)' % (odir, str(msg)))
if odir:
frozen_c = os.path.join(odir, frozen_c)
config_c = os.path.join(odir, config_c)
target = os.path.join(odir, target)
makefile = os.path.join(odir,makefile)
# Actual work starts here... # Actual work starts here...
...@@ -260,7 +255,7 @@ def main(): ...@@ -260,7 +255,7 @@ def main():
somevars[key] = makevars[key] somevars[key] = makevars[key]
somevars['CFLAGS'] = string.join(cflags) # override somevars['CFLAGS'] = string.join(cflags) # override
files = ['$(OPT)', '$(LDFLAGS)', config_c, frozen_c] + \ files = ['$(OPT)', '$(LDFLAGS)', base_config_c, base_frozen_c] + \
supp_sources + addfiles + libs + \ supp_sources + addfiles + libs + \
['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)'] ['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)']
...@@ -271,7 +266,7 @@ def main(): ...@@ -271,7 +266,7 @@ def main():
backup = None backup = None
outfp = open(makefile, 'w') outfp = open(makefile, 'w')
try: try:
makemakefile.makemakefile(outfp, somevars, files, target) makemakefile.makemakefile(outfp, somevars, files, base_target)
finally: finally:
outfp.close() outfp.close()
if backup: if backup:
...@@ -284,13 +279,17 @@ def main(): ...@@ -284,13 +279,17 @@ def main():
# Done! # Done!
print 'Now run make to build the target:', target if odir:
print 'Now run make in', odir,
print 'to build the target:', base_target
else:
print 'Now run make to build the target:', base_target
# Print usage message and exit # Print usage message and exit
def usage(msg = None): def usage(msg = None):
sys.stderr.write(usage_msg) sys.stderr.write(__doc__)
# Put the error last since the usage message scrolls off the screen # Put the error last since the usage message scrolls off the screen
if msg: if msg:
sys.stderr.write('\nError: ' + str(msg) + '\n') sys.stderr.write('\nError: ' + str(msg) + '\n')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment