为什么makefile应该有一个“安装”目标?


18

来自C和C ++的世界,大多数构建系统都有一个install目标,尤其是Makefiles(例如,GNU建议在其中)或CMake。此目标在操作系统(例如,在C:\Program Files\Windows中)中复制运行时文件(可执行文件,库等)。

这感觉确实很棘手,因为对我而言,安装程序不是构建系统的责任(实际上是操作系统/程序包管理器的责任)。这也意味着构建系统或构建脚本必须知道已安装程序的组织,以及环境变量,注册表变量,符号链接,权限等。

充其量,构建系统应该有一个release目标,该目标将输出可安装的程序(例如.deb.msi),然后请操作系统安装该程序。它还将允许用户无需键入即可卸载make uninstall

所以,我的问题是:为什么构建系统通常建议有install目标?


7
您认为“ make install”不属于构建系统的责任,但是涉及更多和特定于平台的创建可安装软件包的责任。
pmf

2
无论如何:有时您想要安装OS /软件包管理器无法处理的应用程序(因为它具有依赖关系,可能导致无法使用软件包管理器解决冲突)。make install通常安装在/usr/local(或什至/opt)这些目录不是“核心操作系统/软件包管理系统”处理的目录下。不过,不知道Windows是否具有一些类似的约定。
Bakuriu

11
“这真的很hacky。” 那么,您对C / C ++的世界有什么期望?;-)
梅森·惠勒

1
请注意,make install当我们谈论交叉编译时,这毫无意义
Hagen von Eitzen

1
@HagenvonEitzen与兼容DESTDIR
Nax'vi-vim-nvim'18年

Answers:


23

许多构建脚本或Makefile都有安装目标,因为它们是在程序包管理器存在之前创建的,并且即使在今天,许多系统也没有程序包管理器。另外,有些系统make install实际上管理软件包的首选方法。


我对make install首选系统感到好奇。除此之外,当我说makefile应该创建可安装的软件包时,我是指程序管理员。我认为几乎所有的操作系​​统都具有管理已安装程序的方式?例如,Windows没有软件包管理器(除了商店),但是仍然可以管理安装的程序(例如通过.msi软件包)
Synxis

2
@Synxis BSD,Linux和Unix都使用makefile。我不知道是否首选使用它们进行安装,但是您经常会使用make install
罗布

1
至少在debian中,首选使用checkinstallover make install的原因有两个:“您只需一步即可轻松除去软件包。” 和“您可以在多台计算机上安装生成的软件包。” -当checkinstall构建.deb并安装它时,它使用了程序包管理器...
Aaron Hall

1
@Synxis-有多个linux发行版(通常称为源发行版),其中程序包管理器通过下载tar文件来安装程序,将其解压缩然后运行make install
slebetman

1
@AaronHall如果我写错了,请纠正我,但是我得到的印象是,checkinstall调用实际上将使用 make install并监视其用于包构建的操作。
cmaster-恢复莫妮卡

5

A makefile可能没有install目标,更重要的是,您可以拥有甚至不应该安装的程序(例如,因为它们应从其build目录运行,或者因为它们可以在任何位置安装运行)。该install目标只是一个惯例为常用makefile-s。

但是,许多程序需要运行外部资源(例如:字体,数据库,配置文件等)。而且它们的可执行文件经常对这些资源做出一些假设。例如,您的bash外壳一般会读一些初始化文件/etc/bash.bashrc等....这些资源通常是在文件系统中(见票数(7)公约有关文件层次),默认文件路径是建立在你的可执行文件。

尝试在系统的大多数可执行文件上使用strings(1)。您会发现哪些文件路径是已知的。

顺便说一句,对于许多使用的GNU程序autoconf,您make install DESTDIR=/tmp/destdir/无需root 就可以运行。然后/tmp/destdir/填充了以后应打包的文件。

FWIW,我倾向于认为无法“安装” 我的bismon(GPLv3 +许可)程序(在bismon-chariot-doc.pdf报告中进行了介绍);我不确定是否能够证明这一点,也无法想象如何使该程序可安装。


2
DESTDIR或其他前缀经常被遗忘。一旦涉及到外部资源(例如动态库),就无法在不知道软件安装位置的情况下构建该软件。也非常适合安装到非标准位置,例如或。避免使用不同前缀的唯一方法是使用容器,但这当然是特定于Linux的解决方案。/opt$HOME
阿蒙

