Xulrunner 1.9 will be the default gecko provider in ubuntu. For hardy, every application in main that currently uses firefox as a gecko provider needs to be migrated to use xulrunner 1.9. Gecko embedders in universe can choose to either use xulrunner 1.9 or xulrunner 1.8, but should be aware that xulrunner 1.8 security support will eventually cease during hardy life-cycle - a LTS release. The same is true for extensions and plugins. Those shipped in main need to use xulrunner 1.9, universe extensions and plugins can choose.

This document outlines the release goals and document basics on how to transition your software to xulrunner 1.9. The last two sections annotate patches for real life transitions.

Release Goals


  1. ship xulrunner 1.9 in main: Shipping xulrunner 1.9 in main is an essential requirement for replacing firefox 2 as the default gecko/xpcom provider in ubuntu.
  2. ship firefox 3.0 with --enable-system-xul: use xulrunner 1.9 instead of the in source libxul for firefox.
  3. rdepends transition in main: all packages in main that currently use firefox for gecko or xpcom need to be migrated to use xulrunner-1.9. This includes firefox plugins, gecko embedders and extensions with native components.


  1. rdepends transition in universe: all packages either have to
    • migrate to build against xulrunner-1.9 (preferred) or
    • use xulrunner 1.8 (which we will keep unsupported in universe). Its important to note that as many packages as possible should be transitioned to use xulrunner-1.9, as the security support of 1.8 will eventually cease during the hardy lifetime.
  2. ship thunderbird 3.0: this isn't mandatory as it might not be doable and thunderbird should be supportable more easily security wise.
  3. ship suite-runnner (seamonkey) 2.0: this isn't mandatory as seamonkey is not in main

Transition to Xulrunner 1.9 - Basics

Depends and Build Depends

Xulrunner isn't a real lib, but rather a SDK with a runtime/runner and so the Depends are not auto-detected. So manually add a dependency on xulrunner-1.9 to your package.

Packages that need the xulrunner 1.9 sdk need to build depend on xulrunner-1.9-dev. If they require nspr/nss they should also depend on the libnspr4-dev and libnss3-dev packages.

New Directories for plugins/extensions


xulrunner main directory


xulrunner addons directory


plugins directory considered by all xul applications


extension directory considered by all xul applications

The idea is to install extensions that have more than one target application specified in their install.rdf into the xulrunner-addons directory.

In addition - for cases where plugins/extensions are firefox only - there exist a similar directories for firefox.


plugins directory considered by firefox (>= 3)


extension directory considered by firefox (>= 3)


searchplugins directory for firefox

Frozen Linkage

Xulrunner 1.9 finally enforces frozen linkage. This might require some coding. The upstream guide on how to migrate the code is available here: http://developer.mozilla.org/en/docs/Migrating_from_Internal_Linkage_to_Frozen_Linkage.

Using the Glue

Xulrunner doesn't support directly linking to its libraries. After all they ship in pkglibdir. There are two kind of glues to escape this:

  1. Dependent Glue - only for components/modules that get loaded into an already booted libxul application. In general plugins and native extensions should use these link options.

    pkg-config --cflags --libs libxul-unstable


    PKG_CHECK_MODULES [MOZILLA, libxul-unstable]

    You can use libxul instead of libxul-unstable if you only need headers from /usr/include/xulrunner-1.9*/stable/.

  2. Standalone Glue - all standalone applications should try as hard as possible to use the standalone glue. Only this will provide the proper way of loading xpcom on your own. This way of linking should be used by all standalone applications that are not xul applications (xul applications can be started through xulrunner, like firefox 3). For example, all current gecko embedders (using gtkmozembed) are supposed to use this link option:

    pkg-config --cflags --libs libxul-embedding-unstable


    PKG_CHECK_MODULES [MOZILLA, libxul-embedding-unstable]

    You can use libxul-embedding instead of libxul-embedding-unstable if you only need headers from /usr/include/xulrunner-1.9*/stable/.

Read the http://developer.mozilla.org/en/docs/XPCOM_Glue instructions for more info on this.

Moved Headers

In previous mozilla releases, the headers were shipped in /usr/include/<XULAPP>/ and module specific headers in /usr/lib/<XULAPP>/<modulename>/.

$(pkg-config --variable=includedir libxul)/stable

contains stable xulrunner headers

$(pkg-config --variable=includedir libxul)/unstable

contains ALL (unstable + stable) xulrunner headers

Xulrunner 1.9 starts to ship everything in libxul and so the component split became useless. Thus, headers are now placed just in unstable and stable directories.

