End-User Distribution

From PyWiki

Jump to: navigation, search

The best way to package your Python-Ogre code for end users is to use

Alternately you can simply ship .pyc files along with Python25 and PythonOgre distribution.

Contents

[edit] Setup Programs

NSIS is an excellent choice for a free installer for Windows.

[edit] Code Disassemble

Can python compiled code (in .pyc files) be decompiled? Yes and no. While it is easier to decompile python code then c/c++ assembler code, it is not easy, and one could never get the full source, as it was written from it.

If you're really concerned, you can use pyobfuscate to sramble your code before compiling it to pyc files. that way, even if someone manages to decompile your code, it would be virtually unreadable.


[edit] Windows

When packaging a setup on Windows, be sure to include Visual Studio redistributable package. DirectX installer is also a good idea, though not necessary.

Alternatly, you can distribute Visual studio redist via a method called Side-By-Side assembly :

  • Copy C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT to your distribution directory.
  • Make sure to put that folder in each your folder that contains executable files or dll's.

[edit] py2exe

What I used to get it working

Build PythonOgre executable using py2exe:

I wrote a game, which gets initialization information from config files (not python scripts) in a config_folder in the main folder 'C:\PythonOgre\demos\MyGame'. So the directory structure for my game would be:

> MyGame
---> config_folder
------> config1.conf
------> config2.conf
---> mygame.py
---> lib_file1.py
---> lib_file2.py

I was able to successfully create executables for the game using py2exe. Just want to share with you guys the procedure, which does not seem to be described thoroughly anywhere.

[edit] Requirements

1. You can't organize your modules into folders like './libs'. You must dump all scripts into your main folder, i.e. MyGame in my case. Main reason: Avoid changing sys path in your game.

2. You must be able to run your program thoroughly without any error (apparently).

[edit] Steps:

1. Create file 'setup.py' in folder MyGame. The content is simple:

from distutils.core import setup
import py2exe

create a bat file like from http://www.py2exe.org/index.cgi/WinBatch

Note that if you use any "dynamic" importing of modules you will need to add them to the packages option in that batch file

3. the internet for following files: MSVCP80.dll and MSVCR80.dll. After you have done step 2, they must be somewhere in your computer. Copy them to folder MyGame.

4. Search in Ogre folders (I can't remember which one, to play safe, just search in all), at least look at C:\PythonOgre (or the respective installed folder of PythonOgre on your PC) and %Python25_folder%, the file: boost_python-vc90-mt-1_36.dll. Copy it to folder MyGame.

5. Try running the bat file. Search in the python ogre folder for *.dll and get most of those there

6. The py2exe command in step 5 should have ended successfully by now. Now, all your executables are ready in MyGame\dist.

7. (for my own game) Copy config_folder into dist.

8. Copy plugins.cfg and resources.cfg to dist.

9. In dist, create folder 'plugins'. Copy all dll files from C:\PythonOgre\plugins to this folder.

10. In dist, open plugins.cfg, change 'PluginFolder=../../plugins' to 'PluginFolder=./plugins'

11. In dist, create folder Media. In folder Media, create folder 'Ogre' to store Ogre's resources, and folder 'MyGame' to store MyGame's resources. Copy all folders from C:\PythonOgre\demos\media into 'Ogre', and copy all your resource files to 'MyGame'

12. In dist, open resources.cfg. Change all paths of Bootstrap and General section from '../media' to 'Media/Ogre', and all paths of MyGame section to 'Media/MyGame'. The important file in this case is the ogrecore.zip if you want a smaller executable.

13. Try running mygame.exe several times. Whenever you encounter a problem, check out mygame.exe.log for the error message. If there is error regarding file not found, try searching it on your computer, and copy to folder 'dist' or 'dist\plugins'.

14. Done!!

[edit] Mac OS X

Applications in Mac OS X are bundles -- specially formatted folders with extension .app. You can examine .app folders by choosing "Show package contents" from contextual menu in Finder, or by browsing into the .app folder through terminal.

Most applications in Mac OS X are expected to be installable by dragging the .app bundle onto the hard drive. Freeware is usually distributed online, via .dmg files built with Disk Utility.

Since bundles are folders, you can store your data files in them.

[edit] Where in the world are dylibs?

I recommend libboost*.dylib files, already mentioned in OSXBuildV2, to be placed along with the main script (app.py, exe.py, debug.py or whatever you call it) - typically, in the root of the game (.../dev/po-game/). That way, you don't have to mess with DYLD_LIBRARY_PATH, and py2app will be able to find it hyper-easily.

[edit] Copying PythonOgre packages

This is quite probably optional. Nevertheles... :-)

No matter what you do, you want to get the PythonOgre packages somewhere you and your app can easily find them (besides, you want to fixate them at certain version during dev process even if you update systemwide PythonOgre). If you followed OSXBuildV2 you have your PythonOgre build system in /Users/blah/development/. Additionally, all your finally-built libs end up in /Users/blah/development/root/usr/lib/python2.5/site-packages. Just copy "ogre" into your app's development folder. That way it's easy to import the Ogre modules and you fixated the version used.

[edit] py2app

A good way to package Python applications is py2app. Check out their documentation for detailed installation tutorial and generic information.

Let's examine a few PyhonOgre-related issues.

[edit] Basic setup script

#!/usr/bin/python
from setuptools import setup
 
sys.argv+=['py2app'] # trick setuptools into thinking we're automagically starting py2app. this is so we don't need to specify 'py2app' argument on cmdline
NAME="PythonOgre Game"
VERSION="1.0 mac"
plist={'CFBundleIconFile':NAME,
       'CFBundleName':NAME,
       'CFBundleShortVersionString':VERSION,
       'CFBundleGetInfoString':' '.join([NAME, VERSION]),
       'CFBundleExecutable':NAME,
       'CFBundleIdentifier':'com.example.identifier.replace.this',
}
 
setup(app=[{'script':'exe.py','plist':plist}],
        setup_requires=["py2app"]
      )

(Adapted from the script we're using, for explanation purposes. See py2app trunk for real examples and documentation.)

In above example, plist is using as the equivalent of a resource file (.rc) in C++ win32 projects. It assigns name of bundle, icon file, creator identifier, etc. We're also specifying exe.py as our startup script. This is the script from which the execution starts.

Why are we modifying sys.argv? setuptools would want us launch like this:

$ python setup.py py2app

Since we're just making a simple build script, we've added a hashbang (#!/usr/bin/python) and sys.argv modification so we can easily test like this:

$ ./setup.py

[edit] Problem with finding _ogre_.so

Having problem with py2app finding _ogre_.so?

8/15/09 12:36:45 PM [0x0-0x42042].com.example.identifier.replace.this[527] ImportError: '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload/ogremac/renderer/OGRE/_ogre_.so' not found 

Solution is hackish, but simple. According to a March 2008 mailing list post, there won't be a fix.

Just insert this in your exe.py.

import sys,platform
if platform.system()=='Darwin':
    sys.path.insert(0, '../Resources/lib/python2.5/lib-dynload')
    sys.path.insert(0, '../Resources/lib/python2.5/site-packages.zip')

[edit] Any included source .py files?

Your exe.py will be included. From what I can tell, other source will not be included. Only .pyc files will be there. You may want to examine the .app bundle yourself before sending that RTM CD master into production, though... :-)

[edit] Including Python into .app for distribution

According to this mailing list post, if you install python.org Python, and use that instead of Apple's included Python when running py2app setup script, the python.org Python should be included.

You will quite probably have to rebuild boost_python, and thus PythonOgre, even if you use the same version of Python (e.g. in Leopard 2.5.1 is included -- even if you install 2.5.1 from python.org, you will probably have to rebuild). At least the author of these lines had to.

Including Python in the .app is a must if you intend to distribute to 10.4.

[edit] Including frameworks into .app for distribution

If broken frameworks get included in the .app (those that don't include library itself), try copying into your systemwide /Library/Frameworks (as of 996):

sudo cp -Rf /Users/blah/development/{ogre/Dependencies/,ogre/Mac/build/Release/,ois/Mac/XCode-2.2/build/Release/}*.{f,F}ramework /Library/Frameworks/

Then copy them into your .app, approximately like this:

for folder in ('/Library/Frameworks/CEGUI.framework',
               '/Library/Frameworks/Ogre.framework',
               '/Library/Frameworks/OgreCEGUIRenderer.framework',
               '/Library/Frameworks/OIS.framework'):
    dest='thisismyappsname.app/Contents/Frameworks/' + os.path.basename(folder)
    try: shutil.rmtree(dest)
    except: pass
    cp(folder,dest)

[edit] Building for 10.4 and PPC compatibility

There is more about this on OSXBuildV2. If you just followed regular build process, you will have to rebuild.

A nice trick to test for PPC compatibility is to right click on your .app, do a "Get Info", and tick "Run with Rosetta" checkbox. This will force the OS to use Rosetta even if the built code is an universal binary.

Personal tools