为什么 Homebrew 创建了一个 /usr/local/opt 目录,我应该使用它吗?

Why is there a /usr/local/opt directory created by Homebrew and should I use it?

我对使用 homebrew 很陌生,我想弄清楚在我自己的项目中使用一些库(例如 boost、gsl、openblas)是如何工作的。

据我所知,每个公式都是由 Homebrew 安装在 /usr/local/Cellar/ 中,然后在 usr/local/bin、usr/local/lib、usr/local/include 中进行符号链接,看起来,除了keg-only 公式,因此它不会与 OS 已经安装的库混淆(例如,参见 Understand homebrew and keg-only dependencies)。但我发现每个公式也链接到一个 /usr/local/opt 目录。

所以我的问题是为什么会有这个 /usr/local/opt 目录(有点多余),以及我必须使用什么路径来使用公式(usr/local/Cellar 或 usr/local / 或 usr/local/opt 基本上) ?

它为公式的内容提供了一个路径,该路径在版本升级时不会改变。

考虑这种情况:假设您使用 Homebrew 构建 libfoo.dylib。它是 2.0.0 版,因此位于 /usr/local/Cellar/libfoo/2.0.0/lib/libfoo.dylib。你想从你正在构建的另一个程序 link 到它,所以你将 -L/usr/local/Cellar/libfoo/2.0.0/lib -lfoo 传递给 gcc。你的程序编译。稍后,您升级到 libfoo 2.0.1 并删除 v2.0.0。现在 /usr/local/Cellar/libfoo/2.0.0/lib/libfoo.dylib 不存在了,你的程序也不再运行了,因为它不能动态加载 libfoo.

没关系。 libfoo.dylib 也可在 /usr/local/lib/libfoo.dylib 获得。它是最新版本 libfoo 的符号link,因此它应该始终存在。所以你将 -L/usr/local/lib -lfoo 传递给你的程序并编译它。稍后升级到 libfoo 2.0.1。没问题,因为 /usr/local/lib/libfoo.dylib 仍然存在并指向 v2.0.1 副本。

太棒了,Homebrew 仅在该系统中存在了一段时间。问题是,有些公式是 "keg-only",所以它们不是从 /usr/local 符号 link 编辑的。 (通常它们只是 keg-only,因为它们隐藏了 OS X 附带的库版本,并且取代 OS X 库可能会导致问题。)假设你想 link 到一个keg-only 版本的库。它不是来自 /usr/local/lib 的 symlinked,所以你必须给出安装在 /usr/local/Cellar 中的版本的完整路径,这会让你回到上面列出的第一个问题。

/usr/local/opt 解决了这个问题。它为当前版本的 all 公式提供了一个位置,无论它们是否是 keg-only 或不是。现在,当你想编译你的程序时,你可以使用 -L/usr/local/opt/libfoo/lib -lfoo,你的程序将 link 到最新版本的 libfoo,即使你升级它,即使它是 keg-only。

只是为了补充 mipadi 的回答。

来自一篇名为“/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.

来源:版权所有 © 2014 Extellisys

我发现在/usr/local/opt(在我自己的macOS文件系统中)有很多与其他程序相关的符号链接,例如opensslgnutls等。所以我认为这个(/usr/local/opt)特定目录不仅仅是为 HomeBrew 创建的,它可能适用于更广泛的可执行程序。

BTW 1:我查阅了“文件系统层次结构标准(FHS)”的主页。我在“第 4 章 /usr 层次结构”中没有找到关于 /usr/local/opt 的描述。有点好奇。

顺便说一句 2:我已经安装了 HomeBrew 的 GNU Stow。当我输入命令 brew --prefix stow 时,终端显示路径 /usr/local/opt/stow。然后我尝试在终端中使用命令 open /usr/local/opt/stow 打开它。它打开一个路径为 /usr/local/Cellar/stow/2.3.1.

的目录