Why is there a /usr/local/opt directory created by

2020-05-12 01:51发布

问题:

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) ?

回答1:

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.



回答2:

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