Post

pkgsrc (1/6)

pkgsrc (1/6)

This post is an automatic translation from French. You can read the original version here.

A great tool presented by Imil this Saturday, so I hope my notes will live up to the occasion! Today’s topic is the pkgsrc package management system, aka “Package source”. Closely tied to NetBSD, this package management system is fully cross-platform (Yes indeed, even on Windows or Mac!)

For those unfamiliar, a package allows distributing software in a standardized way across multiple machines. Basically, it is a tool that will not only install the piece of software you need, but also the other components (man pages, config files, etc.) and perform the necessary ancillary tasks (permission management, creation of a dedicated user, for example…). In short, packages exist so you don’t have to do artisanal installations, and can therefore manage all your machines in a strictly uniform way. You probably use one on your system: apt, yum or portage… It depends on your preferences (I’m not prejudiced, I have a friend who uses the Windows package manager T.T).

However, in 1994, FreeBSD introduced ports, a source-based package system that allows everyone to install applications by recompiling them on their platform rather than fetching a pre-compiled binary. The idea was good, the NetBSD folks forked it and turned it into a universal (i.e., multi-OS) system: pkgsrc was born!

First contact with pkgsrc

While pkgsrc is particularly associated with the NetBSD world, it works perfectly on other operating systems. That is actually its strong point, apparently. So I will see, as I type these notes, how to use it on Linux.

Installation (bootstrap, on Linux)

On NetBSD, the directory tree associated with pkgsrc is located in /usr/pkgsrc. This is normal, as it is the native system for that distribution. On Linux, you can place it wherever you want as long as it doesn’t interfere with the existing package system.

To keep things simple, I will do a “bootstrap” installation, meaning in my home directory and without using root privileges.

Instead of installing into /usr/pkgsrc, pkgsrc will be in /home/rancune/pkgsrc:

$cd ~
$env CVS_RSH=ssh cvs -d anoncvs@anoncvs.NetBSD.org:/cvsroot checkout -P pkgsrc

Yes, it uses CVS… If you don’t have it, you will need to install it or use git instead (github.com/NetBSD/pkgsrc)

Lines scroll by (while CVS does its job), and you end up with a nice pkgsrc directory of 1.2G (For a package system, that’s not too big!)

Here are its contents:

$cd pkgsrc

