将二进制文件安装到 /bin、/sbin、/usr/bin 和 /usr/sbin,与 --prefix 和 DESTDIR 交互

Posted

技术标签:

【中文标题】将二进制文件安装到 /bin、/sbin、/usr/bin 和 /usr/sbin,与 --prefix 和 DESTDIR 交互【英文标题】:Install binaries into /bin, /sbin, /usr/bin and /usr/sbin, interactions with --prefix and DESTDIR 【发布时间】:2012-01-29 22:57:33 【问题描述】:

大多数使用 Autotools 的软件包都是用户级实用程序,或者至少足够高以完全低于 /usr,或低至足以完全低于 /usr

我正在编写一个包,它需要将一些文件安装到/bin,一些安装到/sbin/usr/bin/usr/sbin。它正在替换传统上放置在这些位置下的几个现有二进制文件。

它还需要在/lib/security 中安装一个PAM 模块(显然/usr/lib/security 不起作用)。

现在的问题是:默认配置的前缀似乎是/usr/local。我可以在我的configure.ac 中控制该默认值。而且至少Gentoo Linux 的默认值是--prefix=/usr。这是个问题,因为它会覆盖我在configure.ac 中设置的所有默认值。

我简要了解了其他类似的软件包是如何处理这个问题的。以下是我的发现:

bash-4.1 似乎安装到 /usr/bin 中,并且发行版构建脚本将 bash 二进制文件移动到 /bin Linux-PAM 在configure.ac 中有hack,因此如果前缀是/usr,它将使用/sbin/lib 来处理它的一些文件。它还将默认前缀设置为/usr。我不确定如果用户传递不同的--prefix 会发生什么。 如果前缀是 /usrshadow-utilsexec_prefix 设置为 ""。那么bin_PROGRAMS 指向/binubindir 被声明为指向$prefix/bin,所以ubin_PROGRAMS 指向/usr/bin

我的问题是:

--prefix 的其他发行版默认设置是什么?我可以合理地假设它总是/usr吗?我现在只关心 Linux,而不关心 BSD。 以上哪种解决方案看起来最干净?您是否发现了一些更好的解决方案? 上述解决方案有哪些潜在问题?这些问题有解决方案吗? 我可以将所有内容安装到/bin 并创建兼容性符号链接。它是否使问题更简单? 是否有其他一些通用构建系统可以被低级系统实用程序接受以更好地满足我的要求?

请随时要求澄清我正在尝试做什么。请注意,如果我想保持与我要替换的内容的兼容性,如果它用于运送二进制文件 A 和 B,一个在 /sbin 和一个在 /usr/bin,我想我只需要在这些地方或最少有符号链接。 PAM 模块也有固定的安装位置。

我显然会支持任何有用的答案。我是一个“公认的答案”我主要是在寻找“我应该做什么”的建议,什么是问题的最干净的解决方案,以及如果适用的话,讨论选项和缺点、利弊。

【问题讨论】:

您不应更改 configure.ac 中的默认值。如果用户在没有分配前缀的情况下运行您的配置脚本,则用户完全有权期望 /usr/local 作为默认值。如果你改变它,你就有一个包装错误。设置前缀是用户的权利(和责任),包维护者无权操心。 您可以在 .spec 文件或 debian/rules 中设置 --prefix,但绝对不得在 configure.ac 中修改它 【参考方案1】:

基本上,//usr 层次结构之间的区别不应该也不应该掌握在包的上游维护者手中(阅读:不是你的责任)。由于/ 应该只包含启动和使/usr 可用所必需的文件,因此/ 的内容是一个管理决定。对于从源代码安装,此决定由安装程序做出,而对于分发,则由软件包维护者做出。

出于某种原因,假设有人试图构建一个chroot 环境。 /usr 和 / 的区别在环境中是没有意义的,不会做。所有前缀都设置为/foo/bar/chroot,任何与$prefix 混淆的配置脚本都可能引发奇怪的行为。同样的论点也适用于像 Debian 打包助手这样的脚本,它们依赖于通常的 $prefix 语义来工作。

因此,最干净的解决方案是bash-4.1 解决方案。你基本上有两个干净的选择:将你的包分成启动关键部分和非启动关键部分,或者让你的configure脚本为启动关键部分提供一个替代前缀,默认设置为/,离开$prefix/usr

【讨论】:

我喜欢这种分为启动关键和非启动关键部分,但不要担心默认值。使它们成为两个单独的包,然后 ebuild 可以调用 econf --prefix=/ 或其他东西。【参考方案2】:

这个问题有两个不同的级别,您的问题似乎都适用于第二个含义(由您的 *.spec 文件或 debian/rules 或 *.pkg 文件生成的二进制包。)目前为止就自动工具而言,您不在乎。您不得尝试在您的 configure.ac 中指定 /usr/local 以外的默认前缀。在二进制包控制文件中指定应该安装的位置,而不是在 configure.ac 中。使用 autoconf 生成的配置脚本的源代码分发默认应该安装在 /usr/local 中,其他任何内容都是打包错误。

如果您想要一个源代码分发版,用户可以使用它在特定平台上的特定位置轻松安装,可以在 tarball 中包含一个脚本来执行此操作。例如,您可能包含一个类似于以下内容的构建脚本:

#!/bin/sh 案例 1 美元 foo) args='--prefix=/usr --bindir=/bin --sysconfdir=/etc';; bar) args='--prefix=/opt';; *) 参数=;; 经社理事会 $(dirname $0)/configure $args && 制作 && 进行安装

这将指定为“foo”和“bar”平台配置的默认参数,但听起来你的问题确实是关于二进制包的控制文件。

【讨论】:

以上是关于将二进制文件安装到 /bin、/sbin、/usr/bin 和 /usr/sbin,与 --prefix 和 DESTDIR 交互的主要内容,如果未能解决你的问题,请参考以下文章

linux磁盘和文件系统管理

macOS 中的特权文件复制(将辅助二进制文件安装到 /usr/local/bin)

elasticsearch安装插件找不到java可执行的二进制文件问题

Linux目录与文件管理

linux根目录下重要文件和作用

Linux文件系统