Standalone PyXPCOM

From MozillaZine Knowledge Base

This page describes a way to build PyXPCOM support "stand-alone", without rebuilding the entire mozilla application. Currently this has been tested under Linux, but it should be applicable to other platforms as well.

These instructions are based on building standalone XPCOM.


First you need to pull the source:

cvs -z3 -d co -r DOM_AGNOSTIC2_BRANCH mozilla/
cd mozilla
gmake -f pull_all BUILD_MODULES=xpcom MOZ_CO_MODULE=mozilla/extensions/python/xpcom,mozilla/extensions/

(note that I'm using the DOM_AGNOSTIC2 branch; at the time of writing (2005-12-14), the pyxpcom module in the trunk fails to build)

Then, you build it.

./configure --enable-application=standalone --enable-standalone-modules=xpcom --enable-extensions=python/xpcom
make BUILD_MODULES=all tier_42_dirs=extensions tier_42

If everything goes well, you can try a few tests:

cd dist/bin
export PYTHONPATH=python
python python/xpcom/tools/

Browser integration

At this point you're ready to play with the basic PyXPCOM. However, most XPCOM components will be unavailable, since you've only built the standalone xpcom libraries. For serious work, you'll probably want to integrate PyXPCOM into the browser.

I've tested adding PyXPCOM from the latest DOM_AGNOSTIC2_BRANCH (2005-12-14) to Firefox 1.5 without problems. I assume it will also work with Mozilla Suite.

I've copied the following files from dist/bin to the Firefox directory (preserving their relative paths):

  • components/
  • python/*

Then you need to convince Firefox to rescan the components. For me, this meant removing compreg.dat and xpti.dat from my profile. If you then start Firefox from the commandline, it should report "Registering 'moz.pyloader.1' (".


Here's a sample component I wrote for a quick test. I've placed it in $(firefox)/components/

from xpcom import components, verbose

class AboutPython:
        _com_interfaces_ = components.interfaces.nsIAboutModule
        _reg_contractid_ = ';1?what=python'
        _reg_clsid_ = '{6d5d462e-6de7-4bca-bbc6-c488d481351b}'
        _reg_desc_ = "about:python handler"

        def __init__(self):

        def newChannel(self, aURI):
                ioService = components.classes[";1"] \
                uri = ioService.newURI("", "utf-8", aURI)
                return ioService.newChannelFromURI(uri)

See above on how to refresh the component database. If it works, typing "about:python" in the address bar should load