$ls
total 912
drwxr-xr-x  157 rancune rancune   4096 24 avril 15:34 archivers
drwxr-xr-x  529 rancune rancune  20480 24 avril 15:34 audio
drwxr-xr-x   56 rancune rancune   4096 24 avril 15:34 benchmarks
drwxr-xr-x   76 rancune rancune   4096 24 avril 15:34 biology
drwxr-xr-x    3 rancune rancune   4096 24 avril 15:34 bootstrap
drwxr-xr-x   75 rancune rancune   4096 24 avril 15:34 cad
drwxr-xr-x  156 rancune rancune  12288 24 avril 15:34 chat
drwxr-xr-x   95 rancune rancune   4096 24 avril 15:34 comms
drwxr-xr-x  161 rancune rancune   4096 24 avril 15:34 converters
drwxr-xr-x   83 rancune rancune   4096 24 avril 15:34 cross
drwxr-xr-x    2 rancune rancune   4096 24 avril 15:28 CVS
drwxr-xr-x  534 rancune rancune  36864 24 avril 15:34 databases
drwxr-xr-x 3309 rancune rancune 135168 24 avril 15:34 devel
drwxr-xr-x    3 rancune rancune   4096 24 avril 15:30 distfiles
drwxr-xr-x    4 rancune rancune   4096 24 avril 15:34 doc
drwxr-xr-x  192 rancune rancune   4096 24 avril 15:34 editors
drwxr-xr-x  417 rancune rancune  20480 24 avril 15:34 emulators
drwxr-xr-x   50 rancune rancune   4096 24 avril 15:34 filesystems
drwxr-xr-x  121 rancune rancune   4096 24 avril 15:34 finance
drwxr-xr-x  891 rancune rancune  36864 24 avril 15:34 fonts
drwxr-xr-x  483 rancune rancune  20480 24 avril 15:34 games
drwxr-xr-x  114 rancune rancune   4096 24 avril 15:34 geography
drwxr-xr-x  850 rancune rancune  36864 24 avril 15:34 graphics
drwxr-xr-x   59 rancune rancune   4096 24 avril 15:34 ham
drwxr-xr-x  170 rancune rancune  12288 24 avril 15:34 inputmethod
drwxr-xr-x  334 rancune rancune  20480 24 avril 15:34 lang
drwxr-xr-x    3 rancune rancune  12288 24 avril 15:31 licenses
drwxr-xr-x  410 rancune rancune  20480 24 avril 15:34 mail
-rw-r--r--    1 rancune rancune   1965 12 févr.  2020 Makefile
drwxr-xr-x  491 rancune rancune  20480 24 avril 15:34 math
drwxr-xr-x   15 rancune rancune   4096 24 avril 15:34 mbone
drwxr-xr-x  104 rancune rancune  12288 24 avril 15:34 meta-pkgs
drwxr-xr-x  405 rancune rancune  20480 24 avril 15:34 misc
drwxr-xr-x   34 rancune rancune   4096 24 avril 15:34 mk
drwxr-xr-x  223 rancune rancune  12288 24 avril 15:34 multimedia
drwxr-xr-x 1041 rancune rancune  36864 24 avril 15:34 net
-rwxr-xr-x    1 rancune rancune   9382 29 déc.   2020 _NetBSD-pkgdb
drwxr-xr-x   30 rancune rancune   4096 24 avril 15:34 news
drwxr-xr-x    3 rancune rancune   4096 24 avril 15:32 packages
drwxr-xr-x   33 rancune rancune   4096 24 avril 15:34 parallel
-rwxr-xr-x    1 rancune rancune   2963 22 août   2018 pkglocate
drwxr-xr-x   79 rancune rancune   4096 24 avril 15:34 pkgtools
drwxr-xr-x 1776 rancune rancune  69632 24 avril 15:34 print
-rw-r--r--    1 rancune rancune   2893 31 janv. 23:39 README.md
drwxr-xr-x   26 rancune rancune   4096 24 avril 15:34 regress
drwxr-xr-x  661 rancune rancune  36864 24 avril 15:34 security
drwxr-xr-x   46 rancune rancune   4096 24 avril 15:34 shells
drwxr-xr-x  922 rancune rancune  36864 24 avril 15:34 sysutils
drwxr-xr-x    3 rancune rancune   4096 24 avril 15:33 templates
drwxr-xr-x 1386 rancune rancune  53248 24 avril 15:34 textproc
drwxr-xr-x  268 rancune rancune  12288 24 avril 15:34 time
drwxr-xr-x  116 rancune rancune   4096 24 avril 15:34 wm
drwxr-xr-x 1082 rancune rancune  69632 24 avril 15:34 www
drwxr-xr-x  708 rancune rancune  36864 24 avril 15:34 x11

As you can see, the “catalog” of available applications is organized as directories corresponding to categories. If, for example, you visit the “biology” category, you will find one directory per software package.

That said, the installation is not finished yet. To set up pkgsrc, we then run the “bootstrap” script, in our case with the unprivileged option since we do not want installations to be done system-wide.

$cd /home/rancune/pkgsrc/bootstrap

$./bootstrap --unprivileged

This command will have two effects:

  • A directory /home/rancune/pkg is created.

  • bmake, the BSD version of make, is compiled and installed in it.

It all ends with the following message:

[...]
===========================================================================

Please remember to add /home/rancune/pkg/bin to your PATH environment variable
and /home/rancune/pkg/man to your MANPATH environment variable, if necessary.

An example mk.conf file with the settings you provided to "bootstrap"
has been created for you. It can be found in:

      /home/rancune/pkg/etc/mk.conf

