为什么总是./configure; make; make install; 作为3个独立的步骤?

每次从源代码编译一些东西,都要经历相同的3个步骤:

$ ./configure
$ make
$ make install

I understand, that it makes sense to divide the installing process into different steps, but I don't get it, why each and every coder on this planet has to write the same three commands again and again just to get one single job done. From my point of view it would make totally sense to have a ./install.sh script automatically delivered with the source code which contains the following text:

#!/bin/sh
./configure
make
make install

为什么人们要分开做这三个步骤?

70738 次浏览

如果发现缺少依赖项,configure可能会失败。

make运行默认目标,这是 Makefile 中列出的第一个目标。通常这个目标是 all,但并不总是如此。所以如果你知道目标是 make all install你只能这么做。

So ...

#!/bin/sh


if ./configure $*; then
if make; then
make install
fi
fi

或:

./configure $* && ./make && ./make install

之所以包含 $*,是因为经常需要为 configure提供选项。

但是为什么不让人们自己做呢? 这真的是一个大胜利吗?

首先。/configure 并不总是能找到它需要的所有东西,或者在其他情况下,它能找到它需要的所有东西,但不能找到它可以使用的所有东西。在这种情况下,你会想知道它(和你的。/install.sh 脚本无论如何都会失败!)在我看来,意外后果不失败的典型例子是编译大型应用程序,比如 ffmpeg 或 mplayer。如果可用,它们将使用库,但如果不可用,它们将无论如何进行编译,这使得一些选项被禁用。问题在于,您后来发现它是在不支持某种格式的情况下编译的,因此需要返回并重做。

还有一件事。/configure 在某种程度上是交互式的,它使您可以选择自定义应用程序将在系统上安装的位置。不同的发行版/环境有不同的约定,您可能希望在系统上遵守这些约定。另外,您可能希望在本地安装它(仅为您自己)。传统上。/configure 和 make 步骤不以 root 身份运行,而 make install (除非它仅为您自己安装)必须以 root 身份运行。

特定的发行版通常提供脚本,以对发行版敏感的方式执行此./install.sh 功能,例如,源 RPM + spec 文件 + rpmbuild懒散

(脚注: 尽管如此,我还是同意./configure; make; make install; 可能会变得非常单调乏味。)

因为每一步都做不同的事情

为建筑物准备(安装)环境

./configure

这个脚本有很多您应该更改的选项。就像 --prefix或者 --with-dir=/foo。这意味着每个系统都有不同的配置。./configure还检查应该安装的缺少库。这里有什么问题 causes not to build your application。这就是为什么发行版有安装在不同地方的软件包,因为每个发行版都认为最好将某些库和文件安装到某些目录中。据说它运行 ./configure,但实际上应该总是更改它。

例如,看看 Arch Linux 软件包站点。在这里,您将看到任何包都使用不同的 configure 参数(假设它们在构建系统中使用 autotools)。

Building the system

make

默认情况下,这实际上是 make all。每个制造商都有不同的行动要做。有些进行构建,有些在构建后进行测试,有些从外部 SCM 存储库进行签出。通常您不必给出任何参数,但是有些包执行它们的方式也不同。

安装到系统

make install

这会将包安装在 configure 指定的位置。如果需要,可以指定 ./configure指向您的主目录。但是,许多配置选项都指向 /usr/usr/local。这意味着您必须实际使用 sudo make install,因为只有 root 才能将文件复制到/usr 和/usr/local。


现在您可以看到,每一步都是下一步的先决条件。每个步骤都是一个准备工作,使事情在一个没有问题的流程。发行版使用这个比喻来构建包(如 RPM、 deb 等)。

这里您将看到,每个步骤实际上是一个不同的状态。这就是为什么包管理器有不同的包装器。下面是一个包装器示例,它允许您在一个步骤中构建整个包。但是请记住,每个应用程序都有一个不同的包装器(实际上,这些包装器有一个名称,如 spec、 PKGBUILD 等) :

def setup:
... #use ./configure if autotools is used


def build:
... #use make if autotools is used


def install:
... #use make all if autotools is used

这里可以使用 autotools,即 ./configuremakemake install。但是另一个可以使用 SCons、与 Python 相关的设置或其他不同的东西。

正如您所看到的,分离每个状态使得维护和部署变得更加容易,特别是对于包维护人员和发行版。

首先,它应该是 ./configure && make && make install,因为每一个都取决于前者的成功。部分原因是演变,部分原因是开发工作流程的便利。

Originally, most Makefiles would only contain the commands to compile a program and installation was left to the user. An extra rule allows make install to place the compiled output in a place that might be correct; there are still plenty of good reasons that you might not want to do this, including not being the system administrator, not want to install it at all. Moreover, if I am developing the software, I probably don't want to install it. I want to make some changes and test the version sitting in my directory. This becomes even more salient if I'm going to have multiple versions lying around.

./configure goes and detects what is available in the environment and/or is desired by the user to determine how to build the software. This is not something that needs to change very often and can often take some time. Again, if I am a developer, it's not worth the time to reconfigure constantly. More importantly, since make uses timestamps to rebuild modules, if I rerun configure there is a possibility that flags will change and now some of the components in my build will be compile with one set of flags and others with a different set of flags that might lead to different, incompatible behaviour. So long as I don't rerun configure, I know that my compilation environment remains the same even if I change my sources. If I rerun configure, I should make clean first, to remove any built sources to ensure things are built uniformly.

只有在用户安装程序或者构建包(例如 Debian 的 debuild 或者 RedHat 的 rpmbuild)时,这三个命令才会同时运行。这里假设包可以得到一个简单的 configure,这种情况通常不适用于包装,至少需要 --prefix=/usr。而且包装商在做 make install部分的时候还要处理假根。由于有很多例外,使 ./configure && make && make install的规则将是不方便的很多人谁这样做的更频繁的基础上!