Packaging

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.


CategoryMozillaTeam

MozillaTeam/XulApps/Packaging (last edited 2008-08-06 17:00:29 by localhost)