notes from /dev/null

by Charles Choi 최민수

Administering MacPorts

31 Jan 2024  Charles Choi

When it comes to package managers for macOS, I’ve started with1 and continue to use MacPorts whenever I can. The reasons for this are largely in line with what Saagar Jha captured in his blog post from 2019 and little since then has changed to convince me otherwise. Over the past two decades (!) I’ve come to some learnings about administering MacPorts, which I’ve captured in this post.

It is not enough to have Xcode installed. You should also install the separate command line tools before installing MacPorts.

In particular, Apple puts certain headers and libraries required by some open-source software into the command line tools package, not in Xcode*.xip. More often than not you’ll want to install software that requires said headers and libraries. Save yourself the guesswork and install the command line tools anyways.

You can do this by running xcode-select in the Terminal.

$ xcode-select --install

At its core, MacPorts is a 90’s-style solution to package management.

The design of MacPorts is heavily influenced by the Ports system from FreeBSD. Ports was designed to solve a 90’s-style problem in package management: How do you distribute for many different Unix variants either from different vendors or different OS versions? Ports took this tack: Download the source, configure for the local environment, and build. That said, since 2011 MacPorts can ship binaries to speed things up but only under certain conditions, particularly with regards to CPU architecture, OS version, and licensing.

Probably the biggest benefit of local building from source is the higher likelihood that you will be running an executable that is tuned to your system (CPU architecture and OS version). On older versions of macOS, MacPorts will likely let you build and run the latest version of an open-source tool. For years I had a 2010 iMac with macOS 10.13.6 High Sierra that could still run the latest versions of open-source tools, extending its useful lifetime as a development system.

Probably the biggest frustration of building from source is dealing with package dependencies. Installing a package with many dependencies (looking at you ffmpeg) can feel like MacPorts is building all the things, because it is.

OS upgrading is a deep operation in MacPorts.

Because MacPorts tries to tune itself to a particular CPU and OS version, whenever there is a macOS upgrade, the recommended guidance is to migrate your install of MacPorts. Effectively this means reinstalling your packages for every OS upgrade.

Pragmatically there are a couple of gotchas with this.

  • At the time of the macOS release, not necessarily all the software packages have been updated to support it. More often than not, rebuilding the package will break.
  • You will need to upgrade Xcode and the command line tools that go along with the OS upgrade before MacPorts migration.
  • There are a lot of steps involved with MacPorts migration. For users (particularly those used to primarily GUI driven flows) this can be both cumbersome and error-prone. (Why this step has not yet been automated still bewilders me.)
  • If you use a shell provided by MacPorts (configured using chsh) then you must remember to revert back to the default macOS installed shell (typically /bin/zsh) before MacPorts migration.

Being burned multiple times over the years with the above has led me to this guidance: Only upgrade the OS and migrate MacPorts when the .1 OS release comes out. While by no means bulletproof, this strategy gives you a higher likelihood of success in migrating MacPorts to the upgraded OS. Admittedly there are years when you must upgrade the OS and Xcode before the .1, particularly if you are an iOS developer. Under such circumstances, you can defer the migration until the .1 OS release as everything in /opt/local/bin should still work.

Reporting Broken Ports

In the event you find a port to be broken, by all means report it. Over the years I’ve found MacPorts maintainers to be attentive and I am grateful for it.

MacPorts was meant to be run by a system administrator.

In the before-time, most deployed Unix systems were multi-user with the responsibilities of system administration given to a separate individual or organization. That system administrator could dedicate the time and resources to manage all of the above, leaving users the benefit of just using the tools installed. With individual ownership of macOS systems being predominant, such users who use MacPorts are forced to wear a sysadmin hat.

I’d observe that among macOS users, almost no one wants, much less cares to be a Unix sysadmin. That includes those who use Macs for Apple (iOS, macOS) development.

If you're going to use MacPorts, expect to be a sysadmin.

Why not use Homebrew?

Some readers might say, with all of the friction described above, why not use Homebrew? I would argue that Homebrew tends to sweep the details of OS upgrading and package migration under the rug. Homebrew tries too much to give you the illusion that installing open source tools is akin to installing a mobile app. But when things go invariably sideways, you are at the mercy of the policies of their package maintainers.

As a general rule, you trade-off control and optimization for convenience with Homebrew. With MacPorts, it’s the opposite. MacPorts doesn’t try to hide the responsibility of system administration from you; Homebrew does. For example, this blog post describes how Homebrew’s update policies created unpleasant surprise to the user when upgrading Python.

In the end, I prefer to have more control, despite the extra work it entails. MacPorts gives me this.

Closing Thoughts

My deepest thanks to the maintainers and contributors to MacPorts; this is software that I’ve been using for the past two decades strong. Hopefully my learnings will be of use to new MacPorts users and perhaps provide clarification for existing users as well.


1 My first install of MacPorts goes all the way back to a 12” Powerbook G4 in 2003.




Feeds & TagsGet Captee for macOS

Powered by Pelican