每次从源代码编译内容时,您都将经过相同的3个步骤:
$ ./configure
$ make
$ make install
我知道,将安装过程分为不同的步骤是有意义的,但是我不明白,为什么这个星球上的每个编码人员都必须一次又一次地编写相同的三个命令才能完成一项工作。以我的观点,完全./install.sh
自动将包含以下文本的脚本与源代码一起交付是完全有意义的:
#!/bin/sh
./configure
make
make install
人们为什么要分别执行这三个步骤?
每次从源代码编译内容时,您都将经过相同的3个步骤:
$ ./configure
$ make
$ make install
我知道,将安装过程分为不同的步骤是有意义的,但是我不明白,为什么这个星球上的每个编码人员都必须一次又一次地编写相同的三个命令才能完成一项工作。以我的观点,完全./install.sh
自动将包含以下文本的脚本与源代码一起交付是完全有意义的:
#!/bin/sh
./configure
make
make install
人们为什么要分别执行这三个步骤?
Answers:
因为每一步都做不同的事情
./configure
该脚本具有许多应更改的选项。喜欢--prefix
或--with-dir=/foo
。这意味着每个系统都有不同的配置。还./configure
检查缺少应安装的库。此处的任何错误都会导致无法构建您的应用程序。这就是发行版将软件包安装在不同位置的原因,因为每个发行版都认为将某些库和文件安装到某些目录会更好。它据说可以运行./configure
,但实际上您应该始终对其进行更改。
例如,查看Arch Linux软件包站点。在这里,您会看到任何包都使用了不同的configure参数(假设它们在构建系统中使用了自动工具)。
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相关的设置或其他工具。
如您所见,分裂每个状态使维护和部署变得更加容易,尤其是对于软件包维护者和发行版。
make install
只需将各种资源安装到预定义的位置即可。如果只关心可执行文件,则可以使用build目录中的可执行文件,并将build dir添加到PATH。
首先,应该是./configure && make && make install
因为每个人都取决于前者的成功。部分原因是发展,部分原因是开发流程的便利。
最初,大多数Makefile
s仅包含用于编译程序的命令,安装留给用户使用。一条额外的规则允许make install
将编译后的输出放置在可能正确的位置。仍然有很多充分的理由使您可能不想这样做,包括不是系统管理员,根本不想安装它。此外,如果我正在开发软件,则可能不想安装它。我要进行一些更改并测试目录中的版本。如果我要准备多个版本,这将变得更加突出。
./configure
并检测环境中可用的和/或用户期望的内容,以确定如何构建软件。这不是需要经常更改的事情,并且通常不会花费一些时间。同样,如果我是一名开发人员,则不值得花时间不断地进行配置。更重要的是,由于make
使用时间戳记来重建模块,因此如果重新运行configure
,则标志可能会更改,现在构建中的某些组件将使用一组标志进行编译,而使用其他标志组进行编译的其他组件可能会导致不同的,不相容的行为。只要不重新运行configure
,就可以知道即使更改源也可以保持编译环境不变。如果我重跑configure
,我应该make clean
首先,删除任何已构建的资源以确保事物被统一构建。
连续运行这三个命令的唯一情况是用户安装程序或构建软件包时(例如Debian的debuild或RedHat的rpmbuild)。并且假设可以给包装袋一个普通configure
的包装,通常情况下,至少--prefix=/usr
在需要包装的情况下,这种包装不是通常的情况。pacakgers喜欢在做make install
零件时要处理假根。由于存在许多例外情况,./configure && make && make install
所以对于很多经常执行此规则的人来说,制定规则将很不便!
&&
!
首先,./configure并不总是找到它需要的所有内容,或者在其他情况下,它找到了它需要的所有内容,但没有找到它可以使用的所有内容。在那种情况下,您可能想知道它(而且您的./install.sh脚本还是会失败!)从我的角度来看,经典失败的非预期示例是编译大型应用程序,例如ffmpeg或mplayer。这些将使用库(如果可用),但如果不可用则将进行编译,从而禁用某些选项。问题在于,您随后会发现它是在不支持某种格式或另一种格式的情况下进行编译的,因此您需要返回并重做它。
./configure以交互方式进行的另一件事是使您可以选择自定义应用程序在系统上的安装位置。不同的发行版/环境具有不同的约定,并且您可能希望遵循系统上的约定。另外,您可能想在本地安装(仅适用于您自己)。传统上,./configure和make步骤不是以root身份运行,而make install(除非它是完全为您自己安装的)必须以root身份运行。
特定的发行版通常会提供脚本,这些脚本以一种对发行版敏感的方式执行此./install.sh功能-例如,源RPM +规范文件+ rpmbuild或slackbuilds。
(注:话虽如此,我同意./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
是GNU Automake工具箱的一部分,它是Make的一个附加组件。Make已经存在很多年了,并且做得很好。也就是说,人们想出了其他方法来处理制作过程。蚂蚁和cmake有他们的追随者。但是构建过程的各个部分(例如配置,构建和安装)仍然都是单独的命令。