There are various techniques for upgrading packages either by using pre-built binary package tarballs or by building new packages via pkgsrc build system. This wiki page hopefully will summarize all of the different ways this can be done, with examples and pointing you to further information.

Methods using only binary packages

pkg_add -uu

pkg_add's -u option is used to update a package. Basically: it saves the package's current list of packages that depend on it (+REQUIRED_BY), installs the new package, and replaces that list of dependencies.

By using the -uu (option used twice), it will attempt to update prerequisite packages also.

Or to automatically add any missing packages using just binary packages:

pkg_chk -b -P URL -a -C pkg_chk.conf

If both -b and -P are given, no pkgsrc tree is used. If packages are on the local machine, they are scanned directly, otherwise the pkg_summary database is fetched. (Using pkg_summary for local packages is on the TODO list.)

(pkg_chk is also covered below.)

Methods that build packages from source

Note: Be sure you have an updated "pkgsrc" directory. It is recommended that you don't update just parts of the pkgsrc directory.

make update

'make update', invoked in a pkgsrc package directory, will remove the package and all packages that depend on it, keeping a list of such packages. It will then attempt to rebuild and install the package and all the packages that were removed.

It is possible, and in the case of updating a package with hundreds of dependencies, arguably even likely that the process will fail at some point. One can fix problems and resume the update by typing make update in the original directory, but the system can have unusuable packages for a prolonged period of time. Thus, many people find 'make update' too dangerous, particularly for something like glib on a system using gnome.

To use binary packages if available with "make update", use "UPDATE_TARGET=bin-install". If package tarball is not available in ${PACKAGES} locally or at URLs (defined with BINPKG_SITES), it will build a package from source.

To enable manual rollback one can keep binary packages. One method is to always use 'make package', and to have "DEPENDS_TARGET=package" in /etc/mk.conf. Another is to use pkg_tarup to save packages before starting.

make replace

The make replace target should only be used by those who understand that there may be ABI issues and can deal with fixing the resulting problems. It is possible that a replaced package will have a different binary interface and thus packages that depend on the replaced packages may not work correctly. This can be because of a shlib (shared library) version bump, where depending package binaries will no longer run, or something more subtle. In these cases, the correct fix is to 'make replace' the problematic depending package. The careful reader will note that this process can in theory require all packages that depend (recursively) on a replaced package to be replaced. See the pkg_rolling-replace section for a way to automate this process.

The "make replace" target preserves the existing +REQUIRED_BY file, uninstalls the currently installed package, installs the newly built package, reinstalls the +REQUIRED_BY file, and changes depending packages to reference the new package instead. It also marks such depending packages with the "unsafe_depends" build variable, set to YES.

It also uses the pkg_tarup tool to create a tarball package for the the currently installed package first, just in case there is a problem.

make replace should preserve the "automatic" build variable, but does not.

