为什么总是./configure; 使; 安装; 作为3个单独的步骤?

每当你从源代码编译的东西,你经历了相同的3个步骤:

$ ./configure $ make $ make install 

我明白,把安装过程划分成不同的步骤是有道理的,但是我不明白,为什么这个星球上的每个编码人员都必须一次又一次地编写相同的三个命令才能完成一个单独的工作。 从我的angular度来看,使用包含以下文本的源代码自动提供./install.sh脚本是完全有意义的:

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

为什么人们会分开做3个步骤?

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

准备(安装)build设环境

 ./configure 

这个脚本有很多你应该改变的选项。 像--prefix--with-dir=/foo 。 这意味着每个系统都有不同的configuration。 另外./configure检查应该安装的缺失库。 这里的任何错误都不会导致您的应用程序无法build立 这就是为什么发行版有安装在不同地方的软件包的原因,因为每个发行版都认为将某些库和文件安装到特定目录会更好。 据说运行./configure ,但实际上你应该总是改变它。

比如看看Arch Linux的软件包网站 。 在这里你会看到任何包都使用不同的configuration参数(假设他们使用自动工具来编译系统)。

build立系统

 make 

实际上这是默认设置。 每一个制作都有不同的行动。 一些做build设,一些build立后testing,一些做外部SCM存储库检出。 通常你不必提供任何参数,但是一些软件包也是以不同的方式执行它们。

安装到系统

 make install 

这将把软件包安装在configure指定的地方。 如果你想要,你可以指定./configure指向你的主目录。 但是,许多configuration选项指向/usr/usr/local 。 这意味着你必须使用sudo make install因为只有root可以将文件复制到/ usr和/ usr / local。


现在你看到每一步都是下一步的先决条件。 每一步都是为了使事情顺利进行而做的准备。 发行版使用这个比喻来构build包(如RPM,deb等)。

在这里你会看到每一步实际上是一个不同的状态。 这就是包pipe理者有不同包装的原因。 下面是一个包装器的例子,可以让你一步完成整个包装。 但是请记住,每个应用程序都有一个不同的包装(实际上这些包装有一个像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,这意味着./configuremake install 。 但另一个可以使用SCons,Python相关的设置或不同的东西。

正如你所看到的,将每个状态分开使维护和部署变得更容易,特别是对于软件包维护者和发行者。

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

最初,大多数Makefile只包含编译程序的命令,安装由用户完成。 一个额外的规则允许make install把编译的输出放在一个可能正确的地方; 还有很多很好的理由,你可能不希望这样做,包括不是系统pipe理员,根本不想安装它。 而且,如果我正在开发软件,我可能不想安装它。 我想做一些改变,testing坐在我的目录中的版本。 如果我要有多个版本,这变得更加突出。

./configure会去检测环境中可用的和/或用户想要的,以确定如何构build软件。 这不是经常需要改变的东西,往往需要一些时间。 再一次,如果我是一个开发人员,不值得花时间重新configuration。 更重要的是,由于make使用时间戳来重build模块,所以如果我重新运行configure有可能会改变标志,现在我的编译中的一些组件将被编译为一组标志,其他组件将被编译一组不同的标志导致不同的,不相容的行为。 只要我不重新configure ,我知道我的编译环境,即使我改变我的来源仍然是相同的。 如果我重新运行configure ,我应该首先make clean掉所有已build立的源,以确保所有东西都是一致的。

连续运行三个命令的唯一情况是用户安装程序或构build了一个包(例如,Debian的debuild或RedHat的rpmbuild)。 假设可以给包提供一个简单的configure ,通常情况下不需要打包,至less需要--prefix=/usr 。 而pacakgers在做make install部分时,就好像不得不处理假根。 由于有很多例外情况,所以使用./configure && make && make install这个规则对于很多频繁使用它的人来说是不方便的!

如果发现依赖关系丢失, configure可能会失败。

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

所以…

 #!/bin/sh if ./configure $*; then if make; then make install fi fi 

要么:

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

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

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

首先./configure并不总能find它需要的所有东西,或者在其他情况下find它需要的所有东西,但不是它可以使用的所有东西。 在这种情况下,你会想知道它(和你的./install.sh脚本无论如何将失败!)从我的angular度来看,无故障的非经典的例子是编译大型应用程序,如ffmpeg或mplayer。 这些将使用图书馆,如果他们是可用的,但将编译无论如何,如果不是,留下一些选项禁用。 问题是,你稍后会发现,它是编译时不支持某种格式或其他格式,因此要求你回去重做。

另一件事./configure有点交互式地给你select定制应用程序将安装在系统上的位置。 不同的发行版/环境有不同的约定,你可能想要坚持你的系统约定。 另外,您可能想要在本地安装(仅限于您自己)。 传统上,./configure和make步骤不能以root身份运行,而make install(除非它是为你自己安装的)必须以root身份运行。

特定的发行版经常提供脚本,以分发敏感的方式执行这个./install.shfunction,例如源代码RPMs + spec文件+ rpmbuild或slackbuilds 。

(脚注:这样说,我同意./configure; make; make install;会变得非常单调乏味。)