A simple port

The anatomy of a port

A basic port consists of a few text files:

  • Makefile
  • distinfo - the SHA256 hashes and filesizes of the distfiles
  • pkg-descr - a description of the port
  • pkg-plist - a list of files installed by the port

This example shows a simple port with a couple of twists:

  • We won't be using an official release version
  • It's a Roundcube plugin that depends on Roundcube, but it also has an additional dependency: php(xx)-curl
  • It comes with a config file we need to handle in a safe manner


This is where the logic goes, but all that's needed for a basic port is to define certain variables like PORTNAME, PORTVERSION, CATEGORIES and a few others (this is not an exhaustive list):

# Created by: Vidar Karlsen 
# $FreeBSD$

PORTNAME=	yubikey_auth
PORTVERSION=	g20170806

MAINTAINER=	vidar@karlsen.tech
COMMENT=	Roundcube yubikey auth plugin


BUILD_DEPENDS=	roundcube>=1.0:mail/roundcube
RUN_DEPENDS=	roundcube>=1.0:mail/roundcube

USES=		php

USE_PHP=	curl

GH_ACCOUNT=	northox
GH_PROJECT=	roundcube-yubikey-plugin
GH_TAGNAME=	52062f1

NO_ARCH=	yes

WWWDIR=		${PREFIX}/www/roundcube/plugins/yubikey_authentication

	cd ${WRKSRC} && ${PAX} -r -w . ${STAGEDIR}${WWWDIR}
	cd ${STAGEDIR}${WWWDIR} && \
		${MV} config.inc.php config.inc.php.sample

.include <bsd.port.mk>


The wanted version of this plugin does not have an upstream release, so PORTVERSION is set to g<date when ${GH_TAGNAME} was committed>, as shown in the Porter's Handbook example 5.13. It could be tempting to use GH_TAGNAME for this, but that is a hash and not guaranteed to move forward/upward, thus not suitable to be used as a version number. We also want to be able to switch to an actual version number in the future without having to use PORTEPOCH to "reset the clock" on the versioning scheme.


This is a Roundcube plugin, so it obviously needs to depend on Roundcube.

Additionally, it requires the PHP curl plugin, which Roundcube does not depend on, so we need to make sure that it gets pulled in.

Adding USES=php and USE_PHP=curl will use the /Mk/Uses/php.mk subsystem to pull in php(xx)-curl as a dependency.

The config file

It is important that the deinstallation of a package does not remove the config file if it has been changed.

The last line of the do-install target of the Makefile will move config.inc.php to config.inc.php.sample. The final step of this magic is done in pkg-plist (see below).


Create the distinfo file by simply running make makesum. The file will look like this:

TIMESTAMP = 1505336059
SHA256 (northox-roundcube-yubikey-plugin-g20170806-52062f1_GH0.tar.gz) = fec865b01ec1c3e86dd8a7e556a08ad6d4874140c8812cf3efa94f1a55ff9542
SIZE (northox-roundcube-yubikey-plugin-g20170806-52062f1_GH0.tar.gz) = 14091


Generate the contents of pkg-plist by running make makeplist > pkg-plist. Edit the file afterwards to remove the top line and define config files as sample files. In this case, the final pkg-plist should look like this:
@sample %%WWWDIR%%/config.inc.php.sample

Note that I have appended .sample to config.inc.php and prefixed the line with @sample. This will make sure that a copy of config.inc.php.sample will be installed as config.inc.php and that the latter will not be removed (if changed) during a pkg remove operation.


Finally, make a pkg-descr file with a description of the port.

Each line should not exceed 80 characters, and it should contain a WWW address to the official website:

This plugin adds the option to use a YubiKey as second-factor

The YubiKey is a USB key emulating a generic keyboard and making
use of one-time passwords to provide two-factor authentication.

Activate the plugin by adding the following to Roundcube's
$config['plugins'] = array('yubikey_authentication');

WWW: https://github.com/northox/roundcube-yubikey-plugin