You can find extensive documentation of the NetBSD Packages Collection
in /home/rancune/pkgsrc/doc/pkgsrc.txt.

Thank you for using pkgsrc!

===========================================================================

Since I’m an obedient fellow, I add the following two lines to my bashrc:

export PATH="$PATH:/home/rancune/pkg/bin:/home/rancune/pkg/sbin"
export MANPATH="$MANPATH:/home/rancune/pkg/man"

After restarting my bash, I can verify that everything seems to work with the pkg_info command, which lists the installed packages:

$pkg_info
bootstrap-mk-files-20180901 *.mk files for the bootstrap bmake utility
bmake-20200524nb1   Portable (autoconf) version of NetBSD 'make' utility
cwrappers-20220403  pkgsrc compiler wrappers
pkg_install-20211115 Package management and administration tools for pkgsrc

Note the presence (automatic installation) of bmake: pkgsrc depends on bmake and therefore requires its installation! On Linux, you must be careful to use it instead of (gnu)make.

The pkg directory that was created contains all the usual directories: bin, sbin, etc… This is the environment where all software provided by pkgsrc will be installed. No mixing with the system, no conflicts, no risk. I like that!

$ls /home/rancune/pkg
total 28
drwxr-xr-x 2 rancune rancune 4096 24 avril 15:44 bin
drwxr-xr-x 2 rancune tty     4096 24 avril 15:45 etc
drwxr-xr-x 3 rancune rancune 4096 24 avril 15:44 libexec
drwxr-xr-x 6 rancune rancune 4096 24 avril 15:45 man
drwxr-xr-x 6 rancune rancune 4096 24 avril 15:45 pkgdb
drwxr-xr-x 2 rancune rancune 4096 24 avril 15:45 sbin
drwxr-xr-x 3 rancune rancune 4096 24 avril 15:44 share

Alright, the pkgsrc installation is done… Shall we play?

Configuring pkgsrc

The pkgsrc configuration is in the file etc/mk.conf

Since we are on a bootstrapped system, that will be:

/home/rancune/pkg/etc/mk.conf

$ cat /home/rancune/pkg/etc/mk.conf
# Example /home/rancune/pkg/etc/mk.conf file produced by bootstrap-pkgsrc
# dim. 24 avril 2022 15:43:18 CEST

.ifdef BSD_PKG_MK       # begin pkgsrc settings

ABI=                    64

UNPRIVILEGED=           yes
PKG_DBDIR=              /home/rancune/pkg/pkgdb
LOCALBASE=              /home/rancune/pkg
SYSCONFBASE=            /home/rancune/pkg/etc
VARBASE=                /home/rancune/pkg/var
PKG_TOOLS_BIN=          /home/rancune/pkg/sbin
PKGINFODIR=             info
PKGMANDIR=              man

# WARNING: Changing PREFER_* after bootstrap will require rebuilding all
# packages with a dependency that switched between native/pkgsrc.
PREFER_PKGSRC=          yes


.endif                  # end pkgsrc settings

This is where we can fine-tune our compilation settings: CFLAGS, LDFLAGS and other goodies.

Alright, how about we try installing something now?

An example?

To test pkgsrc, we will install the pkgfind utility, a tool for searching among available packages. We start by navigating to the right directory:

$cd /home/rancune/pkgsrc/pkgtools/pkgfind

$ls
total 20
drwxr-xr-x 2 rancune rancune 4096 24 avril 15:32 CVS
-rw-r--r-- 1 rancune rancune  109 22 juin   2004 DESCR
drwxr-xr-x 3 rancune rancune 4096 24 avril 15:32 files
-rw-r--r-- 1 rancune rancune  856  4 juil.  2018 Makefile
-rw-r--r-- 1 rancune rancune   90 18 janv.  2005 PLIST

As you can see, the contents of the directory are not too complex. It mainly contains a Makefile with the recipe for compiling our software.

We will proceed with said compilation using bmake:

