Clone this wiki locally
- Create Package Directory
- Create Initial Package Files
- Create buildlink3.mk
- Further Information
This tutorial will use augeas as an example of how to package a new piece of software, as it happens to be a package that was requested at time of writing, and is relatively straight-forward.
Some packages are simpler than this, and many are significantly more complicated. This guide only explains the basic process. For more challenging packages, have a look at some of the larger packages already in pkgsrc for ideas and consult the pkgsrc guide for further details.
This guide assumed that you have followed the
setup document and are logged into an
First, install the
pkgtools/url2pkg package, as this massively simplifies the
task in hand.
: If you have binary packages available.. # pkg_add url2pkg : ..else build from source # (cd pkgtools/url2pkg; bmake install)
Create Package Directory
Next, create a new package directory, choosing the most appropriate category (in
devel), then run
url2pkg giving it an argument of the source
$ mkdir devel/augeas $ cd devel/augeas $ url2pkg http://download.augeas.net/augeas-1.0.0.tar.gz
Create Initial Package Files
First it will open an editor session on
Makefile. You should customise a few
MAINTAINEReither to your email address, or to
pkgsrc-users@NetBSD.orgif you do not want to be the primary maintainer of the package.
Write a brief one-line
COMMENTdescribing what the package is.
LICENSEto a list of the licenses the package is made available under (see
mk/license.mkfor an available list).
Here is what was used for augeas:
# $NetBSD$ DISTNAME= augeas-1.0.0 CATEGORIES= devel MASTER_SITES= http://download.augeas.net/ MAINTAINER= pkgsrc-users@NetBSD.org HOMEPAGE= http://download.augeas.net/ COMMENT= Configuration file editing tool and library LICENSE= gnu-lgpl-v2 # url2pkg-marker (please do not remove this line.) .include "../../mk/bsd.pkg.mk"
After writing the file and exiting the editor session,
url2pkg will continue
and download the source tarball, create the
files, then unpack the source ready for you to start applying patches.
At this point you should edit
DESCR and put in a few lines which describe the
The general cycle will then be:
Try building the package with
If something goes wrong, modify the
Makefileor patch the source with
until the package builds. Before running your first
bmake, I would strongly
PKG_DEVELOPER=yes to your
mk.conf to turn on a lot of
augeas, a couple of things were needed.
The first problem hit was:
$ bmake [...] => Checking for portability problems in extracted files ERROR: [check-portability.awk] => Found test ... == ...: ERROR: [check-portability.awk] configure: test "`uname`" == "SunOS" && \ Explanation: =========================================================================== The "test" command, as well as the "[" command, are not required to know the "==" operator. Only a few implementations like bash and some versions of ksh support it. When you run "test foo == foo" on a platform that does not support the "==" operator, the result will be "false" instead of "true". This can lead to unexpected behavior. There are two ways to fix this error message. If the file that contains the "test ==" is needed for building the package, you should create a patch for it, replacing the "==" operator with "=". If the file is not needed, add its name to the CHECK_PORTABILITY_SKIP variable in the package Makefile. ===========================================================================
In this case pkgsrc gives us a very helpful message telling us about the
problem and what needs to be done to fix it (unfortunately not all problems are
handled this well!). As
configure is pretty important, we'll need to patch
This is the usual way of handling patches (ensuring
: Use the 'cdwrk' alias to cd into the WRKSRC area. # cdwrk : Edit the file in question using the pkgvi wrapper. # pkgvi configure : Return to the pkgsrc directory and test the patch. # cd - # bmake : Once the package builds successfully, use mkpatches to generate patches of : your changes. 'bmake mps' updates the 'distinfo' checksum file, and the : 'mkpatches -c' performs a cleanup. # mkpatches; bmake mps; mkpatches -c
This was enough to fix the
Dependencies in pkgsrc are primarily handled in two ways, either with a
buildlink file when depending upon shared libraries or particular
infrastructure, or a simple
DEPENDS line to pull in a required package.
The first dependency problem was:
[...] checking readline/readline.h usability... no checking readline/readline.h presence... no checking for readline/readline.h... no checking for readline in -lreadline... no checking for library containing tgetent... -lcurses checking for rl_initialize in -lreadline... no configure: WARNING: readline library not found configure: error: Could not find a working readline library (see config.log for details). *** Error code 1
Ok, so this package depends upon readline. As that is a library, we are
looking for a suitable
buildlink3.mk file, and one of the easiest ways to do
$ ls -1d ../../*/*readline*/buildlink3.mk ../../devel/readline/buildlink3.mk
To use that file, all we need to do is add an
.include line at the bottom of
Makefile, just above the
.include "../../devel/readline/buildlink3.mk" .include "../../mk/bsd.pkg.mk"
bmake clean; bmake to try again. It is necessary to perform a
clean build to ensure the dependencies are pulled in correctly.
The next problem was:
[...] checking for LIBXML... no configure: error: Package requirements (libxml-2.0) were not met: No package 'libxml-2.0' found
Ok, so similar method:
$ ls -1d ../../*/*libxml*/buildlink3.mk ../../textproc/libxml++/buildlink3.mk ../../textproc/libxml++1/buildlink3.mk ../../textproc/libxml/buildlink3.mk ../../textproc/libxml2/buildlink3.mk ../../textproc/py-libxml2/buildlink3.mk
configure message said libxml-2.0, so we'll pick
you want to be more thorough you can look at the
PLIST files for each of the
possible candidate packages - experience often comes into play here.
The bottom of
Makefile now looks like this:
.include "../../devel/readline/buildlink3.mk" .include "../../textproc/libxml2/buildlink3.mk" .include "../../mk/bsd.pkg.mk"
You'll note that we try to keep all includes other than
bsd.pkg.mk (which is
special) sorted alphabetically.
After this, the package finally completes a
bmake with no problems. The
final step is to get the
install phase working.
First we need to run a
stage-install which will execute
make install into a
$ bmake stage-install
This will almost certainly fail as we haven't configured the
PLIST yet, so
pkgsrc has no idea what will be installed from this package.
[...] => Automatic manual page handling => Generating post-install file lists => Checking file-check results for augeas-1.0.0 ERROR: ************************************************************ ERROR: The following files are in /home/pbulk/build/devel/augeas/work/.destdir/opt/pkg but not in the PLIST: ERROR: /home/pbulk/build/devel/augeas/work/.destdir/opt/pkg/bin/augparse ERROR: /home/pbulk/build/devel/augeas/work/.destdir/opt/pkg/bin/augtool [...]
However, now that we have a populated
DESTDIR, we can use the
target to generate it for us:
$ bmake print-PLIST >PLIST
Finally, it's worth doing a full clean and install to ensure everything works as expected.
$ bmake clean $ bmake install [...] => Creating binary package /home/pbulk/build/devel/augeas/work/.packages/augeas-1.0.0.tgz ===> Install binary package of augeas-1.0.0
As we are installing a library package, we should provide a
file of our own so that other packages can depend on us correctly. Again,
there is a package that can help with this -
$ createbuildlink >buildlink3.mk
This will create a template file but you should read and edit, removing the
lines marked with
XXX and making any changes they recommend.
Once we have a working package it's worth doing a couple of checks to make sure everything looks ok:
: Check the package listing looks ok $ pkg_info -L augeas : View the included DESCR and homepage $ pkg_info -d augeas : Check what the package lists as its dependencies $ pkg_info -N augeas
We also should run
pkgtools/pkglint) which will perform some
sanity checks on our infrastructure files prior to us importing the package
into pkgsrc itself. In my case it pointed out some possible issues:
$ pkglint WARN: PLIST:8: Packages that install libtool libraries should define USE_LIBTOOL. WARN: PLIST:9: Packages that install libtool libraries should define USE_LIBTOOL. ERROR: patches/patch-configure:3: Comment expected. 1 errors and 2 warnings found. (Use -e for more details.)
For the first issue, add
Makefile which will ensure that
the pkgsrc libtool is used (has better support for cross-platform issues), and
for the second, add a comment at the top of the file explaining what it is for,
After making those changes, everything looks great:
$ pkglint looks fine.
The final - and sometimes most challenging - part is to get your shiny new package integrated into pkgsrc. There are a few options:
Find a NetBSD developer who can review your package and put it straight into pkgsrc.
Get a pkgsrc-wip account and work on your package there, before getting it reviewed and integrated.
If it's somewhat niche just publish it up on GitHub or similar for people to use, in a similar way to what we do with pkgsrc-joyent
This post only scratches the surface of adding a new package. pkgsrc provides a huge amount of infrastructure to help get packages working on multiple platforms, and there are lots of options available.
Certain parts of the infrastructure, like buildlink, are very complicated, and for more in-depth information you should refer to the pkgsrc guide.
The best way is often just to look at other packages to see what they do and re-use useful bits you find. With 17,000+ packages there is almost certainly another package which does something similar to what you need!