下一篇:,上一篇:Makefile 约定   [目录][索引]


7.2.1 Makefile 的通用约定

每个 Makefile 都应该包含以下行

SHELL = /bin/sh

以避免在 `SHELL` 变量可能从环境中继承的系统上出现问题。(这在 GNU `make` 中永远不是问题。)

不同的 `make` 程序具有不兼容的后缀列表和隐式规则,这有时会造成混淆或错误行为。因此,最好显式地设置后缀列表,只使用特定 Makefile 中需要的后缀,如下所示:

.SUFFIXES:
.SUFFIXES: .c .o

第一行清除后缀列表,第二行引入此 Makefile 中可能受隐式规则约束的所有后缀。

不要假设 `.` 在命令执行的路径中。当你需要在 make 期间运行属于你的软件包的程序时,请确保如果该程序是作为 make 的一部分构建的,则使用 `./`,如果该文件是源代码中不变的部分,则使用 `$(srcdir)/`。如果没有这些前缀之一,则会使用当前搜索路径。

`./`(_构建目录_)和 `$(srcdir)/`(_源目录_)之间的区别很重要,因为用户可以使用 `configure` 的 `--srcdir` 选项在单独的目录中构建。以下形式的规则:

foo.1 : foo.man sedscript
        sed -f sedscript foo.man > foo.1

当构建目录不是源目录时将失败,因为 `foo.man` 和 `sedscript` 位于源目录中。

当使用 GNU `make` 时,依赖 `VPATH` 来查找源文件在只有一个依赖文件的情况下是可行的,因为 `make` 自动变量 `$<` 将表示源文件,无论它在哪里。(许多版本的 `make` 仅在隐式规则中设置 `$<`。)像这样的 Makefile 目标:

foo.o : bar.c
        $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o

应该改为这样编写:

foo.o : bar.c
        $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@

以便 `VPATH` 能够正常工作。当目标具有多个依赖项时,使用显式的 `$(srcdir)` 是使规则正常工作的最简单方法。例如,上面针对 `foo.1` 的目标最好这样编写:

foo.1 : foo.man sedscript
        sed -f $(srcdir)/sedscript $(srcdir)/foo.man > $@

GNU 发行版通常包含一些不是源文件的文件,例如 Info 文件,以及来自 Autoconf、Automake、Bison 或 Flex 的输出。由于这些文件通常出现在源目录中,它们应该始终出现在源目录中,而不是构建目录中。因此,更新它们的 Makefile 规则应将更新后的文件放入源目录中。

但是,如果某个文件没有出现在发行版中,那么 Makefile 不应该将其放入源目录中,因为在正常情况下构建程序不应以任何方式修改源目录。

尝试使构建和安装目标(至少)以及它们的所有子目标能够通过并行 `make` 正确工作。


下一篇:,上一篇:Makefile 约定   [目录][索引]