-

Where does your built version of panda look for the python executable? Is that where you are running your setup.py from? What I mean is, if you have two versions of python 2.4, one might not know where to look for the direct tree where the other one would. So if you haven’t yet, try running ppython setup.py instead of python setup.py

I’ve never used py2exe, so I can’t help much there.

However, I can say this: the pandac module is implemented quite differently under 1.1 than under 1.0. If you figure out how to solve it under 1.0, you’ll probably have to use a different solution under 1.1. Under 1.1, here’s how it works:

Each DLL such as “libpandaexpress” contains a bunch of python classes and methods. These are self-contained in the sense that you can import them directly into python without any sort of intervening wrapper and it works fine. For example, you can say:

from libpandaexpress import *

and you’ll get a bunch of the panda classes. In fact, I think their intent is to gradually move toward a system where you just import classes directly from the DLLs in the way I just showed.

However, in a few unusual cases, the disney guys are mixing C++ and python classes like this:

  • Define the class in C++
  • Write most of the methods in C++
  • Write a few “extra methods” in python.

If you just import the classes directly from the DLLs, you’ll get the C++ class definition and the C++ methods, but you’ll miss out on the “extra methods.” That’s what the “pandac” directory is for.

The pandac directory contains small files that look like this:

from libpandaexpress import *
define extra method 1
insert extra method 1 into such-and-such class
define extra method 2
insert extra method 2 into such-and-such class
etc, etc.

So basically, 90 percent of the work consists of just importing the class and its methods from the DLLs, and the remaining 10 percent is attaching the python methods to the C++ classes.

I don’t know if that will help you sort this out, I hope it does, though.

I haven’t checked this method but maybe it works:

*)Use packpanda https://discourse.panda3d.org/viewtopic.php?t=884
*)Install it on your computer
*)Start py2exe for this installed game

I have recently tried to make some progress on this, but have only narrowed the problem…

I have installed py2exe into a registered version of python and copied the files over to the site-packages directory in panda3d’s python (although IPKnightly’s method above would have worked just as well). I then created a setup.py the same as IPKnightly with all of the direct packages listed, and tried testing it on a simple one-file panda application. I built the file using ppython and these were the warnings:

The first run of the executable, I got this error:

I remembered that PandaModules looks for the .pyz file in the same directory its located, so I copied PandaModules.pyz into the same directory that the executable was. I figured this was ok since PandaModules.pyz is just a bunch of zipped up python files for faster loading (maybe I am wrong about that).

After a couple more runs I had errors about missing .dll files. These were:

and:

I copied those .dll files to the same directory as the executable as well. I really just wanted to see how far I could get. The last error I got was:

I am assuming this was because I was copying dlls into places they should not have been.

When I moved the enitre directory containing the executable outside of the folder I built it in, I finally got IPKnightly’s error of

I figured out that this has nothing to do with pandac, but rather the fact that the direct/init.py file was not trivial. Here is the code from that file:

import os,sys
srcdir1 = os.path.join(__path__[0], 'src')
srcdir2 = os.path.join(__path__[0], '..', '..', 'direct', 'src')
if    (os.path.isdir(srcdir1)): __path__[0] = srcdir1
elif  (os.path.isdir(srcdir2)): __path__[0] = srcdir2
else: sys.exit("Cannot find the 'direct' tree")

Basically it looks for a path either with ‘src’ appended to the path name, or two levels up from the current directory and then ‘direct/src’.

Before I had moved my executable file, it was two directories deep from the direct folder in panda, which inadvertently resolved that issue, but reappeared when I moved the location away from that particular directory structure.

So the real question is what is the best way to fix the non-trivial init problem? When byte-compiled, the init.py file needs to be able to look for the direct packages without trying to mangle the path. At leat thats my best guess. The quick solution would be to include the direct package two directories above the distribution executable, but that is really just a hack and I would like to find the ‘correct’ solution.

Any help would be greatly appreciated.