$ bmake
[..]
cc -DHAVE_NBCOMPAT_H=1 -I/home/rancune/pkgsrc/pkgtools/pkgfind/work/libnbcompat -I. -I.  -O2 -D_FORTIFY_SOURCE=2 -DHAVE_CONFIG_H -c setmode.c
cc -DHAVE_NBCOMPAT_H=1 -I/home/rancune/pkgsrc/pkgtools/pkgfind/work/libnbcompat -I. -I.  -O2 -D_FORTIFY_SOURCE=2 -DHAVE_CONFIG_H -c pwcache.c
ar cr libnbcompat.a glob.o md5c.o md5hl.o rmd160.o rmd160hl.o sha1.o sha1hl.o sha2.o sha2hl.o vis.o unvis.o fgetln.o fparseln.o lchflags.o setgroupent.o setpassent.o setprogname.o shquote.o strlcat.o strlcpy.o strmode.o setmode.o pwcache.o
ranlib libnbcompat.a
=> Adjusting pkgsrc directory.
===> Building for pkgfind-20111022
cc -O2 -D_FORTIFY_SOURCE=2   -DHAVE_NBCOMPAT_H=1 -I/home/rancune/pkgsrc/pkgtools/pkgfind/work/libnbcompat    -L/home/rancune/pkgsrc/pkgtools/pkgfind/work/libnbcompat -Wl,-zrelro -Wl,-R/home/rancune/pkg/lib -o /home/rancune/pkgsrc/pkgtools/pkgfind/work/pkgfind-20111022/pkgfind       /home/rancune/pkgsrc/pkgtools/pkgfind/work/pkgfind-20111022/pkgfind.c  -lnbcompat

$ls
drwxr-xr-x  2 rancune rancune 4096 24 avril 15:32 CVS
-rw-r--r--  1 rancune rancune  109 22 juin   2004 DESCR
drwxr-xr-x  3 rancune rancune 4096 24 avril 15:32 files
-rw-r--r--  1 rancune rancune  856  4 juil.  2018 Makefile
-rw-r--r--  1 rancune rancune   90 18 janv.  2005 PLIST
drwxr-xr-x 16 rancune rancune 4096 24 avril 18:45 work

$ls work/
total 8
drwxr-xr-x 6 rancune rancune 4096 24 avril 18:45 libnbcompat
drwxr-xr-x 3 rancune rancune 4096 24 avril 18:45 pkgfind-20111022

$ls work/pkgfind-20111022/
total 40
drwxr-xr-x 2 rancune rancune  4096 24 avril 18:45 CVS
-rwxr-xr-x 1 rancune rancune 18040 24 avril 18:45 pkgfind
-rw-r--r-- 1 rancune rancune  2620 24 avril 18:45 pkgfind.1
-rw-r--r-- 1 rancune rancune  8461 24 avril 18:45 pkgfind.c

As you can see, the different compilation steps take place in the work/ directory, created for this purpose.

All that remains is to install our software, once again using bmake:

$bmake install
===> Installing for pkgfind-20111022
=> Generating pre-install file lists
=> Creating installation directories
/usr/bin/install -c -s -o rancune -g rancune -m 755 /home/rancune/pkgsrc/pkgtools/pkgfind/work/pkgfind-20111022/pkgfind /home/rancune/pkgsrc/pkgtools/pkgfind/work/.destdir/home/rancune/pkg/bin/pkgfind
/usr/bin/install -c -o rancune -g rancune -m 644 /home/rancune/pkgsrc/pkgtools/pkgfind/work/pkgfind-20111022/pkgfind.1 /home/rancune/pkgsrc/pkgtools/pkgfind/work/.destdir/home/rancune/pkg/man/man1/pkgfind.1
=> Automatic manual page handling
=> Generating post-install file lists
=> Checking file-check results for pkgfind-20111022
=> Creating binary package /home/rancune/pkgsrc/pkgtools/pkgfind/work/.packages/pkgfind-20111022.tgz
===> Building binary package for pkgfind-20111022
=> Creating binary package /home/rancune/pkgsrc/packages/All/pkgfind-20111022.tgz
===> Installing binary package of pkgfind-20111022
===> Cleaning for pkgfind-20111022

