Introduction
The goal of this tutorial is to teach you how to package xulrunner applications for Ubuntu, using tools such as bzr, cdbs and quilt. This could be a difficult topic as each xulapp is different but we will go through the basics in order to bring the foundations on which you should be able to move forward.
We will work with fennec, the Mobile Browser from Mozilla.
Prerequisites
- a launchpad account
- the following packages: build-essential xulrunner-1.9-dev mozilla-devscripts cdbs debhelper devscripts autoconf2.13 pkg-config unzip quilt bzr bzr-builddeb mercurial libgtk2.0-dev libgnomevfs2-dev libdbus-glib-1-dev libxt-dev
FIXME: we need xulruner-1.9-dev (>= 1.9+nobinonly-0ubuntu3~)and mozilla-devscripts (>= 0.09~) from ~fta PPA for this to work. See https://edge.launchpad.net/~fta/+archive/ FIXME2: some of these packages are just needed to please configure (mostly lib* and pkg-config), we should think about patching configure to make those tests not fatal when using --with-libxul-sdk)
- a working dir to practice this tutorial
Before you package a xulrunner application
- check the license for main, universe suitability. Below a list of good licenses. for other licenses, ask on #ubuntu-mozillateam (freenode)
- MPL/GPL/LGPL - tri-license: this is the preferred license
- GPL
- LGPL
- MPL
- MIT
- 2 or 3-clause BSD
- mozilla-devscripts contains some cdbs hooks providing a Mozilla build system in sync with the current xulrunner. There are some prerequisites in order for those hooks to work correctly. This will be explained in the next section.
Packaging Procedure
- You need a source tarball containing the source tree from upstream. It could be a tar file, or a snapshot from a VCS.
The structure of the tarball we need to create the package is important. Everything must be contained into a toplevel directory with a precise name. What you get from upstream will have to be tweaked if the toplevel is either missing or wrong. Here is how, using our example.
fennec is the name of the application. It is maintained by upstream within a Mercurial (hg) tree. In that tree, the branch is called mobile-browser. Move to your working directory, then clone the branch:
hg clone http://hg.mozilla.org/mobile-browser
You now have a directory called mobile-browser. Look inside, there is a file called build.mk.
drwxr-xr-x 3 ubuntu ubuntu 4096 2008-06-21 00:47 app -rw-r--r-- 1 ubuntu ubuntu 2067 2008-06-21 00:47 build.mk <===== drwxr-xr-x 5 ubuntu ubuntu 4096 2008-06-21 00:47 chrome -rw-r--r-- 1 ubuntu ubuntu 1860 2008-06-21 00:47 confvars.sh drwxr-xr-x 3 ubuntu ubuntu 4096 2008-06-21 00:47 installer -rw-r--r-- 1 ubuntu ubuntu 1890 2008-06-21 00:47 Makefile.in -rw-r--r-- 1 ubuntu ubuntu 2176 2008-06-21 00:47 makefiles.sh
Inside this file, you see that installer is supposed to be in a directory called mobile.
... tier_app_dirs += \ mobile \ $(NULL) installer: @echo "Mobile doesn't have an installer yet." @exit 1 package: @$(MAKE) -C mobile/installer <============= here install:: @echo "Mobile can't be installed directly." <== for later: this is a bad sign @exit 1
Hint: remember that mobile name, you will need it later.
Rename mobile-browser into mobile
mv mobile-browser mobile
We also need the version of this application, it's somewhere into the sources. In our example, it's in confvars.sh
MOZ_APP_NAME=fennec MOZ_APP_DISPLAYNAME=Fennec MOZ_APP_VERSION=0.3 <======
Hint: the name fennec comes from here, i.e. MOZ_APP_NAME
We will continue with 0.3~hg in order to remember it's a snapshot (not a final release). We will also exclude VCS data from our tarball, here, it's .hg but also CVS (probably a left-over). Now, we have all we need to create the tarball:
mkdir fennec-0.3~hg mv mobile fennec-0.3~hg tar --exclude .hg --exclude CVS -zcvf fennec_0.3~hg.orig.tar.gz fennec-0.3~hg rm -rf fennec-0.3~hg
we are done with the tarball.
- We want to package our application inside a bzr branch and use bzr-builddeb to build it
For this, we need to create the structure:
mkdir tarballs mv fennec_0.3~hg.orig.tar.gz tarballs mkdir fennec.dev cd fennec.dev bzr init
- We now need the debian/ directory and a few files inside it.
The minimum set is changelog, compat, copyright, control and rules.
mkdir debian echo 5 > debian/compat dch --create --package fennec -v 0.3~hg "Initial release"
debian/copyright is important. Your package could be rejected if this file is not right.
FIXME: add guidelines for debian/copyright
For debian/control, we need some hints about what the package really needs, but also what the build-system expects. For now, use this:
Source: fennec Section: net Priority: optional Maintainer: your name <your@email.dom> Vcs-Bzr: https://code.launchpad.net/~your_lp_id/+junk/fennec.dev Build-Depends: debhelper (>= 5.0.51~), cdbs, autoconf2.13, pkg-config, libgtk2.0-dev (>= 2.10), libgnomevfs2-dev, libdbus-glib-1-dev (>= 0.60), libxt-dev, quilt, unzip, zip, sharutils, imagemagick, mozilla-devscripts (>= 0.09~), xulrunner-1.9-dev (>= 1.9+nobinonly-0ubuntu3~) Standards-Version: 3.7.3 Package: fennec Architecture: any Depends: fontconfig, psmisc, debianutils (>= 1.16), xulrunner-1.9 (>= 1.9), ${shlibs:Depends} Description: Mobile browser from Mozilla Mozilla Fennec
The last file is debian/rules. This is where the magic from cdbs and mozilla-devscripts kicks in.
# These are used for cross-compiling and for saving the configure script # from having to guess our platform (since we know it already) DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) DEBIAN_APP_NAME := fennec DEBIAN_XUL_VER := $(shell xulrunner-1.9 --gre-version) DEBIAN_XUL_DEV := /usr/lib/xulrunner-devel-$(DEBIAN_XUL_VER) DEB_AUTO_UPDATE_AUTOCONF=2.13 include /usr/share/cdbs/1/rules/patchsys-quilt.mk include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk include /usr/share/mozilla-devscripts/xulapp.mk DEB_CONFIGURE_USER_FLAGS= \ --with-libxul-sdk=$(DEBIAN_XUL_DEV) \ --enable-application=mobile \ --disable-debug \ --disable-crashreporter \ --with-distribution-id=com.ubuntu
See the --enable-application=mobile ? Remember I said that name will be useful later ? This is it.
From here, the package should already build. Let's try:
chmod 755 debian/rules bzr add debian bzr bd --merge --dont-purge
If it went well, you should have your debs inside ../build-area.
If it failed like this:
dpkg-checkbuilddeps: Unmet build dependencies: libx11-dev x y z dpkg-buildpackage: warning: Build dependencies/conflicts unsatisfied; aborting. dpkg-buildpackage: warning: (Use -d flag to override.) bzr: ERROR: The build failed.
you have to install the necessary build-deps. Hint: apt-get build-dep xulrunner-1.9 should do the trick in one shot, otherwise, apt-get install libx11-dev x y z will sure do.
You can retry with just:
bzr bd --merge --dont-purge
Our example builds fine but fails at the install stage. I said earlier there was a bad sign, here it is.
/usr/bin/make -C . install DESTDIR=/tmp/foo/build-area/fennec-0.3~hg/debian/fennec/ make[1]: Entering directory `/tmp/foo/build-area/fennec-0.3~hg' Mobile can't be installed directly. <============= make[1]: *** [install] Error 1 make[1]: Leaving directory `/tmp/foo/build-area/fennec-0.3~hg' make: *** [common-install-impl] Error 2 dpkg-buildpackage: failure: fakeroot debian/rules binary gave error exit status 2 bzr: ERROR: The build failed.
FIXME: This is real life packaging pain.. I don't see how I can explain how to fix this in simpler terms.. especially now that quilt cdbs hooks are no longer installing the symlink.. anyway..
Let's create our first patch, using quilt:
cd ../build-area/fennec-0.3~hg mkdir debian/patches export QUILT_PATCHES=`pwd`/debian/patches quilt new fix_installer.patch quilt add mobile/build.mk
now edit mobile/build.mk to:
1. add this just after the license block:
ifndef LIBXUL_SDK include $(topsrcdir)/toolkit/toolkit-tiers.mk endif
2. replace the install:: rules by this:
install:: @$(MAKE) -C mobile/installer install
hint: it's a tab before the @$(MAKE), not spaces
then:
quilt diff
should show:
Index: fennec-0.3~hg/mobile/build.mk =================================================================== --- fennec-0.3~hg.orig/mobile/build.mk +++ fennec-0.3~hg/mobile/build.mk @@ -35,6 +35,10 @@ # # ***** END LICENSE BLOCK ***** +ifndef LIBXUL_SDK +include $(topsrcdir)/toolkit/toolkit-tiers.mk +endif + TIERS += app ifdef MOZ_EXTENSIONS @@ -53,8 +57,7 @@ @$(MAKE) -C mobile/installer install:: - @echo "Mobile can't be installed directly." - @exit 1 + @$(MAKE) -C mobile/installer install ifeq ($(OS_TARGET),Linux) deb: package
if it's okay, commit the patch:
quilt refresh
FIXME: This patch should be sent upstream
Here we can rebuild the package with:
dpkg-buildpackage
if it's fine, it ends like this:
dh_builddeb -pfennec dpkg-deb: building package `fennec' in `../fennec_0.3~hg_i386.deb'. dpkg-genchanges -b >../fennec_0.3~hg_i386.changes dpkg-genchanges: warning: duplicate files list entry for file fennec_0.3~hg_i386.deb (line 2) dpkg-genchanges: binary-only upload - not including any source code signfile fennec_0.3~hg_i386.changes dpkg-buildpackage: binary only upload (no source included)
Do not forget to migrate your patch back to the bzr branch:
mkdir ../../fennec.dev/debian/patches cp debian/patches/* ../../fennec.dev/debian/patches/ cd ../../fennec.dev/ bzr add bzr st
the last line should show this:
added: debian/ debian/changelog debian/compat debian/control debian/copyright debian/patches/ debian/patches/fix_installer.patch debian/patches/series debian/rules
It's time to commit your first revision to your bzr branch and push it to launchpad:
bzr commit -m "* Initial revision" bzr push bzr+ssh://your_lp_id@bazaar.launchpad.net/~your_lp_id/+junk/fennec.dev
Now, you have the foundations to start a project on your own. Please give it a try, and come visit us at #ubuntu-mozillateam on freenode to let us know your feedbacks about this tutorial.
Note: at this stage, the deb contains a full copy of xulrunner. This is not really needed in Ubuntu. If you want to fix this, you could borrow the patch from prism: http://bazaar.launchpad.net/~mozillateam/prism/prism/annotate/head:/debian/patches/installer_shouldnt_copy_xulrunner.patch
Enjoy.