bmake 的优点
除了 bmake 是 GNU make 的 BSD 等价物这一事实之外,我无法清楚地理解它相对于 GNU make 的优势。谁能帮助我吗?我只能找到一个有点帮助的资源。感谢更多帮助或指示。
Apart from the fact that bmake is an BSD equivalent of GNU make, I could not clearly understand it's advantages over GNU make. Can anyone help me? I was able to find only one resource that was bit helpful. More help or pointers are appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
BSD make 和 GNU make 都是原始 AT&T make 的免费替代品。主要区别在于高级功能具有不同的语法。以下是如何在 BSD make 中将 shell 命令的输出放入变量中:
在 GNU make 中:
一旦有人在 Makefile 中写入
$(shell ...)
,它就需要 GNU make 。由于语法不同,有些包需要 GNU make 来构建,有些则需要 BSD make。BSD make 最初的名称是 PMake,是parallel 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 make(1) 现在始终采用并行模式,每行一个 shell。4.3BSD-Reno 将 PMake 包含为
make
和 bsd.*.mk 包含文件。这些包含文件是 BSD make 的最佳功能。 4.3 中的 src/bin/sed/Makefile BSD-Tahoe(4.3BSD-Reno 之前的版本)定义了几个目标,例如 clean、depend、install 等。 src/usr.bin/sed/Makefile在 4.3BSD-Reno 中只有四行非空行:这里 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,另一个目录中必须有第二个 Makefile。所以 OpenBSD 中的 src/usr.sbin/smtpd/ 有 6 个子目录,其中每个子目录只包含一个 Makefile,因为 smtpd 构建了 6 个程序。
除了 BSD 本身之外,很少使用 bsd.*.mk 来构建任何东西。 BSD 开发人员提供的许多可移植软件包,例如 OpenSSH(来自 OpenBSD)或 mksh(来自 MirBSD),不需要 BSD make,也不使用 bsd.*.mk 文件。
文件bsd.port.mk位于FreeBSD Ports系统的中心为 FreeBSD 构建软件包。 (NetBSD pkgsrc 将此文件称为bsd.pkg.mk。)该系统在其他脚本语言中具有竞争对手。 Homebrew 使用 Ruby。 MacPort 使用 Tcl。
过去,GNU make 比 BSD make 更可移植。由于 BSD make 是 BSD 的一部分,因此很少在其他系统上找到 BSD make。现在有用于其他系统的可移植的bmake。这是 NetBSD make 的便携版本。便携式 bmake 最常见的用途是在非 NetBSD 系统上运行 pkgsrc。我在 OS X 上运行 pkgsrc,并由 pkgsrc 引导 bmake。
BSD make and GNU make are both free replacements for the original AT&T make. The major difference is having different syntax for the advanced features. Here is how to put the output of a shell command in a variable in BSD make:
And in GNU make:
As soon as someone writes
$(shell ...)
in a Makefile, it requries GNU make. Because of the different syntax, some packages require GNU make for the build, and some require BSD make.BSD make began its life as PMake, short for parallel make. Its author, Adam de Boor, described PMake in PMake -- A Tutorial. Its merit was the new ability to run jobs in parallel, as in
make -j 3
. This parallel mode broke compatibility by running all commands for each target in a single shell, not in one shell per line. GNU make has a parallel mode, also-j
, that keeps one shell per line. NetBSD make(1) now hasmake -B -j 3
to do parallel mode with one shell per line. OpenBSD make(1) now always does parallel mode with one shell per line.4.3BSD-Reno included PMake as
make
and the bsd.*.mk include files. These include files are the best feature of BSD make. src/bin/sed/Makefile in 4.3BSD-Tahoe (the release before 4.3BSD-Reno) defines several targets like clean, depend, install, and so on. src/usr.bin/sed/Makefile in 4.3BSD-Reno has only four non-empty lines:Here bsd.prog.mk automatically sets
OBJS
tosed0.o sed1.o
, defines a sed target to link sed from those objects, defines other targets like clean, depend, install, and causesmake install
to install both sed and its manual page sed.1. There is also bsd.lib.mk for building libraries.When using bsd.*.mk, each Makefile can build only one program or library. To build another one, there must be a second Makefile in another directory. So src/usr.sbin/smtpd/ in OpenBSD has six subdirectories, where each subdirectory only contains a Makefile, because smtpd builds six programs.
It is also rare to use bsd.*.mk to build anything except BSD itself. Many portable packages from BSD developers, like OpenSSH (from OpenBSD) or mksh (from MirBSD), do not require BSD make and do not use bsd.*.mk files.
The file bsd.port.mk is at the center of FreeBSD Ports, the system that builds software packages for FreeBSD. (NetBSD pkgsrc calls this file bsd.pkg.mk.) This system has rivals in other scripting languages. Homebrew uses Ruby. MacPorts use Tcl.
In the past, GNU make was more portable than BSD make. Because BSD make was part of BSD, it is rare to find BSD make on other systems. Now there is portable bmake for other systems. This is a portable version of NetBSD make. The most common use for portable bmake is to run pkgsrc on non-NetBSD systems. I run pkgsrc on OS X, with bmake bootstrapped by pkgsrc.
我正在编写 BSD Owl,一个基于 BSD Make 的便携式构建系统。我从 2000 年开始使用 GNU Make 编写 Makefile,并很快切换到 BSD Make。让我概述一下指导我选择的原因。
文档和可用文献
这确实是要点。虽然 GNU 项目为自由软件世界提供了很棒且重要的软件,但文档并没有清楚地区分用户手册和参考手册,这是 GNU 文档的一贯特征。因此,GNU Make 文档庞大(远超过 200 页) )文档通过玩具示例对系统的各个方面进行了仔细的描述。当我使用它时,我从未发现这些示例有用,因为它们与实际用例相去甚远,并且总是需要几分钟来定位或重新定位我必须查找的信息。 GNU Make 可用的文献库确实非常庞大,但是很难找到有趣的例子来指导自己编写像 BSD 猫头鹰。也许是因为项目依赖于 automake 而不是直接编写 Makefile。也许是因为我搜索得不够仔细。
FreeBSD 方面的情况要好得多。事实上,
当然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 使用filemon(4)
监视 I/O 以确定实际的先决条件列表。I am writing BSD Owl, a portable build system based on BSD Make. I started to write Makefiles in 2000 with GNU Make and quickly switched to BSD Make. Let me outline the reasons which guided my choice.
Documentation and available literature
This is the main point, really. While the GNU project provided awesome and important piece of software to the free software world, documentation does not cleanly distinguish between user manual and reference manual, a consistent characteristic of GNU documentation. As a result, GNU Make documentation is a huge (well over 200 pages) document interleaving careful description of each aspect of the system with toy-examples. When I used it, I never found these examples useful, because they are nowhere near of actual use cases, and always needed several minutes to locate or relocate information I had to look up. The literature corpus available for GNU Make is really huge, however it very hard to find interesting examples to guide oneself in the writing of a comprehensive portable build system like BSD Owl. Maybe it is because projects rely on automake instead of writing the Makefiles directly. Maybe it is because I did not search hard enough.
The state of things was much better on the FreeBSD side. Indeed,
Of course the manual page of BSD Make is not as detailed as the manual of GNU Make, but it is much more dense and easier to use. The FreeBSD build systems are at the same time (a) a proof of concept that BSD Make can orchestrate the build of large complex projects and (b) a show-case of advanced techniques in the art of Makefile writing.
Programming features
A very funny thing is that programming features of GNU Make seem much more powerful than what BSD Make provide. Nevertheless, I found them incredibly hard to use, mostly because of expansion order, and because of the lack of useful examples. BSD Make has much less constructs and function, but they are very solid and easy to use: most of the code I need to write are conditionals and for-loops to define lists of targets and BSD Make does this very easily and reliably.
Advanced features
BSD Make has an advanced feature that GNU Make does not have — as far as I know — it is called the meta mode. The most difficult part of writing Makefiles is to correctly specify prerequisite lists in a package. Some software like
mkdep(1)
tries to automate the process by analysing sources. BSD Make takes a different approach: we write a Makefile with possibly buggy (incomplete) dependencies, but precise enough to successfully build the package. During the process, BSD Make monitors I/O usingfilemon(4)
to determine the actual list of prerequisites.BSD make 可以基于条件或循环内生成目标。有时这非常方便。
The BSD make can generate targets, based on conditionals or within loops. This comes quite handy sometimes.
每当将 GNU 实用程序与 BSD 实用程序进行比较时,请记住,大多数进行比较的人都会将许可视为一种功能或本身的错误 - 并且进行比较的开发人员中有一半赞成宽松的许可证,一半赞成 GPL -就像病毒许可证一样。这并不是说没有真正的差异(有时是有的,但通常是一种洗涤)。
bmake 不像 GNU make 那样臃肿,并且两者都与大多数手写 makefile 兼容(如果您使用 autotools 生成 makefile,autotools 能够生成与其中一个或两者兼容的 makefile)。
据我所知,bmake 唯一明显的好处是,使用它会让那些病态地害怕 GPL 的人感到高兴。但是,bmake 的作者声称这是尝试修补 pmake(正常的 BSD make)以接受 autotools 的输出的结果。考虑到我在尝试让它理解自动工具生成的 makefile 时遇到的麻烦,我怀疑这是否成功。其他人提出了其他主张,其中一些没有意义。
最后,如果您坚持 makefile 的标准元素并且不偏离 POSIX 太远,那么您使用哪个应该不会太重要。
Whenever comparing GNU utilities to BSD utilities, keep in mind that most people making comparisons will treat licensing as a feature or a bug in of itself -- and that something like half the developers making a comparison favor a permissive license and half favor a GPL-like viral license. This is not to say that there aren't real differences (sometimes there are, but often it's a wash).
bmake isn't quite as bloated as GNU make, and both are compatible with most hand-written makefiles (and if you generate makefiles with autotools, autotools is capable of generating makefiles compatible with either or both).
The only clear benefit to bmake so far as I can tell is that using it will please people who are pathologically afraid of GPLs. But, bmake's author claims that it is the result of trying to patch pmake (the normal BSD make) to accept the output of autotools. Given the trouble I've had trying to get it to understand autotools-generated makefiles, I am suspicious of how successful this was. Other people make other claims, some of which aren't meaningful.
In the end, if you stick to the standard elements of makefiles and don't stray too far from POSIX, it shouldn't matter too much which make you use.
我没有使用它,但我的理解是BSD make是一个make程序+一个标准模板库(即或多或少相当于GNU make+automake,也许还有autoconf)。
I'm not using it, but my understanding is that the BSD make is a make program + a standard library of templates (i.e. more or less the equivalent of GNU make + automake and perhaps autoconf).