FreeBSD ports: want to recompile everything, a few packages fail because “uninstall error” / “already installed”

bsd-portsfreebsd

Only used binary packages via pkg install for a long time. Then had to compile one package from source, since additional options had to be activated. Since that went so well, I wanted to switch completely to /usr/ports on this machine.

Cleanup (got this from somewhere):

pkg autoremove
portsclean -C -D -DD
portsnap auto
portsclean -C -D -DD

Then doing portupgrade -af --batch. This command results in:

** Listing the failed packages (-:ignored / *:skipped / !:failed)
        ! multimedia/libvpx (libvpx-1.9.0)      (uninstall error)
        ! databases/db5 (db5-5.3.28_7)  (uninstall error)
        * databases/ruby-bdb (ruby26-bdb-0.6.6_8)
        * ports-mgmt/portupgrade (portupgrade-2.4.16,2)
        * devel/apr1 (apr-1.7.0.1.6.1_1)
        [...]

… and then many more skipped packages.

root:/usr/ports/multimedia/libvpx # make install
===>  Installing for libvpx-1.9.0
===>  Checking if libvpx is already installed
===>   libvpx-1.9.0 is already installed
      You may wish to ``make deinstall'' and install this port again
      by ``make reinstall'' to upgrade it properly.
      If you really wish to overwrite the old port of libvpx
      without deleting it first, set the variable "FORCE_PKG_REGISTER"
      in your environment or the "make install" command line.
*** Error code 1

Stop.
make: stopped in /usr/ports/multimedia/libvpx

Similar for databases/db5. So I do make deinstall and make reinstall in both directories and start portupgrade -af --batch again. But it ends with a similar message, which seems even worse; here just listing the lines with !:

        ! multimedia/libvpx (libvpx-1.9.0)      (uninstall error)
        ! databases/db5 (db5-5.3.28_7)  (uninstall error)
        ! devel/boost-libs (boost-libs-1.72.0_2)        (uninstall error)
        ! devel/cmake (cmake-3.18.3)    (uninstall error)

So it is again the "uninstall error".

What is the proper way to handle this?

Update: It seems that Portupgrade is the culprit. It does work fine with Portmaster. Namely:

env BATCH=yes portmaster -afGyd --no-confirm

It took me a while to find out how convince this tool not to keep me busy pressing "y" and "Enter" every other minute, but then it worked through all my packages either with an "install", a "re-install", or an "upgrade". No errors.

Then I tried portupgrade -af --batch once more, and it resulted in "uninstall error" again.

I will write this up as an answer once I confirmed it by another run.

Update 2: Another run with Portmaster yielded "uninstall error" for a few packages. Tried again on another day, after portsnap auto, and Portmaster worked through all my packages just fine. So the problem comes and goes. I'm giving up now. Since the last full run of Portmaster was successful, I will leave it at this. I installed a daily cron job:

#!/bin/sh
set -e
portsnap auto
env BATCH=yes portmaster -aGyd --no-confirm
env BATCH=yes portmaster -ys --no-confirm
service -R
echo "All done!"

Hope this will be good.

Update 3: I interleaved the above script with a couple more of env BATCH=yes portmaster -afGyd --no-confirm manually, which did not yield any errors, but indeed reinstalled all my packages.

General remark: I will from now on always use ports on my FreeBSD installations. Precompiled packages via pkg work fine, but there will come a day when you need one tiny configuration in one tiny package to be set differently from the precompiled version. Then you need ports. Moreover, on that day, you will perhaps not have time to re-learn how to use essential parts of your operating system infrastructure. So I recommend to use ports all the way. Maybe check out Poudriere if having multiple machines (never tried it myself, but maybe will some day).

Best Answer

pkg autoremove doesn't do what you think it does.

pkg autoremove is used for removing orphan packages, which were installed during dependency resolution and are no longer needed.

What you should do is pkg delete <pkg> for what you want to uninstall. Then there are a number of steps needed to install a port if you are going to use make.

First step inside /usr/ports/<pkg>:

make config fetch checksum depends extract patch configure build

Then make install followed by make clean to remove the work file or make distclean to remove both the work file and the downloaded program.

All of this is assuming you have kept your ports tree and packages up-to-date.

You should follow the excellent FreeBSD Handbook

Related Question