Our program is now installed in /home/rancune/pkg.

How classy is that… \o/

Installing binaries directly with pkgin

If you don’t want to recompile everything, you can also use a tool that downloads binaries directly and installs them: pkgin!

(Proof of the software’s quality: a certain Imil’s name appears in the project’s commits… ^^)

Because we are not condemned to always recompile everything, there are build farms that do the heavy lifting and provide binary repositories. Among them, the company Joyent notably provides binaries for Mac, Linux, SmartOS and NetBSD!

Here are some basic commands:

  • To update the list of available packages:
pkgin up
  • To install a package (here screen):
pkgin in screen
  • To search for a package:
pkgin se gnome
pkgin se gnome*.term
  • To get an easter egg (what? it’s important!)
pkgin tonic

Much like apt, pkgin is configured through the file:

/home/rancune/pkg/etc/pkgin/repositories.conf

which allows you to choose which repos you want to use.

Let’s package something… pkgsrc-wip!

It is now time to practice making our own package and become a bit more active in this fine community.

The pkgsrc-wip (Work in Progress) project is a repo that allows you to “get your hands dirty”. You gain access after proving yourself (it seems fairly straightforward) and it allows you to submit your own packages to the community. After 10, 20… 30 commits, you might get noticed and be invited to join the official project – who knows?

In any case, to follow this path, you first need to clone the git repo in the right place:

$cd /home/rancune/pkgsrc
$git clone git://wip.pkgsrc.org/pkgsrc-wip.git wip

No permission needed for that.

We are going to package a superb piece of software, crafted by Master Imil himself! It is available in the following gitlab repo:

https://gitlab.com/iMil/truefalse

(Imil, in his great wisdom, tagged the version we are interested in with the sweet name “v1.0”. Make sure to get the right version – it matters!

This repo contains three files:

  • truefalse.c
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    if (argc < 1)
        return EXIT_SUCCESS;

    return EXIT_FAILURE;
}
  • a Makefile (for bmake)
PROG=	truefalse
MAN=

.include <bsd.prog.mk>
  • a README.md
This is a dummy repository to explain pkgsrc's packaging framework.

Prerequisites

Before we begin, we first need to tell pkgsrc that we are developers. Yes, this is where impostor syndrome comes knocking on the door, but you’ll see, it will be fine.

To do this, we edit the etc/mk.conf file and add the following line:

PKG_DEVELOPER=     yes

We then install the meta-package pkg_developer which pulls in everything we need for this new job (Can you feel the responsibilities piling up? The pressure rising???)

$cd /home/rancune/pkgsrc/meta-pkgs/pkg_developer
$bmake
$bmake install

(You can go grab a coffee – this compiles for a while!)

If you get bored during the compilation, you can prepare the directory for our package in the meantime:

$mkdir ~/pkgsrc/wip/truefalse

Playskool presents: my first package!

The url2pkg tool, previously installed by pkg_developer, will build a package template from a simple URL in tar.gz format:

$cd ~/pkgsrc/wip/truefalse

$url2pkg https://gitlab.com/iMil/truefalse/-/archive/v1.0/truefalse-v1.0.tar.gz
===> Cleaning for truefalse-1.0
=> Bootstrap dependency digest>=20211023: found digest-20220214
=> Fetching truefalse-v1.0.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   492  100   492    0     0   1206      0 --:--:-- --:--:-- --:--:--  1366
=> distinfo: unchanged.
=> Checksum BLAKE2s OK for truefalse-v1.0.tar.gz
=> Checksum SHA512 OK for truefalse-v1.0.tar.gz
===> Installing dependencies for truefalse-1.0
=> Tool dependency cwrappers>=20150314: found cwrappers-20220403
===> Checking for vulnerabilities in truefalse-1.0
===> Overriding tools for truefalse-1.0
===> Extracting for truefalse-1.0

