If you distribute WPY applications, it may be more convenient to put
the required Python *.py libraries and application files into a DLL
rather than try to establish a Python library directory on the customer's
computer.  That way, you just put the DLL in the directory with your
executable rather than trying to get PYTHONPATH pointing to the
Python directory.

The standard Python "freeze" tool will create a C-language
file which consists of the Python *.pyc files, and this file can be
compiled to a DLL which can be shipped with your application.  See
Tools/freeze/README in the Python root directory.

To create the C file, you need a list of all the Python modules required
by your application, both Python libraries, your own Python programs and
modules, and WPY Python files.  These are given on the command line to
the makefreeze.py program:
  pyth_nt makefreeze.py mymod1.py string.pyc ...
The C-language is printed on stdout.  If you name a *.py file, it will
be compiled, but *.pyc files are not compiled so make sure the *.pyc
files are up to date.

If there is a module named "__main__" in your DLL, it will be started
as the main program.  Rename your main Python program as "__main__" if
you want that to happen.  Here is a Unix-style shell script to create the
C-language source for a list of Python files:

PYLIB='K:/python/lib'
OURLIB='K:/python'
FRZ='N:/python/python/Tools/freeze/makefreeze.py'
echo Making Python file dll ...
cp $OURLIB/my_main.py ./__main__.py
pyth_nt $FRZ __main__.py \
    $OURLIB/mymod1.py $OURLIB/mymod2.py $OURLIB/mymod3.py \
    $OURLIB/wpy.py $OURLIB/wpycon.py \
    $PYLIB/ntpath.pyc $PYLIB/os.pyc $PYLIB/regex_syntax.pyc $PYLIB/regsub.pyc \
    $PYLIB/stat.pyc $PYLIB/string.pyc $PYLIB/types.pyc $PYLIB/UserDict.pyc \
    $PYLIB/os.pyc $PYLIB/regsub.pyc \
    > my_dll.c

Next you need to compile my_dll.c into a DLL.  This can be done with any
C compiler which can produce a DLL.  Here is a script for VC++ 4.2:

MSDevDir=C:/MSDEV
VcOsDir=WINNT
PATH="$MSDevDir/BIN;$MSDevDir/BIN/$VcOsDir;"$PATH
INCLUDE="$MSDevDir/INCLUDE;$MSDevDir/MFC/INCLUDE"
LIB="$MSDevDir/LIB;$MSDevDir/MFC/LIB"
export INCLUDE LIB

rc my_main.rc
cl /nologo /W3 /GX /I "N:/python/python/PC" /I "N:/python/python/Include" \
  /D "WIN32" /D "_WINDOWS" /D "HAVE_CONFIG_H" /D "USE_DL_EXPORT" /YX \
  my_dll.c my_main.res \
  /link /subsystem:windows /dll /machine:I386 /OUT:my_main.dll

The file my_main.rc is optional, but provides a way to put resources
such as a different program icon into your DLL.  These will be used
instead of the resources in wpy_nt.exe provided they are a complete
set of resources.  Copy wpy/wpython.rc and make changes.

It is important that the DLL has the same name as your executable
wpy_nt.exe because wpy_nt.exe looks for it based on its own name.  So
if you want your program to be called "my_main.exe", then make your
DLL name "my_main.dll" and copy wpy_nt.exe to "my_main.exe".  The
DLL search path includes both PATH and the directory of the executable,
so I suggest you put the DLL with the executable on your customer's
system.