Tuesday 31 May 2022

I don’t like Homebrew

This exploration came about because of trying to add GNAT Math Extensions to Alire.

GNAT Math Extensions is a front-end to LAPACK in the style of Ada.Numerics.Real & Complex vectors and matrices for the Eigenvalues and Eigenvectors subprograms, without the limitations of symmetry (for the real version) or Hermitian-ness (for the complex version). Subprograms to compute generalised eigensystems are also provided.

In order to do this, LAPACK (and BLAS) must be available.

On macOS, they are provided as part of the Accelerate framework, a development version of which comes with Xcode or the Command Line Tools.

On Debian-based Linux, the libraries liblapack-dev and libblas-dev are available.

On Windows, msys2 provides mingw-w64-x86_64-lapack, which also contains BLAS.

At present, there’s no way we can tell Alire that it doesn’t need to install anything on macOS, with the result that users will get a warning message. The way to fix that could be to tweak Alire so that we could say that it was OK.

That would be fine for LAPACK and BLAS, which macOS provides, but what if another project required a library which is not provided?

Alire can support the Linux and Windows needs, because they have recognised package managers (apt, msys2). There are several package managers for macOS, of which Homebrew is probably the most convenient (others are MacPorts, which requires sudo, and Fink, which was two OS releases behind the curve in May 2022).

The first thing to note is that, on Intel (x86_64) Macs, Homebrew installs in /usr/local, altering ownership to the installing user, and spreading itself with abandon. On Macs with Apple (aarch64) processors, it installs in /opt/homebrew, which is much more satisfactory (I’m not sure what would happen if the installation default was overridden to this on x86_64, but the developers advise against it).

Once installed, brew install <package> will install package under $HOMEBREW_PREFIX, so on aarch64 for example brew install SDL2 will install the include files in /opt/homebrew/include/SDL2 and the libraries in /opt/homebrew/lib.

Unfortunately, for reasons which I don’t fully understand but seem to be that the Homebrew developers want to discourage you from using their libraries rather than the perfectly good ones that Apple supply in the Accelerate framework, LAPACK (and OpenBLAS) don’t install where you’d expect:

lapack is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS provides LAPACK in Accelerate.framework.

For compilers to find lapack you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/lapack/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/lapack/include"

For pkg-config to find lapack you may need to set:
  export PKG_CONFIG_PATH="/opt/homebrew/opt/lapack/lib/pkgconfig"

It seems you can force brew to install a keg-only package where you would expect by brew link –overwrite –force <package>:

$ brew link --overwrite --force lapack
Linking /opt/homebrew/Cellar/lapack/3.10.1... 19 symlinks created.

$ ls $HOMEBREW_PREFIX/include/lapack*
/opt/homebrew/include/lapack.h
/opt/homebrew/include/lapacke.h
/opt/homebrew/include/lapacke_config.h
/opt/homebrew/include/lapacke_mangling.h
/opt/homebrew/include/lapacke_utils.h

$ ls $HOMEBREW_PREFIX/lib/liblapack*
/opt/homebrew/lib/liblapack.3.10.1.dylib
/opt/homebrew/lib/liblapack.3.dylib
/opt/homebrew/lib/liblapack.dylib
/opt/homebrew/lib/liblapacke.3.10.1.dylib
/opt/homebrew/lib/liblapacke.3.dylib
/opt/homebrew/lib/liblapacke.dylib

That all said, it seems reasonable to use Homebrew to obtain utilities (e.g. wget) which might be tricky to obtain otherwise, often because of complex build processes - wget involves encryption (SSL).

No comments:

Post a Comment