I am quite new at using homebrew and I am trying to figure out how it works to use some libraries (boost, gsl, openblas for example) in my own project.
I have understood that each formula is installed by Homebrew in /usr/local/Cellar/ and then symlinked in usr/local/bin, usr/local/lib, usr/local/include, so it seems, excepts for keg-only formulas so it does not mess with already installed libraries by the OS (cf. Understand homebrew and keg-only dependencies for example). But I found out that every formula is also linked to a /usr/local/opt directory.
So my question is why is there this /usr/local/opt directory (it is kind of redundant), and what path do I have to use for using formulas (usr/local/Cellar or usr/local/ or usr/local/opt basically) ?
It's usually describes as for optional add-on software packages source, or anything that isn't part of the base system. Only some distributions use it, others simply use /usr/local . Show activity on this post. It holds optional software and packages that you install that are not required for the system to run.
From the Homebrew FAQ : The prefix /opt/homebrew was chosen to allow installations in /opt/homebrew for Apple Silicon and /usr/local for Rosetta 2 to coexist and use bottles.
Whatever the format you find opt within your macOS directory, the purpose of this folder is: “a directory for installing unbundled packages (i.e., packages not part of the Operating System distribution, but provided by an independent source), each one in its own subdirectory.”
/usr/local is for locally built or locally installed files, whether packaged or not that somewhat become part of that instance of the Operating System. /opt is a place to install "foreign" packages not part of the Operating System.
It provides a path for a formula's contents that does not change across version upgrades.
Consider this scenario: Say you build libfoo.dylib
with Homebrew. It is version 2.0.0, and so it lives at /usr/local/Cellar/libfoo/2.0.0/lib/libfoo.dylib
. You want to link to it from another program you are building, so you pass -L/usr/local/Cellar/libfoo/2.0.0/lib -lfoo
to gcc
. Your program compiles. Later on, you upgrade to libfoo 2.0.1 and remove v2.0.0. Now /usr/local/Cellar/libfoo/2.0.0/lib/libfoo.dylib
no longer exists, and your program no longer runs, because it can't dynamically load libfoo.
That's okay. libfoo.dylib
is also available at /usr/local/lib/libfoo.dylib
. It's a symlink to the latest version of libfoo, so it should always be present. So you pass -L/usr/local/lib -lfoo
to your program and compile it. Later you upgrade to libfoo 2.0.1. No problem, because /usr/local/lib/libfoo.dylib
is still present and points to the v2.0.1 copy.
That's great, and Homebrew existed with just that system for a while. The problem is, some formula are "keg-only", so they are not symlinked from /usr/local
. (Generally they are keg-only because they shadow a version of a library that ships with OS X, and superseding OS X libraries can cause problems.) Say you want to link to a keg-only version of the library. It's not symlinked from /usr/local/lib
, so you have to give the full path to the version installed in /usr/local/Cellar
, which is brings you back to the first problem listed above.
/usr/local/opt
solves this problem. It provides a place for the current version of all formulae to be symlinked, regardless of whether they are keg-only or not. Now, when you want to compile your program, you can use -L/usr/local/opt/libfoo/lib -lfoo
, and your program will link to the latest version of libfoo, even if you upgrade it and even if it is keg-only.
Just to complement mipadi answer.
From an article aptly named '/usr/local/opt'
Storing files in consistent locations is an important part of keeping a system clean and maintainable. On most Linux systems, the majority of software is installed using a package manager. A package manager tracks the files that are installed, so it can update and remove software with minimal side-effects.
There are times, however, when software that is not available through the package manager must be installed. To minimize the side-effects on the filesystem, such software is installed within the /usr/local directory. UNIX-style installation of software puts files in the bin, lib, share, etc. subdirectories under the local root, but it is very common to install software into package-specific directories and add soft-links from the local root instead. Doing so allows for easy removal of the software—simply remove the package-specific directory as well as any links pointing into it.
Some software provides local installation instructions that promote creating a package-specific directory directly in /usr/local. This does not promote good organization, as it mixes UNIX hierarchy directories with package-specific directories. Installation of software into package-specific directories is already done elsewhere, in the /opt directory, and it would therefore make sense to follow the same conventions and put locally installed package-specific directories in a /usr/local/opt directory.
Including a version number in the directory name is not required, but it is good practice for locally-installed software because it allows multiple versions to be installed and tested simultaneously. To run a specific version of the software, run the executable under the package directory directly. Any version can be made the default by controlling which executable is linked to from /usr/local/bin. For example, a new version of software can be installed and tested without removing the old version. When the new version is ready, the link in /usr/local/bin can be updated to point to it. The old version of the software can then be removed when it is no longer needed.
Source: Copyright © 2014 Extellisys
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With