Well, the fancy init.py file is really itself just a hack to allow people to run files out of direct/src/whatever, instead of direct/whatever, which is where the installed files should end up when they are published. I would just copy the Python files into the appropriate places in the publish tree, omitting the intervening “src” directory, and omitting the init.py files.

But isn’t this whole problem already solved with Josh’s packpanda tool?

David

I am using version 1.0.5 which doesn’t have packpanda. I did install version 1.1.0 to try it out on the same file , but got an error:

I figured trying to fix packpanda (the fixes found here and here), and then debug it to build it into version 1.0.5 would be a lot more work than I could handle right now. I was hoping that getting py2exe to work might be easier.

I’ll try to resturcture the direct packages and see how it goes. Any ideas on why there are a few select pandac modules missing? I would think it would be all or nothing. Does moving the PandaModules.pyz file fix that problem?

You mean the dll’s? These have to be loaded by the system, so they have to be found somewhere on sys.path, regardless of where PandaModules.pyz is found. As to why you only got an error from two of them, well, those are the first two loaded; I bet you will get the same error from the rest of them when you get further.

David

I thought the packpanda util just made an installer for the program, but doesnt freeze the actual program into an exe like py2exe ?

Thanks David, I appreciate all of the help.

I was actually referring to the initial warnings from py2exe, but knowing that all of the dll files will be missing will help. I’ll try to find a solution.

Also, as far as I know, packpanda is an installer for .py or .pyc files that also installs panda (or some minimal version of it). It says packpanda was used to create the Airblade.exe found in the software downloads, so that might give an example of a finished packpanda distribution.

In that case, I’d recomend sticking with a combination of ino setup and py2exe. I already compiled a panda3d program with it with panda 1.0.5 and 1.1.0. Using 1.1.0 its much easier, but sadly, I already deleted the test compiles I did…

I just remember that the direct package is abit of a bastard in this, I think I had a second copy in my libarary.zip, but then with all modules in the direct dir, not source. And yes, you need to copy most .dll files from your bin dir to the dist dir.

good luck, if you want me to redo what I did, I’ll have a look.

Edit:

Oh and yeah, I seem to remember that you needed to edit some of the modules, they’re just a few from the pandac bundle though

Thanks Yellow

I restructured the direct tree and unzipped the PandaModules.pyz file using genpycode. This created all of the pandac files which allowed py2exe to search for the dll files to copy over. So that was taken care of. It also deleted the PandaModules.py file as well, which a lot of files import from. So I created my own PandaModules.py file like this:

#PandaModules.py
from libpandaModules import *

import ConfigConfigureGetConfigConfigShowbase
import CIntervalManager
import CInterval
import LinearEulerIntegrator
import CLerpAnimEffectInterval


ConfigConfigureGetConfigConfigShowbase = ConfigConfigureGetConfigConfigShowbase.ConfigConfigureGetConfigConfigShowbase
CIntervalManager = CIntervalManager.CIntervalManager
CInterval = CInterval.CInterval
LinearEulerIntegrator = LinearEulerIntegrator.LinearEulerIntegrator
CLerpAnimEffectInterval = CLerpAnimEffectInterval.CLerpAnimEffectInterval

I created the extra imports from error messages given by running through it a couple times. I would think there is a file similar to libpandaModules that has these imports, and probably others that I am missing. Anyone know which?

The most recent error I am recieving is:

The corresponding code in ShowBase:

        # Lerp stuff needs this event, and it must be generated in
        # C++, not in Python.
        throwNewFrame()

Where is throwNewFrame() located? I am guessing It would have been imported into PandaModules at some point, which I would have missed.

Thanks again

Right, throwNewFrame() is a C++ function (defined in showBase.cxx, and called throw_new_frame() there) that should have been imported when you imported the contents of PandaModules. Maybe there’s something missing in the PandaModules.py that you created.

