[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Pygame, PyOpenGl, and py2exe, OH MY!



What you are lacking is actually part of Python itself (or the stdlib):

Python 2.6.4 (r264:75821M, Oct 27 2009, 19:48:32) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.pythonapi.PyString_AsString
<_FuncPtr object at 0x3697b0>

It might be that py2exe is unable to DWIM that you are using the ctypes.pythonapi subpackage.

Perhaps you need to add an 'import ctypes.pythonapi' to one of your modules (like the main one) or otherwise explicitly tell py2exe to include it?

-Casey

On Apr 22, 2010, at 8:08 PM, Keith Nemitz wrote:

> 
> I spent the day in py2exe hell. After grinding through six separate problems, now I'm stuck. Has anyone got this combo to work? I'm using Python 2.6 and Pygame 1.9.x and pyOpenGl 3.0.x and the latest py2exe. When I run the resulting exe, I get the following runtime error:
> 
> Traceback (most recent call last):
>  File "main.py", line 29, in <module>
>  File "zipextimporter.pyo", line 82, in load_module
>  File "pygl2d\__init__.pyo", line 5, in <module>
>  File "zipextimporter.pyo", line 82, in load_module
>  File "pygl2d\window.pyo", line 3, in <module>
>  File ".\OpenGL\GL\__init__.py", line 2, in <module>
>    from OpenGL.raw.GL import *
>  File ".\OpenGL\raw\GL\__init__.py", line 6, in <module>
>    from OpenGL.raw.GL.constants import *
>  File ".\OpenGL\raw\GL\constants.py", line 7, in <module>
>    from OpenGL import platform, arrays
>  File ".\OpenGL\arrays\__init__.py", line 22, in <module>
>    formathandler.FormatHandler.loadAll()
>  File ".\OpenGL\arrays\formathandler.py", line 37, in loadAll
>    cls.loadPlugin( entrypoint )
>  File ".\OpenGL\arrays\formathandler.py", line 44, in loadPlugin
>    plugin_class = entrypoint.load()
>  File ".\OpenGL\plugins.py", line 14, in load
>    return importByName( self.import_path )
>  File ".\OpenGL\plugins.py", line 28, in importByName
>    module = __import__( ".".join(moduleName), {}, {}, moduleName)
>  File ".\OpenGL\arrays\strings.py", line 8, in <module>
>    psas = ctypes.pythonapi.PyString_AsString
>  File "ctypes\__init__.pyo", line 366, in __getattr__
>  File "ctypes\__init__.pyo", line 371, in __getitem__
> AttributeError: function 'PyString_AsString' not found
> 
> 
> 
> 
> Here is the script I'm currently using, based on the pygame wiki script:
> 
> 
> # This will create a dist directory containing the executable file, all the data
> # directories. All Libraries will be bundled in executable file.
> #
> # Run the build process by entering 'pygame2exe.py' or
> # 'python pygame2exe.py' in a console prompt.
> #
> # To build exe, python, pygame, and py2exe have to be installed. After
> # building exe none of this libraries are needed.
> 
> try:
>    from distutils.core import setup
>    import py2exe, pygame
>    from modulefinder import Module
>    import glob, fnmatch
>    import sys, os, shutil
>    import operator    
> except ImportError, message:
>    raise SystemExit,  "Unable to load module. %s" % message
> 
> #---HACK
> origIsSystemDLL = py2exe.build_exe.isSystemDLL
> def isSystemDLL(pathname):
>       if os.path.basename(pathname).lower() in ["sdl_ttf.dll","sdl_mixer.dll","libogg-0.dll"]:
>               return 0
>       return origIsSystemDLL(pathname)
> py2exe.build_exe.isSystemDLL = isSystemDLL
> #---ENDHACK
> 
> 
> class pygame2exe(py2exe.build_exe.py2exe): #This hack make sure that pygame default font is copied: no need to modify code for specifying default font
>    def copy_extensions(self, extensions):
>        #Get pygame default font
>        pygamedir = os.path.split(pygame.base.__file__)[0]
>        pygame_default_font = os.path.join(pygamedir, pygame.font.get_default_font())
> 
>        #Add font to list of extension to be copied
>        extensions.append(Module("pygame.font", pygame_default_font))
>        py2exe.build_exe.py2exe.copy_extensions(self, extensions)
> 
> class BuildExe:
>    def __init__(self):
>        #Name of starting .py
>        self.script = "main.py"
> 
>        #Name of program
>        self.project_name = "Around"
> 
>        #Project url
>        self.project_url = "about:none"
> 
>        #Version of program
>        self.project_version = "0.0.0.1"
> 
>        #License of the program
>        self.license = "MyApps License"
> 
>        #Auhor of program
>        self.author_name = "Keith Nemitz"
>        self.author_email = "musenik atya hoo doh com"
>        self.copyright = "Copyright (c) 2010 Keith Nemitz. All rights reserved."
> 
>        #Description
>        self.project_description = "..."
> 
>        #Icon file (None will use pygame default icon)
>        self.icon_file = None
> 
>        #Extra files/dirs copied to game
>        self.extra_datas = ["data","OpenGL","extras/Microsoft.VC90.CRT.manifest",
>                                    "extras/msvcm90.dll","extras/msvcp90.dll","extras/msvcr90.dll"]
> 
>        #Extra/excludes python modules
>        self.extra_modules = []
>        self.exclude_modules = ["OpenGL"]
> 
>        #DLL Excludes
>        self.exclude_dll = ['']
> 
>        #Zip file name (None will bundle files in exe instead of zip file)
>        self.zipfile_name = None
> 
>        #Dist directory
>        self.dist_dir ='dist'
> 
>    ## Code from DistUtils tutorial at http://wiki.python.org/moin/Distutils/Tutorial
>    ## Originally borrowed from wxPython's setup and config files
>    def opj(self, *args):
>        path = os.path.join(*args)
>        return os.path.normpath(path)
> 
>    def find_data_files(self, srcdir, *wildcards, **kw):
>        # get a list of all files under the srcdir matching wildcards,
>        # returned in a format to be used for install_data
>        def walk_helper(arg, dirname, files):
>            if '.svn' in dirname:
>                return
>            names = []
>            lst, wildcards = arg
>            for wc in wildcards:
>                wc_name = self.opj(dirname, wc)
>                for f in files:
>                    filename = self.opj(dirname, f)
> 
>                    if fnmatch.fnmatch(filename, wc_name) and not os.path.isdir(filename):
>                        names.append(filename)
>            if names:
>                lst.append( (dirname, names ) )
> 
>        file_list = []
>        recursive = kw.get('recursive', True)
>        if recursive:
>            os.path.walk(srcdir, walk_helper, (file_list, wildcards))
>        else:
>            walk_helper((file_list, wildcards),
>                        srcdir,
>                        [os.path.basename(f) for f in glob.glob(self.opj(srcdir, '*'))])
>        return file_list
> 
>    def run(self):
>        if os.path.isdir(self.dist_dir): #Erase previous destination dir
>            shutil.rmtree(self.dist_dir)
> 
>        #Use the default pygame icon, if none given
>        if self.icon_file == None:
>            path = os.path.split(pygame.__file__)[0]
>            self.icon_file = os.path.join(path, 'pygame.ico')
> 
>        #List all data files to add
>        extra_datas = []
>        for data in self.extra_datas:
>            if os.path.isdir(data):
>                extra_datas.extend(self.find_data_files(data, '*'))
>            else:
>                extra_datas.append(('.', [data]))
> 
>        setup(
>            cmdclass = {'py2exe': pygame2exe},
>            version = self.project_version,
>            description = self.project_description,
>            name = self.project_name,
>            url = self.project_url,
>            author = self.author_name,
>            author_email = self.author_email,
>            license = self.license,
> 
>            # targets to build
>            windows = [{
>                'script': self.script,
>                'icon_resources': [(0, self.icon_file)],
>                'copyright': self.copyright
>            }],
>            options = {'py2exe': {'optimize': 2, 'bundle_files': 1, 'compressed': True, "includes": ["ctypes", "logging"],
>                                  'excludes': self.exclude_modules, 'packages': self.extra_modules, 
>                                  'dll_excludes': self.exclude_dll} },
>            zipfile = self.zipfile_name,
>            data_files = extra_datas,
>            dist_dir = self.dist_dir
>            )
> 
>        if os.path.isdir('build'): #Clean up build dir
>            shutil.rmtree('build')
> 
> if __name__ == '__main__':
>    if operator.lt(len(sys.argv), 2):
>        sys.argv.append('py2exe')
>    BuildExe().run() #Run generation
>    raw_input("Press enter key to continue") #Pause to let user see that things ends 
>