18 October 2010

Package Builds in FreeBSD

This document details how to create a package on FreeBSD.  Only the
creation of a simple package is detailed in this doc.  For more elaborate
packages, see the relevant man pages.

The following assumptions are being made regarding the package build
described herein:

        - the program, etc, has already been installed on the host
          the package is to be built upon
                - program version is 4.17 (for illustrative purposes)

        - for simplicity, the program, yourProg, and its relevant files
          are installed under /usr/local

        - you have root on the host (hostA) that the package is going
          to be created on

        - hostA's root shell prompt is:

                hostA [0]

        - the package that you are creating belongs to an appropriate
          directory under /usr/ports, such as misc (used in this doc)

        - your host platform is FreeBSD 7.0, x86 (used only for example;
          this document has been used for FreeBSD 4.8 through 7.0)

After the yourProg has been installed on hostA, cd into /var/db/pkg and
create a package directory.

        hostA [0] cd /var/db/pkg
        hostA [0] /bin/mkdir yourProg-4.17
        hostA [0] cd yourProg-4.17

It is now necessary to create a few files to be used in the package
creation process.  The first is +COMMENT, which contains a brief
description of the package to be displayed in the output of pkg_info's
listing of packages.  (This should typically be a single line.)  So with
your favorite text editor (vi), create +COMMENT:

        hostA [0] /usr/bin/vi -- +COMMENT

The secondary parameter to vi, '--', is to tell vi that +COMMENT is meant
to be the file to work against, not a parameter to vi.  An example of
+COMMENT's contents would be:

        yourProg - some single line description of yourProg.

The next file to create is +CONTENTS.  This file effectively tells
FreeBSD package system how to handle the file, as in what directories
to create / remove, what files go where, checksums of the files in
question, etc.  An easy way to create a good portion of this file is to
have the particular files that are to be installed listed within a file,
/tmp/content.input.  This file would contain the following (relative to
the base directory (/usr/local)):

        share/doc/yourProg-4.17/AUTHORS
        share/doc/yourProg-4.17/COPYING
        share/doc/yourProg-4.17/ChangeLog
        share/doc/yourProg-4.17/README
        share/doc/yourProg-4.17/yourProg.conf
        share/doc/yourProg-4.17/yourProg.details
        etc/yourProg.conf
        bin/yourProg
        man/man1/yourProg.1

Since this file requires MD5 checksums of the various files to create,
either cd into /usr/local, the basedir where yourProg is installed,
or you'll need to do some editing after the fact.  This doc assumes
that you've temporarily cd'd into /usr/local.  To create the bulk of
the +CONTENTS file, a simple 'for' loop can be used, redircting the
output to /var/db/pkg/yourProg-4.17/+CONTENTS:

        hostA [0] pwd
        /usr/local
        hostA [0] for i in `/bin/cat /tmp/content.input` ; do
                                  a=`/usr/bin/openssl md5 ${i} | /usr/bin/awk '{print $2}'` ;
                                  echo "${i}\n@comment MD5:${a}" ;
                       done >> /var/db/pkg/yourProg-4.17/+CONTENTS

Your +CONTENTS file should now contain the following:

        share/doc/yourProg-4.17/AUTHORS
        @comment MD5:d86048753af9455c097dfd291e69b78a
        share/doc/yourProg-4.17/COPYING
        @comment MD5:5c262c13b60ebefe3060aed37d334ab6
        share/doc/yourProg-4.17/ChangeLog
        @comment MD5:8c4520c50f5fad805313c388f498c000
        share/doc/yourProg-4.17/README
        @comment MD5:c8f9993fe17411a5ff1f1381d27a9c7d
        share/doc/yourProg-4.17/yourProg.conf
        @comment MD5:c77ab047e3179da123694576715c2bb7
        share/doc/yourProg-4.17/yourProg.conf.complex
        @comment MD5:5958643c2bd5048436b322da820538cb
        share/doc/yourProg-4.17/yourProg.pam
        @comment MD5:4e7ad4ec8f2fe6a40e12bcb2c0b256e3
        etc/yourProg.conf
        @comment MD5:dbed0f81dcb09f64bb79c3dfe41003c6
        bin/yourProg
        @comment MD5:8575c862996572cc7d18ac03a61261c1
        man/man1/yourProg.1
        @comment MD5:8010c538ae035348055aa76ecde91edd

Change directory back to /var/db/pkg/yourProg-4.17, and open +CONTENTS
with your favorite text editor.  Above the current contents of the
+CONTENTS file, add in the following:

        @comment PKG_FORMAT_REVISION:1.1
        @name yourProg-4.17
        @comment ORIGIN:misc/yourProg
        @cwd /usr/local

Following the original MD5 checksums in +CONTENTS, add the following line:

        @dirrm share/doc/yourProg-4.17

(The above directory removal is due to it being specific to youProg,
whereas the other directories are generic to the system.)  At this point,
your +CONTENTS file should appear similar to:

        @comment PKG_FORMAT_REVISION:1.1
        @name yourProg-4.17
        @comment ORIGIN:misc/yourProg
        @cwd /usr/local
        share/doc/yourProg-4.17/AUTHORS
        @comment MD5:d86048753af9455c097dfd291e69b78a
        share/doc/yourProg-4.17/COPYING
        @comment MD5:5c262c13b60ebefe3060aed37d334ab6
        share/doc/yourProg-4.17/ChangeLog
        @comment MD5:8c4520c50f5fad805313c388f498c000
        share/doc/yourProg-4.17/README
        @comment MD5:c8f9993fe17411a5ff1f1381d27a9c7d
        share/doc/yourProg-4.17/yourProg.conf
        @comment MD5:c77ab047e3179da123694576715c2bb7
        share/doc/yourProg-4.17/yourProg.details
        @comment MD5:4e7ad4ec8f2fe6a40e12bcb2c0b256e3
        share/doc/yourProg-4.17/yourProg.paper
        @comment MD5:fb8a0d127d67e57184dc34949d39e42d
        etc/yourProg.conf
        @comment MD5:dbed0f81dcb09f64bb79c3dfe41003c6
        bin/yourProg
        @comment MD5:8575c862996572cc7d18ac03a61261c1
        man/man1/yourProg.1
        @comment MD5:8010c538ae035348055aa76ecde91edd
        @dirrm share/doc/yourProg-4.17

Write the +CONTENTS file and create the description file.  This file
can be a multiline statement giving more descriptive information about
yourProg.  A sample of +DESC would be:

        some description of yourProg, allows multiple lines;
        displayed when using 'pkg_info -d yourProg-4.17'

        WWW: http://some.site.tld/download/yourProg-4.17.tar.gz

The last file to create can actually be reused from another package.
The +MTREE_DIRS file basically contains a generic directory tree that
can be used which helps to setup directories and their permission and
ownership.  Typically, since m4 is installed, one can simply use its file,
so copy it into yourProg-4.17's directory:

        hostA [0] pwd
        /var/db/pkg/yourProg-4.17
        hostA [0] /bin/cp ../m4-1.1.4/+MTREE_DIRS .

The final thing to do is create the package, suitable for use by pkg_add:

        hostA [0] /usr/sbin/pkg_create -v -c +COMMENT -d +DESC -f +CONTENTS -m +MTREE_DIRS /tmp/yourProg-4.17-bsd7-x86.tgz

Once created, the new package can be installed onto a host via:

        hostA [0] /usr/sbin/pkg_add /tmp/yourProg-4.17-bsd7-x86.tgz

For further references, please see the following:

        pkg_info(1)     pkg_create(1)   cat(1)
        openssl(1)      vi(1)         
        http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/