Giving Python legs with XULRunner
Python and XUL are both great languages. Combining them with PyXPCOM and XULRunner promises to be a great combination for creating cross platform GUI applications e.g. Komodo. This post shows how to build and test XULRunner (CVS Head,July 29th 2005) with Python (2.3.5) on Gentoo using gcc 3.4.4 borrowing from work by Christian Persch and Paul Rouget among Others.
- You must link against the Python dynamic library (libpython2.3.so on my machine), (you need to be root to do this)
# cd /usr/lib/python2.3/config && ln -s /usr/lib/libpthon2.3.so .
doing this prevents this common error on xulrunner startup:Fatal Python error: Interpreter not initialized (version mismatch?)
- Create and move to a directory where you will do the build (not as root) e.g.
- Execute these commands to build XULRunner with PyXPCOM
$ wget -c http://homepage.eircom.net/~rachra/build_xulrunner_pyxpcom.sh $ chmod 755 build_xulrunner_pyxpcom.sh $ ./build_xulrunner_pyxpcom.sh
build_xulrunner_pyxpcom.sh is shown belowsit back and wait for an hour or two while XULRunner and PyXPCOM build.1:#!/bin/sh 2:DATE=`date +"%d-%m-%y"` 3:base=`pwd` 4:export CVSROOT=:pserver:anonymous:anonymous@cvs-mirror.mozilla.org:/cvsroot 5:MOZCONFIG=$base/mozilla/.mozconfig 6: 7:#----- remove existing build 8:rm -rf $base/mozilla 9: 10:#----- checkout mozilla from cvs HEAD and create .mozconfig 11:cvs login || exit $? 12:cd $base 13:cvs checkout mozilla/client.mk || exit $? 14:cat << EOF > $MOZCONFIG 15:export MOZILLA_OFFICIAL=1 16:mk_add_options MOZILLA_OFFICIAL=1 17:mk_add_options MOZ_CO_PROJECT=xulrunner 18:ac_add_options --enable-application=xulrunner 19:ac_add_options --disable-debug 20:ac_add_options --disable-tests 21:ac_add_options --disable-optimize 22:ac_add_options --enable-default-toolkit=gtk2 23:ac_add_options --enable-xft 24:ac_add_options --disable-freetype2 25:ac_add_options --enable-extensions=python/xpcom 26:EOF 27: 28:cd mozilla 29:make -f client.mk checkout || exit $? 30: 31:#----- patch the python source http://live.gnome.org/Epiphany_2fEphyPython_2fPyXPCOM 32:cd $base 33:wget -c http://www.gnome.org/~chpe/pyxpcom2.diff 34:cd $base/mozilla/extensions/python/xpcom 35:patch -p0 < $base/pyxpcom2.diff 36:cd $base/mozilla 37: 38:#----- build mozilla 39:make -f client.mk build || exit $?
- Test your xulrunner build
You should see a GUI with a button to increment the number in a text field.
$ cd ~/xulrunner/mozilla/dist/bin $ ./xulrunner ../xpi-stage/simple/application.ini
- Test your PyXPCOM integration with this XULRunner app I've created (A Firefox extension with the same code can be found here). This app uses the PyXPCOM test component (~/xulrunner/mozilla/dist/bin/components/py_test_component.py).
Instructions on creating XULRunner apps can be found here and here.
You should see a GUI with some text and one button, clicking the button will bring up a message box that will tell you if PyXPCOM integration has succeeded or failed.
$ cd ~/xulrunner/mozilla/dist/xpi-stage $ wget -c http://homepage.eircom.net/~rachra/pyxpcomxul.zip $ unzip pyxpcomxul.zip $ cd ~/xulrunner/mozilla/dist/bin $ ./xulrunner ../xpi-stage/pyxpcomxul/application.ini
Fragment of py_test_component.py that gets calledpyxpcomxul.zip contains the following files:252: def GetStrings(self): 253: # void GetStrings(out PRUint32 count, 254: # [retval, array, size_is(count)] out string str); 255: return "Hello from the Python test component".split()
pyxpcomxul/application.inipyxpcomxul/defaults/preferences/pyxpcomxul-prefs.js1:#filter substitution 2:[App] 3:; 4:; This field specifies your organization's name. This field is recommended, 5:; but optional. 6:Vendor=Propylon 7:; 8:; This field specifies your application's name. This field is required. 9:Name=pyxpcomxul 10:; 11:; This field specifies your application's version. This field is optional. 12:Version=0.1 13:; 14:; This field specifies your application's build ID (timestamp). This field is 15:; required. 16:BuildID=20050728 17:; 18:; This field specifies a compact copyright notice for your application. This 19:; field is optional. 20:Copyright=Copyright (c) 2005 Mozilla 21:; 22:; This ID is just an example. Every XUL app ought to have it's own unique ID. 23:; You can use the microsoft "guidgen" or "uuidgen" tools, or go on 24:; irc.mozilla.org and /msg botbot uuid. This field is optional. 25:ID={604f89f5-b138-40f9-9c67-f9ae064d6ef3} 26: 27:[Gecko] 28:; 29:; This field is required. It specifies the minimum Gecko version that this 30:; application requires. Specifying 1.8 matches all releases with a version 31:; prefixed by 1.8 (e.g., 1.8a4, 1.8b, 1.8.2). 32:MinVersion=1.8 33:; 34:; This field is optional. It specifies the maximum Gecko version that this 35:; application requires. It should be specified if your application uses 36:; unfrozen interfaces. Specifying 1.8 matches all releases with a version 37:; prefixed by 1.8 (e.g., 1.8a4, 1.8b, 1.8.2). 38:MaxVersion=1.8 39: 40:
pyxpcomxul/chrome/chrome.manifest1:pref("toolkit.defaultChromeURI", "chrome://pyxpcomxul/content/pyxpcomxul.xul"); 2:pref("general.useragent.extra.pyxpcomxul", "PyXPCOMXUL/0.1");
content pyxpcomxul jar:pyxpcomxul.jar!/pyxpcomxul/content/
pyxpcomxul/chrome/pyxpcomxul.jar!/pyxpcomxul/content/pyxpcomxul.xulpyxpcomxul/chrome/pyxpcomxul.jar!/pyxpcomxul/content/pyxpcom.js1:<?xml version="1.0"?> 2:<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 3:<window 4: id="pyxpcomtest-window" 5: title="PyXPCOMTest" 6: orient="horizontal" 7: xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 8: <script type="application/x-JavaScript" src="chrome://pyxpcomxul/content/pyxpcom.js"/> 9: <keyset> 10: <key id="close-window" modifiers="accel" key="W" oncommand="window.close();"/> 11: <key id="quit" modifiers="accel" key="Q" oncommand="window.close();"/> 12: <key id="push-button" modifiers="accel" key="T" oncommand="testPythonInterface();"/> 13: </keyset> 14: <vbox> 15: <label>This is the PyXPCOM test component, click on the button. 16: (relies on component py_test_component.py)</label> 17: <button id="testPyXPCOM" label="Test PyXPCOM" 18: accesskey="T" key="push-button" oncommand="testPythonInterface();"/> 19: <label>if you get the message "Hello,from,the,Python,test,component", 20: you have connection to PyXPCOM objects.</label> 21: </vbox> 22:</window>
1:var cls = this.Components.classes["Python.TestComponent"]; 2:var pyTestObj = cls.createInstance(Components.interfaces.nsIPythonTestInterface); 3: 4:function testPythonInterface() 5:{ 6: try { 7: var j = new Object(); 8: var k; 9: var retArray = pyTestObj.GetStrings(j, k); 10: alert("Test Succeeded: "+retArray); 11: } 12: catch (e) { 13: alert("Test Failed: "+e); 14: } 15:}
- View the PyXPCOM integration code. The code that is being run is actually contained in the pyxpcomxul/chrome/pyxpcomxul.jar file
See Activestate and IBM for a tutorial on writing PyXPCOM components.
$ cd ~/xulrunner/mozilla/dist/xpi-stage/pyxpcomxul/chrome $ unzip pyxpcomxul.jar $ jedit pyxpcomxul/content/pyxpcomxul.xul $ jedit pyxpcomxul/content/pyxpcom.js $ jedit ../../../bin/components/py_test_component.py
- Modify and re-deploy code. Make any changes you like to the .xul or .js file (xcomponent can be found at ~/xulrunner/mozilla/dist/bin
Modifications to the .py file are picked up immediately.
$ cd ~/xulrunner/mozilla/dist/xpi-stage/pyxpcomxul/chrome $ zip -r pyxpcomxul.jar pyxpcomxul/ $ cd ~/xulrunner/mozilla/dist/bin $ ./xulrunner ../xpi-stage/pyxpcomxul/application.ini
$ mkdir ~/xulrunner && cd ~/xulrunner
- Should be possible to deploy python xpcomponents to ~/xulrunner/mozilla/dist/xpi-stage/pyxpcomxul/components directory, couldn't get this to work
- Replace all Javascript with Python i.e.
replace
with
8: <script type="application/x-JavaScript" src="chrome://pyxpcomxul/content/pyxpcom.js"/>
8: <script type="application/x-python" src="chrome://pyxpcomxul/content/pyxpcom.py"/>
- Updating of XULRunner components similar to Firefox extensions, not sure how this is achieved.

4 Comments:
hi,
i was wondering if you know of any updated instruction on how to build xulrunner with pyxpcom (regarding the fact that all dev takes place now in the DOM_AGNOSTIC2_BRANCH), or if you managed to build a recent xulrunner with pyxpcom and care to share your experience.
thx for any pointer/info
any luck with getting this to compile on windows? i can't seem to get xulrunner to compile with python support.
Michael,
Looks interesting. I'm going to try it out later. I've been looking forward to using Python with XML. I'm no fan of javascript.
That is so great!
It's also possible to run python in parallel on SMP: Parallel Python
Post a Comment
<< Home