每次从源代码编译时,都会经历相同的3个步骤:
$ ./configure
$ make
$ make install
我理解,将安装过程划分为不同的步骤是有意义的,但我不明白,为什么这个星球上的每个编码器必须一次又一次地编写相同的三个命令才能得到一个任务完成。从我的观点来看,使用包含以下文本的源代码自动提供./install.sh
脚本是完全合理的:
#!/bin/sh
./configure
make
make install
为什么人们会分别做3个步骤?
答案 0 :(得分:114)
因为每一步都做不同的事情
./configure
此脚本有许多您应该更改的选项。与--prefix
或--with-dir=/foo
一样。这意味着每个系统都有不同的配置。另外./configure
检查是否应该安装缺少的库。这里有什么问题导致不构建您的应用程序。这就是为什么发行版具有安装在不同位置的软件包,因为每个发行版都认为将某些库和文件安装到某些目录会更好。据说它运行./configure
,但事实上你应该总是改变它。
例如,请查看the Arch Linux packages site。在这里,您将看到任何包使用不同的configure参数(假设它们使用autotools构建系统)。
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
这里可以使用自动工具,这意味着./configure
,make
和make install
。但另一个可以使用SCons,Python相关的设置或不同的东西。
如您所见,拆分每个状态会使维护和部署变得更加容易,特别是对于软件包维护人员和发行版。
答案 1 :(得分:28)
首先,它应该是./configure && make && make install
,因为每个都取决于前者的成功。部分原因是进化,部分原因是开发工作流程的便利性。
最初,大多数Makefile
只包含编译程序的命令,安装留给用户。额外的规则允许make install
将编译后的输出放在可能正确的位置;您可能不想这样做有很多充分的理由,包括不是系统管理员,根本不想安装它。而且,如果我正在开发软件,我可能不想安装它。我想进行一些更改并测试位于我的目录中的版本。如果我将要有多个版本,这就变得更加突出了。
./configure
会检测环境中可用的内容和/或用户是否需要确定如何构建软件。这不是需要经常更改的东西,通常需要一些时间。同样,如果我是开发人员,则不值得花时间不断重新配置。更重要的是,由于make
使用时间戳来重建模块,如果我重新运行configure
,标志可能会发生变化,现在我的构建中的一些组件将使用一组标志和其他标志进行编译使用不同的标志集可能会导致不同的不兼容行为。只要我不重新运行configure
,我就知道即使我更改了源代码,我的编译环境仍然保持不变。如果我重新运行configure
,我应首先make clean
删除所有已构建的来源,以确保统一构建内容。
连续运行三个命令的唯一情况是用户安装程序或构建程序包(例如,Debian的debuild或RedHat的rpmbuild)。并且假设包装可以是普通的configure
,这通常不是包装的情况,至少需要--prefix=/usr
。在做make install
部分时,pacakgers喜欢处理假根。由于存在许多例外情况,因此制定./configure && make && make install
规则对于很多频繁执行该规则的人来说会很不方便!
答案 2 :(得分:3)
configure
如果发现缺少依赖关系,可能会失败。
make
运行默认目标,即Makefile中列出的第一个目标。通常这个目标是all
,但并非总是如此。如果您知道那是目标,那么您只能make all install
。
所以......
#!/bin/sh
if ./configure $*; then
if make; then
make install
fi
fi
或:
./configure $* && ./make && ./make install
包含$*
,因为通常必须为configure
提供选项。
但为什么不让人们自己做呢?这真是一场如此大的胜利吗?
答案 3 :(得分:3)
首先./configure并不总能找到它需要的所有东西,或者在其他情况下它会找到它需要的一切,但不能找到它可以使用的一切。在这种情况下,您可能想知道它(并且您的./install.sh脚本无论如何都会失败!)从我的观点来看,非故障的经典示例会产生意想不到的后果,它正在编译大型应用程序,如ffmpeg或mplayer。如果它们可用,它们将使用库,但如果它们不可用则会编译,从而禁用某些选项。问题是你后来发现它是在没有支持某种格式的情况下编译的,因此要求你返回并重做它。
另一件事./configure在某种程度上交互式地为您提供了自定义应用程序将安装在系统上的位置的选项。不同的发行版/环境有不同的约定,您可能希望坚持您的系统上的约定。此外,您可能希望在本地安装它(仅适用于您自己)。传统上./configure和make步骤不是以root身份运行,而make install(除非它仅为自己安装)必须以root身份运行。
特定发行版通常提供以分发敏感方式执行此./install.sh功能的脚本 - 例如source RPMs + spec file + rpmbuild或slackbuilds。
(脚注:话虽如此,我同意./configure; make; make install;会变得非常繁琐。)