diff --git a/Sconstruct b/Sconstruct index 3070a03..71a27d4 100644 --- a/Sconstruct +++ b/Sconstruct @@ -33,10 +33,11 @@ if platform.name == "win32": for mode in "cons", "win": env = base_env.Copy() - # The DLL runtime must be the same of that used by the python DLL. - # I cannot think of a way to guess it from here, so let's assume - # the user has a non-debug build of Python in his system. - env.Append(CCFLAGS = ["/MD"]) + # The bootloader is built as a static executable. We want it + # to be self-contained. Extra care was put in writing it so + # that it does not share objects/memory with python.dll (which + # it loads). + env.Append(CCFLAGS = ["/ML"]) if flavour == "debug": # No optimizations diff --git a/doc/CHANGES.txt b/doc/CHANGES.txt index cc5be67..140864a 100644 --- a/doc/CHANGES.txt +++ b/doc/CHANGES.txt @@ -3,12 +3,15 @@ Current changes since PyInstaller 1.0 ------------------------------------- - + Fix problem with incorrect python path detection. Now using distutils. + + Fix problem with incorrect python path detection. Now using helpers from + distutils. + Fix problem with rare encodings introduced in newer Python versions: now all the encodings are automatically found and included, so this problem should be gone forever. + Add import hook for dnspython (tested with 1.3.4) - + + (Windows) Make single-file packages not depend on MSVCRT71.DLL anymore, + even under Python 2.4. You can eventually ship your programs really as + single-file executables, even when using the newest Python version! PyInstaller 1.0 (with respect to McMillan's Python Installer 5b5): diff --git a/doc/Manual.html b/doc/Manual.html index 9b63f7b..5762266 100644 --- a/doc/Manual.html +++ b/doc/Manual.html @@ -21,7 +21,7 @@
Currently, there is an issue when using --onefile with Python 2.4: the -resulting executable will depend on MSVCR71.DLL. This is a standard -Microsoft library which was not present on older Windows (like Win9x), so -you are forced to ship it with your application if you need compatibility -with those operating systems. We plan to fix this issue in a future version -of PyInstaller (consult our Roadmap for more information).
- -python ArchiveViewer.py <archivefile>@@ -445,10 +434,10 @@ given, extracted to stdout.
python bindepend.py <executable_or_dynamic_library>@@ -459,7 +448,7 @@ follow the chain of dependencies of binary extensions and make sure that all of them get included in the final package.
python GrabVersion.py <executable_with_version_resource>@@ -478,20 +467,20 @@ how the data is displayed and the structure of the resource itself. So the easiest thing to do is find an executable that displays the kind of information you want, grab it's resource and edit it. Certainly easier than the Version resource wizard in VC++. - +
You can interactively track down dependencies, including getting cross-references by using mf.py, documented in section mf.py: A modulefinder Replacement
- +Spec files are in Python syntax. They are evaluated by Build.py. A simplistic spec file might look like this:
@@ -524,10 +513,10 @@ and binaries. A EXE is built from the PYZ, the scripts and, in the case of a single-file deployment, the binaries. In a single-directory deployment, a directory is built containing a slim executable and the binaries. - +
Before you can do much with a spec file, you need to understand the TOC (Table Of Contents) class.
A TOC appears to be a list of tuples of the form (name, path, typecode). @@ -672,12 +661,12 @@ the run executables understand are:
becomes possible to factor out common modules, and deploy a project containing multiple executables with minimal redundancy. You'll need some top level code in each executable to mount the common PYZ. - +Analysis(scripts, pathex=None, hookspath=None, excludes=None)@@ -704,10 +693,10 @@ prepended. filtered. On Windows, a long list of MS dlls are excluded. On Linux/Unix, any shared lib in /lib or /usr/lib is excluded. - +
PYZ(toc, name=None, level=9)@@ -719,10 +708,10 @@ PYZ(toc, name=None, level=9)
Generally, you will not need to create your own PKGs, as the EXE will do it for you. This is one way to include read-only data in a single-file deployment, however. A single-file deployment including TK support will use this technique.
@@ -742,10 +731,10 @@ uses sensible values. If zlib is not available, no compression is used.EXE(*args, **kws)@@ -782,19 +771,19 @@ and one for non-ELF platforms (where the run executable is simply renamed, and expects a exename.pkg in the same directory). Which class becomes available as EXE is determined by a flag in config.dat. This flag is set to non-ELF when using Make.py -n. - +
On Windows, this provides support for doing in-process COM servers. It is not generalized. However, embedders can follow the same model to build a special purpose DLL so the Python support in their app is hidden. You will need to write your own dll, but thanks to Allan Green for refactoring the C code and making that a managable task.
- +When an Analysis step runs, it produces a warnings file (named warnproject.txt) in the spec file's directory. Generally, most of these warnings are harmless. For example, os.py (which is cross-platform) works by figuring out what @@ -869,18 +858,18 @@ Both exec and
Any problem detected here can be handled by hooking the analysis of the module. See Listing Hidden Imports below for how to do it.
- +Setting debug=1 on an EXE will cause the executable to put out progress messages (for console apps, these go to stdout; for Windows apps, these show as MessageBoxes). This can be useful if you are doing complex packaging, or your app doesn't seem to be starting, or just to learn how the runtime works.
- +You can also pass a -v (verbose imports) flag to the embedded Python. This can be extremely useful. I usually try it even on apparently working apps, just to make sure that I'm always getting my copies of the modules and no import has @@ -896,13 +885,13 @@ EXE(..., anal.scripts + [('v', '', 'OPTION')], ...)
These messages will always go to stdout, so you won't see them on Windows if console=0.
- +When the analysis phase cannot find needed modules, it may be that the code is manipulating sys.path. The easiest thing to do in this case is tell Analysis about the new directory through the second arg to the constructor:
@@ -919,10 +908,10 @@ anal = Analysis(['somedir/myscript.py'], Makespec.py --paths=path/to/thisdir;path/to/thatdir ...(on *nix, use : as the path separator).
- +Hidden imports are fairly common. These can occur when the code is using __import__ (or, perhaps exec or eval), in which case you will see a warning in the warnproject.txt file. They can also occur when an extension module uses the @@ -954,10 +943,10 @@ explicitly imported module1Hooks section).
If you successfully hook a publicly distributed module in this way, please send us the hook so we can make it available to others.
- +Python allows a package to extend the search path used to find modules and sub-packages through the __path__ mechanism. Normally, a package's __path__ has only one entry - the directory in which the __init__.py was found. But @@ -978,10 +967,10 @@ for an example.
and only the analysis. That is, at runtime win32com.shell is resolved the same way as win32com.anythingelse, and win32com.__path__ knows nothing of ../win32comext.Once in awhile, that's not enough.
- +More bizarre situations can be accomodated with runtime hooks. These are small scripts that manipulate the environment before your main script runs, effectively providing additional top-level code to your script.
@@ -1003,10 +992,10 @@ my persistence scheme). free to do almost anything. One provided hook sets things up so that win32com can generate modules at runtime (to disk), and the generated modules can be found in the win32com package. - +In most sophisticated apps, it becomes necessary to figure out (at runtime) whether you're running "live" or "frozen". For example, you might have a configuration file that (running "live") you locate based on a module's @@ -1016,10 +1005,10 @@ probably want to look for it based on ).
For really advanced users, you can access the iu.ImportManager as sys.importManager. See iu.py for how you might make use of this fact.
- +In a --onedir distribution, this is easy: pass a list of your data files (in TOC format) to the COLLECT, and they will show up in the distribution directory tree. The name in the (name, path, 'DATA') tuple can be a relative @@ -1044,29 +1033,29 @@ data = this.extract('mystuff')[1]
to get the contents as a binary string. See support/unpackTK.py for an advanced example (the TCL and TK lib files are in a PKG which is opened in place, and then extracted to the filesystem).
- +Pmw comes with a script named bundlepmw in the bin directory. If you follow the instructions in that script, you'll end up with a module named Pmw.py. Ensure that Builder finds that module and not the development package.
- +If you're using popen on Windows and want the code to work on Win9x, you'll need to distribute win9xpopen.exe with your app. On older Pythons with Win32all, this would apply to Win32pipe and win32popenWin9x.exe. (On yet older Pythons, no form of popen worked on Win9x).
- +The ELF executable format (Windows, Linux and some others) allows arbitrary data to be concatenated to the end of the executable without disturbing its functionality. For this reason, a CArchive's Table of Contents is at the end of @@ -1075,9 +1064,9 @@ end and 'open' the CArchiveOn other platforms, the archive and the executable are separate, but the archive is named executable.pkg, and expected to be in the same directory. Other than that, the process is the same.
- +In a single directory deployment (--onedir, which is the default), all of the binaries are already in the file system. In that case, the embedding app:
There are a couple situations which require two passes:
In both cases, while one PyInstaller download can be used with any Python version, you need to have separate installations for each Python version.
- +You know what an archive is: a .tar file, a .jar file, a .zip file. Two kinds of archives are used here. One is equivalent to a Java .jar file - it allows Python modules to be stored efficiently and, (with some import hooks) imported @@ -1145,10 +1134,10 @@ directly. This is a ZlibArchive blobs of data. It gets its name from the fact that it can be manipulated easily from C, as well as from Python. Both of these derive from a common base class, making it fairly easy to create new kinds of archives.
- +A ZlibArchive contains compressed .pyc (or .pyo) files. The Table of Contents is a marshalled dictionary, with the key (the module's name as given in an import statement) associated with a seek position and length. Because it is @@ -1163,10 +1152,10 @@ entry was created from (the __fil compiled). On a user's box with no source installed, this is not terribly useful, but if they send you the traceback, at least you can make sense of it.

A CArchive contains whatever you want to stuff into it. It's very much like a .zip file. They are easy to create in Python and unpack from C code. CArchives can be appended to other files (like ELF and COFF executables, for example). @@ -1182,11 +1171,11 @@ file. The name is null terminated. Compression is optional by member.
CArchive as a .zip file, you don't need to worry about this. The type codes are used by the self-extracting executables.
PyInstaller is mainly distributed under the GPL License but it has an exception such that you can use it to compile commercial products.
@@ -1205,10 +1194,10 @@ words, any modifications to will have to be distributed under GPL.For updated information or clarification see our FAQ at PyInstaller home page: http://pyinstaller.hpcf.upr.edu
- +Module mf is modelled after iu.
It also uses ImportDirectors and Owners to partition the import name space. Except for the fact that these return Module instances instead of real module objects, they are identical.
Instead of an ImportManager, mf has an ImportTracker managing things.
- +ImportTracker can be called in two ways: analyze_one(name, importername=None) or analyze_r(name, importername=None). The second method does what modulefinder does - it recursively finds all the module names that importing name would @@ -1232,10 +1221,10 @@ cause to appear in sys.modules - +
When a name is imported, there are structural and dynamic effects. The dynamic effects are due to the execution of the top-level code in the module (or modules) that get imported. The structural effects have to do with whether the @@ -1247,10 +1236,10 @@ dynamic effects. For example, ana or ["A.B", "A.B.C"] depending on whether the import turns out to be relative or absolute. In addition, ImportTracker's modules dict will have Module instances for them.
- +There are Module subclasses for builtins, extensions, packages and (normal) modules. Besides the normal module object attributes, they have an attribute imports. For packages and normal modules, imports is a list populated by @@ -1262,10 +1251,10 @@ it's top-level code executed. That top-level code can do various things so that when the import of B.C finally occurs, something completely different happens (from what a structural analysis would predict). But mf can handle this through it's hooks mechanism.
- +Like modulefinder, mf scans the byte code of a module, looking for imports. In addition, mf will pick out a module's __all__ attribute, if it is built as a list of constant names. This means that if a package declares an __all__ list @@ -1276,10 +1265,10 @@ and can issue warnings when they're found.
import. It recognizes when imports are found at the top-level, and when they are found inside definitions (deferred imports). Within that, it also tracks whether the import is inside a condition (conditional imports). - +In modulefinder, scanning the code takes the place of executing the code object. mf goes further and allows a module to be hooked (after it has been scanned, but before analyze_one is done with it). A hook is a module named @@ -1306,10 +1295,10 @@ trace through PyXML-using code, and I can't believe that it's any easier for the poor programmer using that package). The hook(mod) (if it exists) is called before looking at the others - that way it can, for example, test sys.version and adjust what's in hiddenimports.
- +ImportTracker has a getwarnings() method that returns all the warnings accumulated by the instance, and by the Module instances in its modules dict. Generally, it is ImportTracker who will accumulate the warnings generated @@ -1317,19 +1306,19 @@ during the structural phase, and during the code scan.
Note that by using a hook module, you can silence some particularly tiresome warnings, but not all of them.
- +Once a full analysis (that is, an analyze_r call) has been done, you can get a cross reference by using getxref(). This returns a list of tuples. Each tuple is (modulename, importers), where importers is a list of the (fully qualified) names of the modules importing modulename. Both the returned list and the importers list are sorted.
- +Module iu grows out of the pioneering work that Greg Stein did with imputil (actually, it includes some verbatim imputil code, but since Greg didn't copyright it, we won't mention it). Both modules can take over Python's @@ -1390,9 +1379,9 @@ builtin import and ease writing of at least certain kinds of import hooks.
There is an ImportManager which provides the replacement for builtin import and hides all the semantic complexities of a Python import request from it's delegates.
- +ImportManager formalizes the concept of a metapath. This concept implicitly exists in native Python in that builtins and frozen modules are searched before sys.path, (on Windows there's also a search of the registry while on @@ -1406,18 +1395,18 @@ metapath until one succeeds.
It's up to the ImportManager to decide if an import is relative or absolute; to see if the module has already been imported; to keep sys.modules up to date; to handle the fromlist and return the correct module object. - +An ImportDirector just needs to respond to getmod(name) by returning a module object or None. As you will see, an ImportDirector can consider name to be atomic - it has no need to examine name to see if it is dotted.
To see how this works, we need to examine the PathImportDirector.
- +The PathImportDirector subclass manages a list of names - most notably, sys.path. To do so, it maintains a shadowpath - a dictionary mapping the names on its pathlist (eg, sys.path) to their associated Owners. (It could do this @@ -1425,10 +1414,10 @@ directly, but the assumption that sys.path is occupied solely by strings seems ineradicable.) Owners of the appropriate kind are created as needed (if all your imports are satisfied by the first two elements of sys.path, the PathImportDirector's shadowpath will only have two entries).
- +An Owner is much like an ImportDirector but manages a much more concrete piece of turf. For example, a DirOwner manages one directory. Since there are no other officially recognized filesystem-like namespaces for importing, that's @@ -1443,10 +1432,10 @@ consisting of Owners. namespace.
The rest of the import namespace is covered by treelets, each rooted in a package module (an __init__.py).
- +To make this work, Owners need to recognize when a module is a package. For a DirOwner, this means that name is a subdirectory which contains an __init__.py. The __init__ module is loaded and its __path__ is initialized with the @@ -1461,10 +1450,10 @@ module name, not the package name or the fully qualified name. And that's exactly what it gets. (In a flat namespace - like most archives - it is perfectly easy to route the request back up the package tree to the archive Owner, qualifying the name at each step.)
- +Let's say we want to import from zip files. So, we subclass Owner. The __init__ method should take a filename, and raise a ValueError if the file is not an acceptable .zip file, (when a new name is encountered on sys.path or a @@ -1476,28 +1465,28 @@ lines of code all told for my own archive format, including initializing a pack age with it's __subimporter__).
Once the new Owner class is registered with iu, you can put a zip file on sys.path. A package could even put a zip file on its __path__.
- +This code has been tested with the PyXML, mxBase and Win32 packages, covering over a dozen import hacks from manipulations of __path__ to replacing a module in sys.modules with a different one. Emulation of Python's native import is nearly exact, including the names recorded in sys.modules and module attributes (packages imported through iu have an extra attribute - __importsub__).
- +In most cases, iu is slower than builtin import (by 15 to 20%) but faster than imputil (by 15 to 20%). By inserting archives at the front of sys.path containing the standard lib and the package being tested, this can be reduced to 5 to 10% slower (or, on my 1.52 box, 10% faster!) than builtin import. A bit more can be shaved off by manipulating the ImportManager's metapath.
- +This module makes no attempt to facilitate policy import hacks. It is easy to implement certain kinds of policies within a particular domain, but fundamentally iu works by dividing up the import namespace into independent @@ -1514,7 +1503,7 @@ syntax for those should be, but _ easy to implement.