Install binaries into /bin, /sbin, /usr/bin and /u

2020-04-05 04:48发布

问题:

Most packages using Autotools are user-level utilities or at least high-enough level to be completely under /usr, or low enough to be entirely below /usr.

I'm writing a package that would need to install some files into /bin, some into /sbin, /usr/bin and /usr/sbin. It's replacing several existing binaries that are traditionally placed under those locations.

It also needs to install a PAM module in /lib/security (and obviously /usr/lib/security wouldn't work).

Now the problem is: default configure's prefix seems to be /usr/local. I can control that default in my configure.ac. And at least Gentoo Linux's default is --prefix=/usr. That's a problem because it overrides any defaults I put in my configure.ac.

I took a brief look at how other, similar packages are dealing with this issue. Here are my findings:

  • bash-4.1 seems to install into /usr/bin, and distro build scripts move the bash binary to /bin
  • Linux-PAM has hacks in configure.ac so that if prefix is /usr, it's going to use /sbin and /lib for some of its files. It also sets the default prefix to /usr. I'm not sure what happens if the user passes a different --prefix.
  • shadow-utils set exec_prefix to "" if prefix is /usr. Then bin_PROGRAMS refers to /bin, and ubindir is declared to point to ${prefix}/bin so that ubin_PROGRAMS refers to /usr/bin.

My questions are:

  • What are other distros' defaults for --prefix? Can I reasonably assume it's always /usr? I'm only concerned about Linux at this point, not BSDs.
  • Which of the above solutions seems the cleanest? Do you see some better solutions?
  • What are potential problems with the above solutions? Are there some solutions to those problems?
  • I'm fine with installing everything into /bin and creating compatibility symlinks. Does it make the problem simpler?
  • Is there some other common build system that is acceptable for low-level system utilities that would better handle my requirements?

Feel free to ask for clarification of what I'm trying to do. Note that if I want to retain compatibility with what I'm replacing, if it used to ship binaries A and B, one in /sbin and one in /usr/bin, I think I just have to put replacements in those places or at least have symlinks. PAM modules also have a fixed install location.

I'm obviously going to upvote any useful answer. I an "accepted answer" I'm mostly looking for advice "what should I do", what's the cleanest solution to the problem and if applicable a discussion of options and drawbacks, pros and cons.

回答1:

Essentially, the distinction between the / and the /usr hierarchies is not and should not lie in the hands of the packages' upstream maintainer (read: Is not your responsibility). Since / should only contain files necessary for booting and making /usr available, it is an administrative decision what goes to /. For installations from source, this decision is made by the installer, and for distributions, by the package maintainer.

For a rationale, suppose someone is trying to build a chroot environment. The distinction between /usr and / is meaningless in the environment, and will not be made. All prefixes are set to /foo/bar/chroot, and any configure script messing with $prefix is likely to induce strange behaviour. The same arguments goes for scripts like the Debian packaging helpers, which rely on the usual $prefix semantics to work.

The cleanest solution is therefore the bash-4.1 solution. You have basically two clean options: Split your package into boot-critical and non-boot-critical parts, or let your configure script offer an alternative prefix for the boot-critical parts, which is set by default to /, leaving $prefix as /usr.



回答2:

There are two different levels to this question, and your questions all seem to apply to the second meaning (the binary package generated by your *.spec file, or debian/rules, or a *.pkg file.) As far as the autotools are concerned, you DO NOT CARE. You must not attempt to specify a default prefix other than /usr/local in your configure.ac. Specifying where things should be installed is done in the binary package control files, and NOT in configure.ac. The source distribution using the autoconf generated configure script should install in /usr/local by default, and anything else is a packaging error.

If you want to have a source distribution that the user can use to install easily in a particular location on a particular platform, it would be acceptable to include a script in the tarball that does so. For example, you might include a build script that looks something like:

#!/bin/sh

case $1 in
foo) args='--prefix=/usr --bindir=/bin --sysconfdir=/etc';;
bar) args='--prefix=/opt';;
*) args=;;
esac
$(dirname $0)/configure $args &&
make &&
make install

which would specify default arguments to configure for the 'foo' and 'bar' platforms, but it really sounds like your questions are about control files for binary packages.