Moved .idl Files

Directories for .idl files follow the same stable/unstable scheme:

$(pkg-config --variable=idldir libxul)/stable

contains stable xulrunner headers

$(pkg-config --variable=idldir libxul)/unstable

contains ALL (unstable + stable) xulrunner headers

Asking for Help

If you tried to port your application and are stuck please post a bug in launchpad against xulrunner-1.9. Please attach your current work and describe what you did and how you are stuck.

Transition to Xulrunner 1.9 - Instructions

Transitioning applications might require skills in build systems (mostly autoconf/automake and friends) and C++.

Standalone Applications

Transitioning to standalone glue:

  1. build with CFLAGS=pkg-config --cflags libxul-embedding-unstable (if you only need stable API you can use libxul-embedding)

  2. build with LIBS=pkg-config --libs libxul-embedding (you might need to add --libs nspr to LIBS if you need nspr; remember to add -DXPCOM_GLUE_NEEDS_NSPR to CFLAGS above)

  3. properly initialize the GRE before doing any other xpcom/gecko operation (see the yelp_gecko_init function in the yelp example below)
  4. migrate the code to frozen linkage (http://developer.mozilla.org/en/docs/Migrating_from_Internal_Linkage_to_Frozen_Linkage)

Extensions and Plugins

Transitioning to dependent glue:

  1. build with CFLAGS=pkg-config --cflags libxul-unstable (if you only need stable API you can use libxul instead)

  2. build with LIBS=pkg-config --libs libxul (you might need to add --libs nspr to LIBS if you need nspr)

  3. properly initialize the GRE before doing any other xpcom/gecko operation (see example below)
  4. migrate the code to frozen linkage (http://developer.mozilla.org/en/docs/Migrating_from_Internal_Linkage_to_Frozen_Linkage)

  5. find the right place to install your extension/plugin and adapt your packaging accordingly.

Transition to Xulrunner 1.9 - Examples

Existing projects frequently have a lot legacy code in their build system. This can be tricky to port, especially if you don't want to break builds with older geckos.

The patches annotated below are maintained at:

bzr branch https://code.launchpad.net/~mozillateam/xulrunner/xulrunner-porting

Transition example - Standalone Glue/Application - yelp

Yelp uses the m4/gecko.m4 file available in the bzr porting branch (see previous section)

The patch below is stripped down and excludes the diff of the gecko.m4 which is taken unmodified from the bzr porting branch. Do the same if your build system makes use of a gecko.m4 file.

--- yelp-2.20.0.orig/configure.in
+++ yelp-2.20.0/configure.in
@@ -185,21 +185,26 @@
 case "$MOZILLA" in
 xulrunner) gecko_min_version=1.8 ;;
+libxul-embedding) gecko_min_version=1.9 ;;
 *firefox) gecko_min_version=1.5 ;;
 *) AC_MSG_ERROR([$gecko_cv_gecko is not supported])
-PKG_CHECK_MODULES([MOZILLA_COMPONENT],[${gecko_cv_gecko}-xpcom >= $gecko_min_version $gecko_cv_extra_pkg_dependencies])
+if test $MOZILLA = libxul-embedding; then
+       PKG_CHECK_MODULES([MOZILLA_COMPONENT],[libxul-embedding-unstable $gecko_cv_extra_pkg_dependencies])
+       PKG_CHECK_MODULES([MOZILLA_COMPONENT],[${gecko_cv_gecko}-xpcom >= $gecko_min_version $gecko_cv_extra_pkg_dependencies])
 dnl ====================================
 dnl = zlib for help converters
 dnl ====================================
 AC_CHECK_LIB(z, gzopen, [Z_LIBS=-lz
 AC_SUBST(Z_LIBS)], AC_MSG_ERROR([*** zlib is required]))
 dnl ====================================

     !!! we enable a special --with-gecko= argument ```libxul-embedding''' which then uses pkg-config to determine the MOZILLA_COMPONENT_CFLAGS. !!!


--- yelp-2.20.0.orig/src/Makefile.am
+++ yelp-2.20.0/src/Makefile.am
@@ -60,20 +60,22 @@
        uriloader       \
        webbrwsr        \
        webshell        \
 yelp_CPPFLAGS =                                                                        \
        -I$(top_srcdir)                                                         \
        -I$(top_builddir)/src                                                   \
-       $(addprefix -I$(MOZILLA_INCLUDE_ROOT)/,$(mozilla_include_subdirs))      \
        $(YELP_DEFINES)                                                         \
+yelp_CPPFLAGS += $(addprefix -I$(MOZILLA_INCLUDE_ROOT)/,$(mozilla_include_subdirs))
 yelp_CFLAGS =                          \
        $(YELP_CFLAGS)                  \
        $(YELP_SEARCH_CFLAGS)           \
 yelp_CXXFLAGS =                                \
        $(YELP_CFLAGS)                  \
        $(YELP_SEARCH_CFLAGS)           \

     !!! We add the complete MOZILLA_COMPONENT_CFLAGS to the build CPPFLAGS !!!


@@ -86,17 +88,17 @@
        $(POPT_LIBS)                    \
        $(Z_LIBS)                       \
        $(BZ_LIBS)                      \
        $(X_LIBS)                       \
        $(MOZILLA_COMPONENT_LIBS)       \
        $(MOZILLA_EXTRA_LIBS)           \
 #check_PROGRAMS =              \
 #      test-document           \
 #      test-man-parser         \
 #      test-page               \
 #      test-transform          \
 #      test-resolver

     !!!  don't link using --rpath when using libxul-embedding !!!


@@ -432,25 +437,26 @@
   rv = NS_GetComponentRegistrar(getter_AddRefs(cr));
   nsCOMPtr<nsIComponentManager> cm;
   rv = NS_GetComponentManager (getter_AddRefs (cm));
   nsCOMPtr<nsIGenericFactory> componentFactory;
-  rv = NS_NewGenericFactory(getter_AddRefs(componentFactory),
-                           &(sAppComps[0]));
+  componentFactory = do_CreateInstance ("@mozilla.org/generic-factory;1", &rv);
   if (NS_FAILED(rv) || !componentFactory)
       g_warning ("Failed to make a factory for %s\n", sAppComps[0].mDescription);
+  componentFactory->SetComponentInfo(&(sAppComps[0]));
   rv = cr->RegisterFactory(sAppComps[0].mCID,
   if (NS_FAILED(rv))
       g_warning ("Failed to register %s\n", sAppComps[0].mDescription);

   !!! short-hand constructors for xpcom components are usually not accessible in frozen linkage anymore.
       Instead you have to use the standard xpcom facilities for that.!!!


Index: yelp-2.20.0/src/yelp-gecko-utils.cpp
--- yelp-2.20.0.orig/src/yelp-gecko-utils.cpp
+++ yelp-2.20.0/src/yelp-gecko-utils.cpp
@@ -22,16 +22,18 @@
 #include "mozilla-config.h"
 #include "config.h"
 #include <stdlib.h>
 #include <nsStringAPI.h>
+#include <gtkmozembed_glue.cpp>
 #include <gtkmozembed.h>
 #include <gtkmozembed_internal.h>
 #include <nsCOMPtr.h>
 #include <nsIPrefService.h>
 #include <nsIServiceManager.h>
 #include <nsServiceManagerUtils.h>
 #include "yelp-gecko-services.h"

   !!! legacy support for the gtk_moz_embed functions is not available directly. You need the #include <gtkmozembed_glue.cpp>
       magic to reuse legacy embedding code. New projects should use the available xpcom components directly or should even
       consider to write a real xul-application !!! (TODO: the example code above should use #ifdef XPCOM_GLUE ...)


@@ -197,31 +199,53 @@
        g_free (name);
 extern "C" gboolean
 yelp_gecko_init (void)
+       nsresult rv;
 #ifdef HAVE_GECKO_1_9
        NS_LogInit ();
+#ifdef XPCOM_GLUE
+       static const GREVersionRange greVersion = {
+       "1.9a", PR_TRUE,
+       "1.9.*", PR_TRUE
+       };
+       char xpcomLocation[4096];
+       rv = GRE_GetGREPathWithProperties(&greVersion, 1, nsnull, 0, xpcomLocation, 4096);
+       NS_ENSURE_SUCCESS (rv, rv);
+       // Startup the XPCOM Glue that links us up with XPCOM.
+       rv = XPCOMGlueStartup(xpcomLocation);
+       NS_ENSURE_SUCCESS (rv, rv);
+       rv = GTKEmbedGlueStartup();
+       NS_ENSURE_SUCCESS (rv, rv);
+       char *lastSlash = strrchr(xpcomLocation, '/');
+       if (lastSlash)
+       *lastSlash = '\0';
+       gtk_moz_embed_set_path(xpcomLocation);
 #ifdef HAVE_GECKO_1_9
        gtk_moz_embed_set_path (MOZILLA_HOME);
        gtk_moz_embed_set_comp_path (MOZILLA_HOME);
+#endif // XPCOM_GLUE
        gtk_moz_embed_push_startup ();
        yelp_register_printing ();
-       nsresult rv;
        nsCOMPtr<nsIPrefService> prefService (do_GetService (NS_PREFSERVICE_CONTRACTID, &rv));
        rv = CallQueryInterface (prefService, &gPrefBranch);
        return TRUE;

   !!! this piece of code is mandatory for standalone glue applications. It shows how to detect and load the proper
       runtime as a standalone glue application. In your application, this has to be done '''before''' any other
       gecko/xpcom function is used. The snippet above also illustrates why MOZILLA_HOME isn't needed anymore. !!!

Transition example - Dependent Glue/Plugin - totem

Plugins for xulrunner-1.9 should now be build using just the mozilla-plugin.pc pkg config file. For some plugins you might need xpcom as well (totem needs xpcom). If you need xpcom you do so by linking against the dependent glue.

XUL_LIBS=$(pkg-config --libs "libxul >= 1.9" "mozilla-plugin >= 1.9")
XUL_CFLAGS=$(pkg-config --cflags --define-variable=includetype=unstable "libxul >= 1.9" "mozilla-plugin >= 1.9")

The patch annotated below does a good job in keeping the build system untouched, by mapping the MOZILLA_ variables to special values in case xulrunner 1.9 is detected.

 (some hunks from the totem patch)

--- totem-2.21.2.orig/configure.in
+++ totem-2.21.2/configure.in
@@ -418,23 +418,29 @@
        GECKOS="xulrunner firefox mozilla-firefox seamonkey mozilla"
        if test -z "$with_gecko"; then
                dnl Autodetect gecko
                for g in $GECKOS; do
+                       if $PKG_CONFIG --exists $g-plugin; then
+                               gecko=$g
+                               break;
+                       fi

        !!!! here we test that whether we have xulrunner 1.9 which ships mozilla-plugin.pc !!!!


                        if $PKG_CONFIG --exists $g-xpcom; then
        elif ! $PKG_CONFIG --exists $gecko-xpcom; then
-               AC_MSG_ERROR([Gecko "$gecko" not found])
+               if ! $PKG_CONFIG --exists libxul; then
+                       AC_MSG_ERROR([Gecko "$gecko" not found])
+               fi

            !!!! same here: xul 1.9 doesn't ship xpcom anymore. test if libxul exists !!!


[... some hunks removed for the sake brevity]


@@ -503,20 +517,28 @@
        if test "x$DBUS_BIND" = "xno"; then
                AC_MSG_WARN([dbus-binding-tool not found])
 # Sets some variables, and check for xpidl
 if test "$enable_browser_plugins" = "yes" ; then
-       MOZILLA_PREFIX="`$PKG_CONFIG $MOZILLA-xpcom --variable=prefix`"
-       MOZILLA_LIBDIR="`$PKG_CONFIG $MOZILLA-xpcom --variable=libdir`"
-       MOZILLA_INCLUDE_ROOT="`$PKG_CONFIG --variable=includedir $MOZILLA-xpcom`"
-       MOZILLA_XPCOM_CFLAGS="-I`$PKG_CONFIG --variable=includedir $MOZILLA-xpcom`"
+       if $PKG_CONFIG --exists $MOZILLA-plugin; then
+               MOZILLA_PREFIX="`$PKG_CONFIG $MOZILLA-plugin --variable=prefix`"
+               MOZILLA_LIBDIR="`$PKG_CONFIG $MOZILLA-plugin --variable=sdkdir`/bin"
+               MOZILLA_INCLUDE_ROOT="`$PKG_CONFIG --variable=includedir $MOZILLA-plugin`"
+               MOZILLA_XPCOM_CFLAGS="`$PKG_CONFIG --cflags $MOZILLA-plugin libxul-unstable`"
+       else
+               MOZILLA_PREFIX="`$PKG_CONFIG $MOZILLA-plugin --variable=prefix`"
+               MOZILLA_LIBDIR="`$PKG_CONFIG $MOZILLA-plugin --variable=libdir`"
+               MOZILLA_INCLUDE_ROOT="`$PKG_CONFIG --variable=includedir $MOZILLA-xpcom`"
+               MOZILLA_XPCOM_CFLAGS="`$PKG_CONFIG --cflags $MOZILLA-xpcom`"
+       fi
        if test "x$MOZILLA_XPIDL" = "xno"; then
                AC_MSG_ERROR([xpidl compiler not found])

    !!! in this hunk you see how we map commonly used configure variables. There are a lots of projects that don't use pkg-config.
        (apparently for historical reasons. Try to update them to consider CFLAGS and LIBS from xulrunner pkg-config files. This
        should ease your pain transitioning to xulrunner 1.9.

        IMPORTANT: some projects use MOZILLA_LIBDIR to define MOZILLA_HOME and use that to initiliaze the component/plugin path.
        Further MOZILLA_HOME Is used to link with --rpath. Take extra care that you don't any of this. Dependent Glue 
        components don't need to care anyway, because they are loaded in a properly setup environment. Standalone Glue
        applications have to do it properly in gecko runtime initialization code (see standalone glue example).  !!!


@@ -528,18 +550,22 @@
        AC_ARG_VAR([MOZILLA_PLUGINDIR],[Where to install the plugin to])
 # Search for the idl include directory
 if test "$enable_browser_plugins" = "yes" ; then
-       dnl This only works on gecko 1.8
-       MOZILLA_IDLDIR="`$PKG_CONFIG --variable=idldir $MOZILLA-xpcom`"
+       dnl This only works on gecko 1.9 and 1.8
+       if $PKG_CONFIG --exists libxul; then
+               MOZILLA_IDLDIR="`$PKG_CONFIG --variable=idldir libxul`/unstable"
+       else
+               MOZILLA_IDLDIR="`$PKG_CONFIG --variable=idldir $MOZILLA-xpcom`"
+       fi
        dnl Fallback for older versions
        if test "x$MOZILLA_IDLDIR" = "x"; then
                MOZILLA_IDLDIR="`echo $MOZILLA_LIBDIR | sed -e s!lib!share/idl!`"
        dnl Some distributions (Gentoo) have it in unusual places
        if test "x$MOZILLA_IDLDIR" = "x"; then

     !!! When your component/application ships .idl files you need to adapt the idl patch like above. Idls are similarily to
         headers now categorized in unstable/stable. See how MOZILLA_IDLDIR points to unstablea above !!!


@@ -561,18 +587,24 @@
-       LIBS="$LIBS -L$MOZILLA_LIBDIR -lxpcom -lxpcomglue_s"
-       LDFLAGS="$LDFLAGS -Wl,--rpath -Wl,$MOZILLA_LIBDIR"
+       if test $MOZILLA_VERSION_MIN = 1.9; then
+               LDFLAGS="$LDFLAGS"
+        else 
+               LIBS="$LIBS -L$MOZILLA_LIBDIR -lxpcom -lxpcomglue_s"
+               LDFLAGS="$LDFLAGS -Wl,--rpath -Wl,$MOZILLA_LIBDIR"
+       fi
        AC_MSG_CHECKING([for libxpcomglue_s])
 #include <mozilla-config.h>
 #include <nsStringAPI.h>
 nsCString s;
 const char *t = s.get ();

     !!! Many configure files (or m4/*.m4 macros) try to compile a test program. Fixing the build env needs to be done
         case by case. Above you see how you can fix the AC_LINK_IFELSE in totem configure.in. !!!


@@ -583,17 +615,21 @@
        if test "$have_libxpcomglue_s" = "yes"; then
-               LIBXPCOMGLUE_S="-L$MOZILLA_LIBDIR -lxpcomglue_s"
+               if test $MOZILLA_VERSION_MIN = 1.9; then
+               else
+                       LIBXPCOMGLUE_S="-L$MOZILLA_LIBDIR -lxpcomglue_s"
+               fi
                AC_MSG_WARN([libxpcomglue_s not available; plugins may not be portable])
 # check for -fno-rtti flag

    !!! sometimes the configure even tries to use the dependent (standalone) glue. However, they mostly do it in a
        manual fashion, so better use the complete output of pkg-config --libs libxul(-embedding) which provides the
        right link options for the dependent (standalone) glue. Above the MOZILLA_NOT_LINKED_LIBS contains the
        complete pkg-config --libs libxul output.


@@ -615,17 +651,17 @@
 # check for some additional xpcom headers and for string compatibility
 if test "$enable_browser_plugins" = "yes"; then
        AC_MSG_CHECKING([whether we need string glue])
                                #include <mozilla-config.h>
                                #include <nsStringAPI.h>


XulrunnerGecko (last edited 2008-08-06 17:00:50 by localhost)