If you are an expert (and don't plan to share your packages publically), you can also use in your mk.conf:

USE_ABI_DEPENDS?=no

This is for ignoring the ABI dependency recommendations and just use the required DEPENDS.

Problems with make replace

Besides ABI changes (for which pkg_rolling-replace is a good solution), make replace can fail if packages are named or split. A particularly tricky case is when package foo is installed, but in pkgsrc has been split into foo and foo-libs. In this case, make replace will try to build the new foo (while the old monolithic foo is installed). The foo package depends on foo-libs, and so pkgsrc will go to build and install foo-libs. This will fail because foo-libs will conflict with the old foo. There are three approaches:

manually save the foo +REQUIRED_BY file, pkg_delete foo, and then make package of the new foo. Put back the +REQUIRED_BY, and pkg_admin set unsafe_depends=YES all packages in the +REQUIRED_BY.

pkg_delete -r foo, and make package on everything you still want. Or do make update. Note that this could delete a lot.

Automating the first option would be a useful contribution to pkgsrc.

In addition, any problem that can occur with building a package can occur with make replace. Usually, the solution is not make replace specific

pkg_chk

See all packages which need upgrading:

pkg_chk -u -q

Update packages from sources:

pkg_chk -u -s

You can set UPDATE_TARGET=package in /etc/mk.conf and specify the -b flag, so that the results of compilation work are saved for later use, and binary packages are used if they are not outdated or dependent on outdated packages.

The main problem with pkg_chk, is that it deinstalls all to-be-upgraded candidates before reinstalling then. However a failure is not fatal, because the current state of packages is saved in a pkg_chk* file at the root of the pkgsrc directory.

pkg_rolling-replace

pkgtools/pkg_rolling-replace is a shell script available via pkgsrc. It makes a list of all packages that need updating, and sorts them in dependency order. Then, it invokes "make replace" on the first one, and repeats. A package needs updating if it is marked unsafe_depends or if it is marked rebuild (=YES). If pkg_rolling-replace is invoked with -u, a package needs updating if pkgtools/pkg_chk reports that the installed version differs from the source version. On error, pkg_rolling-replace exits. The user should remove all working directories and fix the reported problem. This can be tricky, but the same process that is appropriate for a make replace should be followed.

Because pkg_rolling-replace just invokes make replace, the problems of ABI changes with make replace apply to pkg_rolling-replace, and the system will be in a state which might be inconsistent while pkg_rolling-replace is executing. But, by the time pkg_rolling-replace has successfully finished, the system will be consistent because every package that has a depending package 'make replaced' out from under it will be marked unsafe_depends, and then replaced itself. This replace "rolls" up the dependency tree because pkg_rolling-replace sorts the packages by dependency and replaces the earliest needing-rebuild package first.

See the pkg_rolling-replace man page (installed by the pkg) for further details.

Example

Find essentials package, that we would rather update manually:

cd /var/db/pkg
find . -name "+PRESERVE" | awk -F/ '{print $2}'

Update everything except the packages above:

pkg_rolling-replace -rsuvX bmake,bootstrap-mk-files,pax,pkg_install

Real-world experience with pkg_rolling-replace

Even if a lot of packages need to be updated, make replace usually works very well if the interval from the last 'pkg_rolling-replace -u' run is not that long (a month or so). With a longer interval, like a year or two, the odds of package renaming/splitting are higher. Still, for those who can resolve the issues, this is a fairly low-pain and reliable way to update.

pkgmanager

Pkgmanager use user defined list of wanted packages for upgrading and installing packages.

User can upgrade his packages with "pkgmanager sync". This command removes packages installed on system which are not listed on want list. Then upgrade all wanted packages and dependencies to new version.

Delete everything

If you don't have a production environment or don't care if your packages will be missing for a while, you can just delete everything and reinstall.

This method is the easiest:

# pkg_delete -Rr '*-*'

-or-

# pkg_delete -ff '*-*'

This expands to all packages, and deletes all packages without caring about dependencies. The second version of the command should be faster, as it does not perform any dependency recursion. (The quotes around the wildcards are so it doesn't get expanded by the shell first.)

An alternative way to choose the packages you want installed is to create your own custom meta-package. A meta-package doesn't install any files itself, but just depends on other packages (usually within a similar topic or need). Have a look at pkgsrc/meta-pkgs category for various examples. If your new meta-package is generic enough and useful for others, please be sure to share it.

chroot environment

Nothing special here. This is really basically the same as just having a another physical system to build packages.

Manually setup a directory containing your base operating system (including compilers, libraries, shells, etc). Put a copy of your pkgsrc tree and distfiles into there or use mount to mount shared directories containing these. Then use the "chroot" command to chroot into that new directory. You can even switch users from root to a regular user in the new environment.

Then build and remove packages as you wish with out affecting your real production system. Be sure to create packages for everything.

Then use other technique from this list to install from these packages (built in chroot).

Or instead of using this manual method, use pkg_comp's chroot.

pkg_comp's chroot

Apart from the examples in the man page, it's necessary supply a list of packages you want to build. The command 'pkg_info -u -Q PKGPATH' will produce a list of packages you explicitly requested be installed; in some strong sense, it's what you want to rebuild.

After you've built new new packages, you need the list of files to reinstall. Assume that you saved the output of 'pkg_info -u -Q PKGPATH' in /etc/pkgs. The following script will produce the name of the binary packages: