除了 bmake 是 GNU make 的 BSD 等价物这一事实之外,我无法清楚地理解它相对于 GNU make 的优势。谁能帮我?我只能找到一个有点帮助的资源。更多帮助或指针表示赞赏。
5 回答
BSD make 和 GNU make 都是原始 AT&T make 的免费替代品。主要区别在于高级功能的语法不同。以下是如何将 shell 命令的输出放入 BSD make 中的变量中:
# BSD make
TODAY != date +%Y-%m-%d
在 GNU make 中:
# GNU make
TODAY = $(shell date +%Y-%m-%d)
只要有人写$(shell ...)
在 Makefile 中写入,它就需要 GNU make。由于语法不同,有些包需要 GNU make 来构建,有些则需要 BSD make。
BSD make 以PMake开始它的生命,是并行 make的缩写。它的作者 Adam de Boor 在PMake - A Tutorial中描述了 PMake 。它的优点是并行运行作业的新能力,如make -j 3
. 这种并行模式破坏了兼容性,因为在单个 shell 中运行每个目标的所有命令,而不是在每行一个 shell 中。GNU make 也有一种并行模式,-j
即每行保留一个 shell。NetBSD make(1)现在必须make -B -j 3
使用每行一个 shell 进行并行模式。OpenBSD 制作(1)现在总是使用每行一个 shell 的并行模式。
4.3BSD-Reno 包含 PMake asmake
和 bsd.*.mk 包含文件。这些包含文件是 BSD make 的最佳特性。4.3BSD-Tahoe(4.3BSD-Reno 之前的版本)中的 src/bin/sed/Makefile定义了几个目标,如 clean、depend、install 等。4.3BSD-Reno 中的 src/usr.bin/sed/Makefile只有四个非空行:
# @(#)Makefile 4.6 (Berkeley) 5/11/90
PROG= sed
SRCS= sed0.c sed1.c
.include <bsd.prog.mk>
这里bsd.prog.mk自动设置OBJS
为sed0.o sed1.o
,定义一个 sed 目标以从这些对象链接 sed,定义其他目标,如 clean、depend、install 和make install
安装 sed 及其手册页 sed.1 的原因。还有bsd.lib.mk用于构建库
使用 bsd.*.mk 时,每个 Makefile 只能构建一个程序或库。要构建另一个,另一个目录中必须有第二个 Makefile。所以OpenBSD 中的 src/usr.sbin/smtpd/有六个子目录,每个子目录只包含一个 Makefile,因为 smtpd 构建了六个程序。
也很少使用 bsd.*.mk 来构建除 BSD 本身之外的任何东西。许多来自 BSD 开发人员的可移植软件包,例如 OpenSSH(来自 OpenBSD)或 mksh(来自 MirBSD),不需要 BSD make 并且不使用 bsd.*.mk 文件。
文件bsd.port.mk位于FreeBSD Ports的中心,该系统为 FreeBSD 构建软件包。(NetBSD pkgsrc称这个文件为 bsd.pkg.mk。)这个系统在其他脚本语言中有竞争对手。Homebrew 使用 Ruby。MacPorts 使用 Tcl。
过去,GNU make 比 BSD make 更便携。因为 BSD make 是 BSD 的一部分,所以很少在其他系统上找到 BSD make。现在有用于其他系统的便携式 bmake 。这是 NetBSD make 的可移植版本。便携式 bmake 最常见的用途是在非 NetBSD 系统上运行 pkgsrc。我在 OS X 上运行 pkgsrc,bmake 由 pkgsrc 引导。
我正在编写BSD Owl,一个基于 BSD Make 的可移植构建系统。我在 2000 年开始使用 GNU Make 编写 Makefile,并迅速切换到 BSD Make。让我概述一下指导我选择的原因。
文档和可用文献
这才是重点,真的。虽然 GNU 项目为自由软件世界提供了令人敬畏和重要的软件,但文档并没有清楚地区分用户手册和参考手册,这是 GNU 文档的一贯特征。因此,GNU Make 文档是一个巨大的(超过 200 页)文档将系统各个方面的仔细描述与玩具示例交织在一起。当我使用它时,我从未发现这些示例有用,因为它们与实际用例相去甚远,并且总是需要几分钟来定位或重新定位我必须查找的信息。可用于 GNU Make 的文献语料库非常庞大,但是很难找到有趣的示例来指导自己编写像BSD Owl这样的全面可移植构建系统。也许是因为项目依赖于 automake 而不是直接编写 Makefile。也许是因为我没有足够努力地寻找。
FreeBSD 方面的情况要好得多。的确,
- Adam de Boor有一个规范的教程或用户手册。
- 手册页可作为参考手册使用,不到 30 页。
- FreeBSD 构建系统和 FreeBSD 移植系统是手写的 makefile 语料库。
当然 BSD Make 的手册页不如 GNU Make 的手册详细,但它更密集,更易于使用。FreeBSD 构建系统同时 (a) BSD Make 可以协调大型复杂项目的构建的概念证明,以及 (b) Makefile 编写艺术中先进技术的展示。
编程功能
一个非常有趣的事情是 GNU Make 的编程功能似乎比 BSD Make 提供的强大得多。然而,我发现它们非常难以使用,主要是因为扩展顺序,并且因为缺乏有用的例子。BSD Make 的结构和功能要少得多,但它们非常可靠且易于使用:我需要编写的大部分代码都是用于定义目标列表的条件和 for 循环,而 BSD Make 非常容易和可靠地做到这一点。
高级功能
BSD Make 有一个 GNU Make 所没有的高级特性——据我所知——它被称为元模式。编写 Makefile 最困难的部分是正确指定包中的先决条件列表。一些软件mkdep(1)
试图通过分析来源来自动化这个过程。BSD Make 采用了不同的方法:我们编写了一个可能有错误(不完整)依赖关系的 Makefile,但足够精确以成功构建包。在此过程中,BSD Make 监视 I/O 使用filemon(4)
以确定实际的先决条件列表。
BSD make 可以根据条件或在循环内生成目标。这有时很方便。
每当将 GNU 实用程序与 BSD 实用程序进行比较时,请记住,大多数进行比较的人会将许可视为一项特性或本身的错误——并且在进行比较的开发人员中,有一半支持许可许可,另一半支持 GPL——像病毒许可。这并不是说没有真正的差异(有时有,但通常是洗礼)。
bmake 不像 GNU make 那样臃肿,并且两者都与大多数手写的 makefile 兼容(如果您使用 autotools 生成 makefile,autotools 能够生成与其中一个或两者兼容的 makefile)。
据我所知,bmake 唯一明显的好处是使用它会让那些病态地害怕 GPL 的人高兴。但是,bmake 的作者声称这是尝试修补 pmake(正常的 BSD make)以接受 autotools 输出的结果。考虑到我试图让它理解 autotools 生成的 makefile 时遇到的麻烦,我怀疑这是多么成功。其他人提出其他主张,其中一些没有意义。
最后,如果您坚持使用 makefile 的标准元素并且不要偏离 POSIX 太远,那么使用哪个并不重要。
我没有使用它,但我的理解是 BSD make 是一个 make 程序 + 一个标准模板库(即或多或少相当于 GNU make + automake 和 autoconf)。