Remember to run pkglint when you're done.
See ../../doc/pkgsrc.txt to get some help.


$ls
total 20
-rw-r--r--  1 rancune rancune  130 25 avril 10:18 DESCR
-rw-r--r--  1 rancune rancune  312 25 avril 10:18 distinfo
-rw-r--r--  1 rancune rancune  425 25 avril 10:18 Makefile
-rw-r--r--  1 rancune rancune  198 25 avril 10:18 PLIST
drwxr-xr-x 11 rancune rancune 4096 25 avril 10:18 work

Oooooh! A Makefile!!!

Let’s take a look at the different files, starting with the Makefile:

# $NetBSD$

DISTNAME=       truefalse-v1.0
PKGNAME=        ${DISTNAME:S,-v,-,}
CATEGORIES=     # TODO: add primary category
MASTER_SITES=   https://gitlab.com/iMil/truefalse/-/archive/v1.0/

MAINTAINER=     INSERT_YOUR_MAIL_ADDRESS_HERE # or use pkgsrc-users@NetBSD.org
HOMEPAGE=       https://gitlab.com/iMil/truefalse/-/archive/v1.0/
COMMENT=        TODO: Short description of the package
#LICENSE=       # TODO: (see mk/license.mk)

.include "../../mk/bsd.pkg.mk"

As you can see, it is relatively simple and contains a few blanks that we will fill in.

The PKGNAME field, for example, contains the package name. It is built from DISTNAME using a regex that removes the version number.

The CATEGORIES field must contain the category in which we want to place our software. To choose, just pick one of the /home/rancune/pkgsrc directories we saw earlier.

For LICENSE, we will do the same. The list of licenses can be found in /home/rancune/pkgsrc/licenses, plain and simple. The mk/licenses.mk file lets you see which licenses are valid and how.

Once filled in, our Makefile looks like this:

# $NetBSD$

DISTNAME=       truefalse-v1.0
PKGNAME=        ${DISTNAME:S,-v,-,}
CATEGORIES=     misc
MASTER_SITES=   https://gitlab.com/iMil/truefalse/-/archive/v1.0/

MAINTAINER=     truefalse@rancune.org
HOMEPAGE=       https://gitlab.com/iMil/truefalse/-/archive/v1.0/
COMMENT=        First attempt at making a package
LICENSE=        original-bsd

.include "../../mk/bsd.pkg.mk"

If you want to extend it, a whole set of tools is available in pkgsrc’s mk directory. It is well worth paying a visit!

The DESCR file contains a description of our package. It is automatically filled from our git repo’s README.md – you just need to tweak it a bit!

# truefalse

This is a dummy repository to explain pkgsrc's packaging framework.

The distinfo file contains the BLAKE2s and SHA512 hashes of the tar.gz file containing the sources. It will allow pkgsrc to verify them before compilation and installation.

$NetBSD$

BLAKE2s (truefalse-v1.0.tar.gz) = 0ebf7a1aaef5f20a6c0df0a0cb38cc9ff7cf1d7d511e18c2ad5a4ec7607265b4
SHA512 (truefalse-v1.0.tar.gz) = 0be26cb93917249540e7d0d37805dcd4540382df91fafc9b9c48a15b71d43059e1a26dbdc752110ac7f26bbeb77aad6c792006059cbea8c2c7976d72ab8bca67
Size (truefalse-v1.0.tar.gz) = 492 bytes

And finally, PLIST contains a list of files that will be installed on the filesystem by our package. For now, it is an empty template:

$cat PLIST
@comment $NetBSD$
@comment TODO: to fill this file with the file listing:
@comment TODO: 1. run "/home/rancune/pkg/bin/bmake package"
@comment TODO: 2. run "/home/rancune/pkg/bin/bmake print-PLIST"

We will fill it in soon!