You could try running genpycode -n. This should generate a PandaModules.py and a long list of separate *.py files, instead of zipping them all up into PandaModules.pyz.

David

Many, many thanks. That was just what I needed. It all works now.

Can you post that file you have used for making the exe.
Or can you write a tutorial in the manual for making an exe with py2exe.

Thanks Martin

The setup.py file I use is outdated. I am using py2exe version 0.4.1 so that it is compatible with python 2.2 and Panda1.0.5. If you are using Panda1.1.0, the file will look different, namely the ‘scripts’ argument will be a ‘console’ or ‘windows’ argument. anyway, here it is.

#setup.py
from distutils.core import setup
from distutils.core import Extension

import py2exe

setup(name = "pandaRun",
      scripts = ["pandaAnim.py"],
      packages = ['direct',
                  'direct.directbase',
                  'direct.showbase',
                  'direct.interval',
                  'direct.actor',
                  'direct.gui',
                  'direct.showbase',
                  'direct.task',
                  'direct.controls',
                  'direct.directnotify',
                  'direct.directtools',
                  'direct.directutil',
                  'direct.fsm',
                  'direct.ffi',
                  'direct.particles',
                  'direct.tkpanels',
                  'direct.tkwidgets',
                  'direct.cluster',
                  'direct.directdevices',
                  'direct.distributed',
                  'pandac'
                 ],
        package_dir = {'direct' : 'C:\\Panda3D-1.0.5\\direct',
        'direct.directbase' : 'C:\\Panda3D-1.0.5\\direct\\directbase',
        'direct.showbase' : 'C:\\Panda3D-1.0.5\\direct\\showbase',
        'direct.interval' : 'C:\\Panda3D-1.0.5\\direct\\interval',
        'direct.actor' : 'C:\\Panda3D-1.0.5\\direct\\actor',
        'direct.gui' : 'C:\\Panda3D-1.0.5\\direct\\gui',
        'direct.showbase' : 'C:\\Panda3D-1.0.5\\direct\\showbase',
        'direct.task' : 'C:\\Panda3D-1.0.5\\direct\\task',
        'direct.controls' : 'C:\\Panda3D-1.0.5\\direct\\controls',
        'direct.directnotify' :'C:\\Panda3D-1.0.5\\direct\\directnotify',
        'direct.directtools' : 'C:\\Panda3D-1.0.5\\direct\\directtools',
        'direct.directutil' : 'C:\\Panda3D-1.0.5\\direct\\directutil',
        'direct.fsm' : 'C:\\Panda3D-1.0.5\\direct\\fsm',
        'direct.ffi' : 'C:\\Panda3D-1.0.5\\direct\\ffi',
        'direct.particles' : 'C:\\Panda3D-1.0.5\\direct\\particles',
        'direct.tkpanels' : 'C:\\Panda3D-1.0.5\\direct\\tkpanels',
        'direct.tkwidgets' : 'C:\\Panda3D-1.0.5\\direct\\tkwidgets',
        'direct.cluster' : 'C:\\Panda3D-1.0.5\\direct\\cluster',
        'direct.directdevices' : 'C:\\Panda3D-1.0.5\\direct\\directdevices',
        'direct.distributed' : 'C:\\Panda3D-1.0.5\\direct\\distributed',
        'pandac' : 'C:\\Panda3D-1.0.5\\pandac'
        } 
      
)

I’ll see if I have time this weekend to test out 1.1.0 with the newest version of py2exe.

Thanks a lot

Any progress with that? I’m trying to build an .exe with Panda 1.1.0, Python 2.4, and the latest py2exe, without much luck.

I’ve created a setup.py file explicitly listing all the panda modules, and I’m getting the following error when I try to run the .exe:

It appears that it doesn’t like the line:

Of course, it’s only getting there because it’s not finding the direct module files. I’ve been over this thread trying to figure out how to get it to work without much luck. I tried moving the direct modules from direct/src directory to direct and modified the init file, which got me a different error: