||<>|| == 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 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. {{{ #!/usr/bin/make -f # 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. ---- [[CategoryMozillaTeam]]