We can now verify that we did everything right with the pkglint tool, which validates a package:

$pkglint
Looks fine.

Since everything checks out, we can start seeing if our package compiles correctly:

$bmake clean
$bmake
=> Bootstrap dependency digest>=20211023: found digest-20220214
=> Checksum BLAKE2s OK for truefalse-v1.0.tar.gz
=> Checksum SHA512 OK for truefalse-v1.0.tar.gz
===> Installing dependencies for truefalse-1.0
=> Tool dependency cwrappers>=20150314: found cwrappers-20220403
===> Checking for vulnerabilities in truefalse-1.0
===> Overriding tools for truefalse-1.0
===> Extracting for truefalse-1.0
===> Patching for truefalse-1.0
===> Creating toolchain wrappers for truefalse-1.0
===> Configuring for truefalse-1.0
===> Building for truefalse-1.0
cc -O2 -D_FORTIFY_SOURCE=2    -c truefalse.c
cc -Wl,-zrelro -Wl,-R/home/rancune/pkg/lib    -o truefalse truefalse.o

Beautiful when it works!

If you are curious, you can go look in the work/ directory that was just created. You will find the different build steps there.

$ls -al work/
total 124
drwxr-xr-x 15 rancune rancune 4096 25 avril 12:16 .
drwxr-xr-x  3 rancune rancune 4096 25 avril 12:16 ..
-rw-r--r--  1 rancune rancune   14 25 avril 12:16 .barrier_cookie
-rw-r--r--  1 rancune rancune   14 25 avril 12:16 .build_done
drwxr-xr-x  5 rancune rancune 4096 25 avril 12:16 .buildlink
-rw-r--r--  1 rancune rancune  561 25 avril 12:16 .build_makevars.mk
drwxr-xr-x  3 rancune rancune 4096 25 avril 12:16 .compiler
-rw-r--r--  1 rancune rancune   14 25 avril 12:16 .configure_done
-rw-r--r--  1 rancune rancune  561 25 avril 12:16 .configure_makevars.mk
drwxr-xr-x  4 rancune rancune 4096 25 avril 12:16 .cwrapper
-rw-r--r--  1 rancune rancune   99 25 avril 12:16 .depends
-rw-r--r--  1 rancune rancune    0 25 avril 12:16 .depends_done
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 .error
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 .error-done
-rw-r--r--  1 rancune rancune   14 25 avril 12:16 .extract_done
-rw-r--r--  1 rancune rancune  561 25 avril 12:16 .extract_makevars.mk
drwxr-xr-x  3 rancune rancune 4096 25 avril 12:16 .gcc
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 .home
-rw-r--r--  1 rancune rancune    0 25 avril 12:16 .patch_done
-rw-r--r--  1 rancune rancune  561 25 avril 12:16 .patch_makevars.mk
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 .pkgdb
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 .pkginstall
-rw-r--r--  1 rancune rancune   87 25 avril 12:16 .rdepends
-rw-r--r--  1 rancune rancune   87 25 avril 12:16 .rrdepends
drwxr-xr-x  3 rancune rancune 4096 25 avril 12:16 .tools
-rw-r--r--  1 rancune rancune  449 25 avril 12:16 .tools_done
-rw-r--r--  1 rancune rancune  561 25 avril 12:16 .tools_makevars.mk
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 truefalse-v1.0
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 .warning
drwxr-xr-x  2 rancune rancune 4096 25 avril 12:16 .warning-done
-rw-r--r--  1 rancune rancune 2915 25 avril 12:16 .work.log
-rw-r--r--  1 rancune rancune   14 25 avril 12:16 .wrapper_done
-rw-r--r--  1 rancune rancune  561 25 avril 12:16 .wrapper_makevars.mk

Installation

Before releasing our package into the wild, it would be good practice to check how and where it will install:

