# Debian OCaml Packaging Reference

###

The Debian OCaml Task Force

`<debian-ocaml-maint@lists.debian.org>`

Revision 0.8.0

Copyright © 2002-2015 Mehdi Dogguy, Stephane Glondu, Sylvain Le Gall, Sven Luther, Samuel Mimram, Ralf Treinen, Stefano Zacchiroli

This manual is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

A copy of the GNU General Public License is available as `/usr/share/common-licenses/GPL-3` on Debian GNU/Linux systems or on the World Wide Web at The GNU Public Licence.

List of Examples

2.1. A `debian/rules` file using dh
3.1. Usage example of the Vcs-* fields, from the findlib package

# Chapter 1. Common use-cases

Build checklist

Build without ocamlopt

Howto install using ocamlfind

dh-ocaml stuff: howto use, what he can guess

need to depend on -dev package outside ocaml package

# Chapter 2. Build systems

## Building packages with debhelper tools and dh-ocaml

The availability of the native compiler can be tested in the `debian/rules` file by testing the possibility of executing `/usr/bin/ocamlopt`, and build the bytecode version or the native version of the program according to the result of the test. This is a sample snippet of `debian/rules` doing so:

              build-stamp:
                      dh_testdir

                      if [ -x /usr/bin/ocamlopt ]; then \
                              $(MAKE) opt; \
                      else \
                              $(MAKE) all; \
                      fi

The following is a snippet of a sample `debian/control`:

              Package: spamoracle-byte
              Architecture: all
              Depends: ocaml-base-${F:OCamlABI}
              Provides: spamoracle
              Conflicts: spamoracle
              Replaces: spamoracle

The following its pairing `debian/rules` snippet:

              OCAMLABI := $(shell ocamlc -version)
              ...
              binary-indep: build install
              dh_gencontrol -i -- -VF:OCamlABI="$(OCAMLABI)"

In the case where there is only one package, which provides either a native version where available or a bytecode version otherwise, the dependency on `ocaml-base-[ocaml-version]` should be added only when the package is built in native mode. For example, the `debian/control` of `approx` contains:

              Package: approx
              Architecture: any
              Depends: ${shlibs:Depends}, ${F:OCamlRun}, adduser, bzip2, curl

and the corresponding `debian/rules` contains:

              OCAMLABI = $(shell ocamlc -version)
              BYTECODE = $(shell [ -x /usr/bin/ocamlopt ] || echo yes)
              OCAMLRUN = $(if $(BYTECODE),ocaml-base-$(OCAMLABI))
              ...
              binary-arch:
                      ...
                      dh_gencontrol -- -VF:OCamlRun="$(OCAMLRUN)"

TODO: section should be simlified by using dh-ocaml

## Building packages with dh (debhelper > 7)

Debhelper provides since version 7 the dh tool which automatizes in simply and standard cases completely the tasks to be done by `debian/rules`, and which provides for various means to adapt to complex or non-standard cases (see dh(1)). The dh-ocaml package provides since version 0.9.0 a ocaml addon to dh.

Example 2.1. A `debian/rules` file using dh

    #!/usr/bin/make -f
    %:
            dh $@ --with ocaml

This package must build-depend on `dh-ocaml (>= 0.9.0)`.

# Chapter 3. Using a Version Control System

## Using Git for packaging

This section is still under construction!

(Hopefully) All OCaml-related Debian packages are maintained using centralized Git repositories. This practice reduce the efforts needed to contribute work inside The Debian OCaml Task Force and, in case of need, provides a place where to massively perform changes to all OCaml-related Debian packages.

In the past, we were using Subversion, but we are progressively migrating our packages to Git.

Debian users can benefit knowing we are using a Git repository (they can for instance subscribe to the RSS feed for changes or have a place where to look for finding patches corresponding to bugs tagged "pending" in the BTS).

For this reason it is recommended to add the `Vcs-Git` and `Vcs-Browser` fields to the `debian/control` of packages maintained in The Debian OCaml Task Force Git repository. Its name specifies that we are using Git as our Version Control System (VCS); their values are the URLs pointing to the package's repository and to a browsable view of the same directory. See the Debian Developer's Reference for more information about these fields.

The general scheme for using the fields are thus:

      Vcs-Git: git://git.debian.org/git/pkg-ocaml-maint/packages/PACKAGE_NAME.git
        Vcs-Browser: http://git.debian.org/?p=pkg-ocaml-maint/packages/PACKAGE_NAME.git

Example 3.1. Usage example of the Vcs-* fields, from the findlib package

      Source: findlib
        Section: devel
        Priority: optional
        Maintainer: Debian OCaml Maintainers <debian-ocaml-maint@lists.debian.org>
        Uploaders: Stefano Zacchiroli <zack@debian.org>
        Build-Depends: debhelper (>> 5.0.0), ocaml (>= 3.11.0), camlp4 (>= 3.11.0), m4, gawk | awk, dh-ocaml
        Standards-Version: 3.8.0
        Vcs-Git: git://git.debian.org/git/pkg-ocaml-maint/packages/findlib.git
        Vcs-Browser: http://git.debian.org/?p=pkg-ocaml-maint/packages/findlib.git
        Homepage: http://projects.camlcity.org/projects/findlib.html

        Package: ocaml-findlib
        Section: devel
        Architecture: any
        Depends: ocaml-${F:OCamlABI}, ${shlibs:Depends}, ${misc:Depends}
        Description: Management tool for OCaml programming language libraries
        ...