2
我已经看到了多个软件包,如果您尝试使用DESTDIR = / tmp / destdir,则在以后安装到正常位置后将无法工作,因为在路径生成中使用了DESTDIR。
约书亚

@amon:我不确定我是否会将容器描述为特定于Linux。Linux可能是容器化的常见目标平台,但是大多数现代操作系统中都存在某种形式的容器技术
凯文

1
@Joshua不应该,DESTDIR应该仅在安装步骤中相关。您应该能够: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install 并且能够将包重新定位到/opt/foo没有任何问题。
Nax'vi-vim-nvim'18年

3

我想到了几个原因。

  • 许多软件包创建软件(例如Debian构建系统和IIRC rpm)已经期望构建脚本将程序“安装”到某些特殊的子目录中。因此,它是由两个方向上的向后兼容性驱动的。
  • 用户可能希望将软件安装到本地空间,例如$HOME目录中。并非所有的程序包管理器都支持它。
  • 仍然可能有没有软件包的环境。

我说了这个问题,我说的是程序管理器,我说makefile应该创建可安装的软件包。
Synxis

1

未提及的一个原因是,很多时候您没有使用软件的当前版本或使用软件的修改版本。尝试创建自定义程序包不仅需要更多工作,而且可能会与当前创建和分发的程序包冲突。在开放源代码中,这种情况经常发生,尤其是如果您正在使用的将来版本中引入了重大更改。

假设您正在使用开源项目FOO,该项目当前版本为2.0.1,而您正在使用版本1.3.0。您不希望使用以上任何内容,因为2.0.0版本与您当前正在执行的操作不兼容,但是您急需在2.0.1中修复一个错误。使用该make install选项,您可以安装修改后的1.3.0软件,而不必担心创建软件包并将其安装在系统上。


1

Linux发行版通常将程序维护与程序包维护分开。集成软件包生成的构建系统将迫使程序维护人员也执行软件包维护。

这通常是个坏主意。发行版具有大量基础结构来验证内部一致性,为多个目标平台提供二进制文件,进行较小的更改以更好地与系统的其余部分集成,并为报告错误的用户提供一致的体验。

要直接从构建系统生成软件包,您将必须集成或绕过所有这些基础架构。集成它需要花费大量精力,而绕过它会给用户带来更糟糕的体验。

这是多方系统中常见的“食物链顶部”问题之一。如果您有多个复杂的系统,则需要一个清晰的层次结构,由哪个系统负责协调所有其他系统。

对于软件安装管理,程序包管理器是该组件,它将运行程序包的构建系统,然后通过方便的界面获取输出(“安装步骤后目录中的文件”),生成程序包并准备将其上传到存储库。

包管理器位于构建系统和存储库之间的中间位置,并且处于最佳位置,可以很好地与两者集成。

您可能已经注意到,只有很少的JavaScript程序包可以通过npm也可以通过获得apt-这主要是因为JavaScript的人们认为npm,相关的存储库将成为他们食物链的顶端,这使得几乎不可能将这些软件包作为Debian软件包发布。

戴上我的Debian Developer帽子:如果您发布开源软件,请把包装交给发行维护者。它为您和我们节省了大量工作。


您没有说为什么有安装目标,在我看来,您所写的大部分内容也都适用
于此

1
@curiousdannii,在构建系统和程序包管理器之间需要有一些接口,而这恰好是最简单的接口,因此它赢了。
西蒙·里希特

1

好了,应用程序开发人员是知道每个文件应该放在哪里的人。他们可以将其保留在文档中,并让软件包维护者阅读并为每个软件包构建一个脚本。软件包的维护者可能会误解文档,并不得不调试脚本,直到脚本起作用为止。这是低效的。对于应用程序开发人员而言,最好编写一个脚本以正确安装他编写的应用程序。

他可以使用任意名称编写安装脚本,也可以使其成为其他脚本过程的一部分。但是,有了标准的安装命令make install(约定早于软件包管理器),制作软件包就变得非常容易。如果查看用于制作Archlinux软件包PKGBUILD模板,您会看到实际打包的函数只是执行了一个make DESTDIR="$pkgdir/" install。这可能适用于大多数软件包,并且可能需要稍加修改即可使用。由于make(和自动工具)是标准配置,因此包装非常非常容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.