$bmake stage-install
=> Bootstrap dependency digest>=20211023: found digest-20220214
===> Checking for vulnerabilities in truefalse-1.0
===> Installing for truefalse-1.0
=> Generating pre-install file lists
install   -c -s   -o rancune -g rancune -m 555 truefalse /home/rancune/pkgsrc/wip/truefalse/work/.destdir/truefalse
=> Automatic manual page handling
=> Generating post-install file lists
=> Checking file-check results for truefalse-1.0

Here, the installation prefix is work/.destdir… and we can see it will place the executable directly at the top!

We will therefore modify the Makefile a bit to correct this:

# $NetBSD$

DISTNAME=	truefalse-v1.0
PKGNAME=	${DISTNAME:S,-v,-,}
CATEGORIES=	misc
MASTER_SITES=	https://gitlab.com/iMil/truefalse/-/archive/v1.0/

MAINTAINER=	truefalse@rancune.org
HOMEPAGE=	https://gitlab.com/iMil/truefalse/-/archive/v1.0/
COMMENT=	First attempt at making a package
LICENSE=	original-bsd

INSTALLATION_DIRS=	bin

do-install:
	${INSTALL_PROGRAM} ${WRKSRC}/truefalse ${DESTDIR}/${PREFIX}/bin/truefalse

.include "../../mk/bsd.pkg.mk"

The do-install target we added to the Makefile is necessary because the author of the software we are packaging did not set up an installation target in their project (make install doesn’t work). Otherwise, it would have worked on its own without us needing to do anything!

We also update the PLIST file:

bmake print-PLIST > PLIST

And we retest…

$bmake clean
===> Cleaning for truefalse-1.0

$bmake stage-install
=> Bootstrap dependency digest>=20211023: found digest-20220214
=> Checksum BLAKE2s OK for truefalse-v1.0.tar.gz
=> Checksum SHA512 OK for truefalse-v1.0.tar.gz
===> Installing dependencies for truefalse-1.0
=> Tool dependency cwrappers>=20150314: found cwrappers-20220403
===> Checking for vulnerabilities in truefalse-1.0
===> Overriding tools for truefalse-1.0
===> Extracting for truefalse-1.0
===> Patching for truefalse-1.0
===> Creating toolchain wrappers for truefalse-1.0
===> Configuring for truefalse-1.0
===> Building for truefalse-1.0
cc -O2 -D_FORTIFY_SOURCE=2    -c truefalse.c
cc -Wl,-zrelro -Wl,-R/home/rancune/pkg/lib    -o truefalse truefalse.o
===> Installing for truefalse-1.0
=> Generating pre-install file lists
=> Creating installation directories
/usr/bin/install -c -s -o rancune -g rancune -m 755 /home/rancune/pkgsrc/wip/truefalse/work/truefalse-v1.0/truefalse /home/rancune/pkgsrc/wip/truefalse/work/.destdir//home/rancune/pkg/bin/truefalse
=> Automatic manual page handling
=> Generating post-install file lists
=> Checking file-check results for truefalse-1.0

Perfect :)

This time we go for real:

$bmake install
=> Bootstrap dependency digest>=20211023: found digest-20220214
===> Checking for vulnerabilities in truefalse-1.0
=> Creating binary package /home/rancune/pkgsrc/wip/truefalse/work/.packages/truefalse-1.0.tgz
===> Building binary package for truefalse-1.0
=> Creating binary package /home/rancune/pkgsrc/packages/All/truefalse-1.0.tgz
===> Installing binary package of truefalse-1.0

It works!!!!!!!!!!!!!!!!!

Yes, but the guy who wrote this software made some mistakes… In the next episode, we will propose an upstream patch and see how it’s done!

Final words…

Although I am much more familiar with portage on Gentoo, the pkgsrc/pkgin duo seems pretty slick! Generally speaking, packages installed by these two tools form a self-contained universe, separate from the rest of the system. So there is no risk of me making a blunder, as often happened to me when I was starting out.

I must admit, I can’t wait to see what comes next :)

Rancune.

References:

This post is licensed under CC BY 4.0 by the author.