This document assumes that you have the following packages installed: `git-buildpackage` and `pristine-tar`.

### How to obtain a copy of a package's Git repository

There is one Git repository per package. To get the list of packages managed with git, you can use the following command (your ssh must be configured properly):

      ssh git.debian.org ls /git/pkg-ocaml-maint/packages

You can obtain a copy of the repository for a package with:

      checkout-d-o-m-git-repo package

The checkout-d-o-m-git-repos script is available in the Subversion repository. You can get a copy with:

      svn co svn://svn.debian.org/svn/pkg-ocaml-maint/trunk/projects/git-guide

You must be member of the Debian OCaml Task Force in order to have the right to push to the central repository.

### Structure of a Git repository

We keep all upstream sources under Git control, in a branch called upstream. This branch usually consists of successive unpacked upstream tarballs. When importing a new upstream tarball, the following command should be used:

      git-import-orig --pristine-tar [--no-dch] <name_version.orig.tar.gz>

The `--pristine-tar` is mandatory to store information for reconstructing the upstream tarball from the repository. That information is not suited for human use and is stored in the pristine-tar branch. Optionally, `--no-dch` can be given to automatically update the Debian changelog (without committing it).

The master branch contains upstream sources along with the `debian/` directory. `git-import-orig` automatically creates a (local) tag in the upstream branch, and merges upstream into master when importing a new tarball. Changes related to Debian should be done in this branch.

### How to add a new package

Let's take dose2 as an example. The following command (the new-d-o-m-git-repo is available at the same location of checkout-d-o-m-git-repo):

      new-d-o-m-git-repo dose2 /some/where/dose2-1.2.tar.gz

will create the remote repository on Alioth, set up notifications, and inject the given tarball in the repository in the upstream branch (using `pristine-tar`). More details there. You can then check it out and start using it.

If the tarball name is missing, new-d-o-m-git-repo will check that the current directory is a git repository, and then push it to Alioth. This allows you to create the repository locally, work on it, and only push it when it is in good shape. It is recommended to check it out after, and use the checked out version, to make sure everything went well, and to have local branches tracking remote ones.

### How to set up your package for use with git-buildpackage

Put the following in `debian/gbp.conf`:

      # Configuration file for git-buildpackage and friends

        [DEFAULT]
        # the default branch for upstream sources:
        upstream-branch = upstream
        # the default branch for the debian patch:
        debian-branch = master
        # use pristine-tar:
        pristine-tar = True

The first two settings are not really useful since they are the defaults, but it might be handy to have them around when working with several branches. The `pristine-tar` is necessary if tarballs are imported. Please see the git-buildpackage documentation for complete information.

If you tried git-buildpackage before writing your `debian/gbp.conf`, remember to delete the `.orig` tarball, and rebuild after writing `debian/gbp.conf`. Alternatively, you can invoke git-buildpackage with the `--git-pristine-tar` option.

### How to build a package with git-buildpackage

Please refer to the git-builpackage documentation for more complete information. Here is just a quick guide.

All options, except those starting on `--git`, are passed to dpkg-buildpackage. Hence, basic usage should be something like this (from the root of the repository): git-buildpackage -rfakeroot -uc -us. The package will be built in place, and the result will be put in the parent directory.

git-buildpackage will complain when your repository is not clean. You may use the option `--git-ignore-new` to override this behaviour.

If your package is ready for upload you may use the `--git-tag` option for the final build. This will create a tag in your local repository. Provided you have commited all your changes to the Git repository, this will after a successful build of the package create a tag for the current version.

### Tip

Tags created by git-import-orig and git-buildpackage are not automatically pushed, you have to push them explicitly with the following command: git push --tags. Be careful if you use local tags!

You can add the --dry-run option to git push to see what will be done.

To build with pbuilder (or cowbuilder), use the following:

      git-buildpackage \
          --git-builder="pdebuild --debbuildopts '-I.git -i\.git -uc -us'" \
          --git-cleaner="fakeroot debian/rules clean"

### Patches

We have not yet decided on how to deal with patches in upstream (this topic is under discussion). Possibilities include direct commits in the master branch, use of TopGit and quilt-serialized patches, and raw quilt or dpatch.

#### Quilt-serialized patches

Patches can be serialized using Git. Two tools are used to apply and save the patches in debian/patches/series.

- dom-apply-patches: Creates the branch patch-queue and checkout it. Then, it applies all patches listed in debian/patches/series.

- dom-save-patches:

  - Move back to branch master

  - Save all patches present in branch patch-queue (where each commit represents a patch to upstream) in debian/patches/

  - Update debian/patches/series

  - Remove branch patch-queue

The branch patch-queue is used only locally and should never be pushed.

# Chapter 4. Transitions to new OCaml upstream versions

TODO

# Appendix A. The Debian OCaml Task Force resources

- The Debian OCaml Task Force's website: http://pkg-ocaml-maint.alioth.debian.org/ (it's an Alioth project)

- The Debian OCaml Task Force's mailing list: debian-ocaml-maint@lists.debian.org ( archives)

- The Debian OCaml Task Force wiki page http://wiki.debian.org/Teams/OCamlTaskForce/