Package Managers

Motivation

A package manager is a system for installing, removing, upgrading or downgrading software packages. They ensure that proper versions of dependency software are installed and keep track of all files installed as part of the package.

A caveman installation is an installation performed by downloading, patching, building and installing software manually or via a custom script that is not part of a package manager. This is a temporary, isolated solution.

A package added to a package manager is a permanent, global solution.

A package need only be created once, and then allows the software to be easily deployed any number of times on any number of computers worldwide.

1,000 people spending 2 hours each doing caveman (ad hoc) installations = 2000 man-hours = 1 year's salary.

1 person spending 2 hours creating a package + 999 spending 2 seconds typing a package install command = 2.55 man-hours.

There is a significant, but one-time investment in learning to package software. Once learned, creating a package usually takes LESS time than a caveman install.

Have you ever been in a panic because your server went down and you're approaching a deadline to get your analysis or models done? If you deploy the software with a package manager, no problem... Just install it on another machine and carry on. If you've done a caveman install, you might be dead in the water for a while until you can restore the server or duplicate the installation on another.

Some packages managers allow the end-user to build from source with many combinations of options, compilers, alternate libraries (BLAS, Atlas, OpenBLAS). FreeBSD ports, Gentoo Portage, MacPorts, pkgsrc.

This provides the user more flexibility.

Binary packages distributed by any package manager must be portable and thus use only minimal optimizations. We can do optimized builds from source (make.conf, mk.conf or command-line additions) such as -march=native.

Building from source takes longer, but is no more difficult for you. It also provides many advantages, such as:

  • The ability to build an optimized installation. Binary (precompiled) packages must be able to run on most CPUs still in use, so they do not take advantage of the latest CPU features (such as AVX2 as of this writing in February 2019). When compiling a package from source, we can add compiler flags such as -march=native to optimize for the local CPU. The package produced may not work on older CPUs.
  • The ability to install to a different prefix. This can be useful for doing multiple installations with different build options, or installing multiple versions of the same software.
  • The ability to easily install software whose license does not allow redistribution in binary form
  • The ability to easily test patches.

It also makes it easy to use the package manager to systematically deploy work-in-progress packages that are not yet complete and for which no binary packages have been built.

Most package managers work only on one platform or possible a few closely related platforms. Some work on multiple platforms with some limitations. The pkgsrc package manager is unique in that it provides general purpose package management for any Unix compatible platform.

Table 40.2, “Package Manager Comparison” provides some information about popular package managers.

Table 40.2. Package Manager Comparison

NamePlatformsBuild From Source?
CondaLinux, Mac, WindowsNo
dportsDragonfly BSD (derived from FreeBSD ports)Yes
Debian PackagesDebian-based (Debian, Ubuntu, etc)No
FreeBSD PortsFreeBSD, Dragonfly BSD*Yes
MacPortsOS XYes
pkgsrcAny POSIXYes
PortageGentoo LinuxYes
Yum/RPMRedhat Enterprise Linux, CentOSNo

A direct comparison of which collection is "biggest" is not really feasible. A raw count of Debian packages will produce a higher number than the others, but this is in part due to the Debian tradition of creating separate packages for documentation (-doc packages) and header files (-dev packages). FreeBSD ports and many other package managers traditionally include documentation and headers in the core package. For example, below are listings of FFTW (fast Fourier transform) packages on Debian and FreeBSD:

Software in the RHEL Yum repository also tends to be older versions than you will find in Debian, FreeBSD, or Gentoo packages.

This is in no way a criticism of Red Hat Enterprise Linux, but simply illustrates that it was designed for a different purpose, namely highly stable enterprise servers running commercial software. The packages in Yum are intended to remain binary compatible with commercial applications for 7 years, not to provide the latest open source applications.

The Pkgsrc software management system can be used to maintain more recent open source software on enterprise Linux systems, separate from the commercial software and support software installed via Yum. Pkgsrc offers over 17,000 packages, most of which are tested on CentOS.

Pkgsrc has the additional benefit of being the only cross-platform SMS. It can currently be used to install most packages on NetBSD, Dragonfly BSD, Linux, Mac OS X, and Interix (a MS Windows Unix layer).

Even if you have to manually build and install your own software, you can probably install most of the prerequisites from an SMS. Doing so will save you time and avoid conflicting installations of the same package on your system.

Better yet, learn how to create packages for an SMS, so that others don't have to duplicate your effort in the future. Each SMS is a prime example of global collaboration, where each user leverages the work of thousands of others. The best way to support this collaboration is by contributing to it, even if in a very small way.

FreeBSD Ports

The FreeBSD ports system represents one of the largest package collections available, and it runs on a platform offering enterprise stability and near-optimal performance.

29,483 packages as of Feb 2 2018.

Port options allow many possible build option combinations for some ports (R is a good example). Some other package managers would require separate binary packages to provide the same support.

Most core scientific libraries are well-tested and maintained. (BLAS, LAPACK, Eigen, R, Octave, mpich2, openmpi, etc.)

Easy to deploy latest open source software, easy to convert to pkgsrc for deployment on other POSIX systems. Great scientific computing platform and sandbox environment.

Advanced development tools (ports-mgmt category), portlint, stage-qa, poudriere.

DEVELOPER=yes
            

Security checks

shell-prompt: pkg install R
            
shell-prompt: cd /usr/ports/math/R
shell-prompt: make rmconfig
shell-prompt: make install
            

Port options dialog for R:

Porter's Handbook

Example: http://acadix.biz/hello.php

Install freebsd-ports-wip: https://github.com/outpaddling/freebsd-ports-wip

Add the following to ~root/.porttools:

EMAIL="your-email@some.domain"
FULLNAME="Your Full Name"
            
shell-prompt: pkg install porttools
shell-prompt: wip-update
shell-prompt: wip-reinstall-port port-dev
shell-prompt: cd /usr/ports/wip
shell-prompt: port create hello

The port directory name given here should usually be all lower-case,
except for ports using perl CPAN and a few other cases.  The PORTNAME
is usally lower-cased as well, but there is not general agreement on this.
It's not that important as "pkg install" is case-insensitive.

shell-prompt: cd hello
shell-prompt: wip-edit

See /usr/ports/Mk/bsd.licenses.db.mk for list of valid licenses.
You can comment out LICENSE_FILE= until after the distfile is downloaded
and unpacked if that's more convenient that figure out it's location
via the web.  It should usually be prefixed with ${WRKSRC}, e.g.

LICENSE_FILE=   ${WRKSRC}/COPYING

shell-prompt: port-check
shell-prompt: port-remake
            

Thorough port testing:

shell-prompt: port-poudriere-setup
ZFS pool []: (just hit enter)
Configuration file opens in vi, accept defaults.
shell-prompt: wip-poudriere-test hello all
            

The port-poudriere-setup script will create a basic poudriere setup and a FreeBSD jail for building and testing ports on the underlying architecture and operating system. It also offers the option to create additional jails for older operating systems and lower architectures (i386 if you are running amd64).

The wip-poudriere-test script runs "poudriere testport" on the named port in the wip collection.

Other useful poudriere commands:

shell-prompt: poudriere ports -u

Updates the ports tree used by poudriere.  This will obsolete any binary
packages saved from previous builds if the corresponding port is upgraded.
Hence, your next poudriere build may take much longer.

shell-prompt: poudriere bulk wip/hello

This will build a binary package for the named port, which you can deploy
with "pkg add" on other systems.
            

Run "poudriere" or "poudriere <command>" or "man poudriere" for help.

Example 2: https://github.com/cdeanj/snpfinder

shell-prompt: cd /usr/ports/wip
shell-prompt: port create snpfinder

USE_GITHUB=yes
GH_ACCOUNT=cdeanj
DISTVERSION=1.0.0

shell-prompt: cd snpfinder
shell-prompt: wip-edit
shell-prompt: port-patch-vi work/snpfinder-1.0.0
shell-prompt: port-check
shell-prompt: port-remake
            
Pkgsrc

Pkgsrc was forked from FreeBSD ports in 1997 by the NetBSD project.

Like everything in the NetBSD project, the primary focus is portability. Pkgsrc aims to support all POSIX environments. Top-tier support for NetBSD, Linux, SmartOS. Strong support for Mac OS X, other BSDs.

Tools analogous to FreeBSD ports, but often less developed. pkglint, stage-qa, pbulk.

http://netbsd.org/~bacon/

url2pkg, fbsd2pkg

PKG_DEVELOPER=yes
            

Pkgsrc Guide (both user and packager documentation)

Example: http://acadix.biz/hello.php

Log into a system using pkgsrc (NetBSD, Linux, Mac, etc.)

Install pkgsrc-wip: https://www.pkgsrc.org/wip/ Use auto-admin?

shell-prompt: cd /usr/pkgsrc/wip/pkg-dev
shell-prompt: bmake install
            

Install FreeBSD ports and wip on your pkgsrc system: (ports collection is mirrored on Github if you prefer git)

shell-prompt: pkgin install subversion
shell-prompt: svn co https://svn.FreeBSD.org/ports/head /usr/ports
shell-prompt: cd /usr/ports
shell-prompt: svn co https://github.com/outpaddling/freebsd-ports-wip.git wip
            

Convert the FreeBSD port to pkgsrc:

shell-prompt: cd /usr/pkgsrc/uwm-pkgsrc-wip/fbsd2pkg
shell-prompt: bmake install
shell-prompt: cd ..
shell-prompt: fbsd2pkg /usr/ports/wip/hello your-email-address

You can run the above command repeatedly until the package is done.

shell-prompt: cd hello
shell-prompt: pkg-check
shell-prompt: pkglint -e
shell-prompt: pkglint -Wall
            

Create the package from scratch using url2pkg:

shell-prompt: mkdir hello
shell-prompt: cd hello
shell-prompt: url2pkg http://acadix.biz/Ports/distfiles/hello-1.0.tar.xz