在Makefile中,*.o/.suffixes的含义是什么?

22

我在许多Makefile中看到了像这样的命令,但我不太理解:

vpath.o: make.h config.h getopt.h gettext.h dep.h

.SUFFIXES:
.SUFFIXES:  .f  .o
#
# %------------------%
# | Default command. |
# %------------------%
#
.DEFAULT:
    @$(ECHO) "Unknown target $@, try:  make help"
#
# %-------------------------------------------%
# |  Command to build .o files from .f files. |
# %-------------------------------------------%
#
.f.o:
    @$(ECHO) Making $@ from $<
    @$(FC) -c $(FFLAGS) $<

*.o*.suffixes是什么意思?

注意:这两个命令来自脚本的不同部分。

5个回答

31

你问题中的第一行只是一个标准的Makefile规则。

vpath.o: make.h config.h getopt.h gettext.h dep.h
.o文件是目标文件;它是源文件和最终编译二进制文件之间的中间产品。它包含已编译的代码,但尚未链接成完整库或二进制文件。这条规则只是说明vpath.o依赖于make.hconfig.h等文件,并且每次更改这些文件时都应该重新编译。构建vpath.o所需的命令应在后续行中按制表符缩进。(如果我重复了您已经知道的内容,请原谅; 我不确定您对第一行哪部分有疑问)。 .SUFFIXES不是实际的文件后缀;它只是makefile中用于配置“后缀规则”的特殊规则。
后缀规则是形式为.a.b的规则,就像您在.f.o规则中看到的那样。它们是一种方式,告诉make,每当您看到一个,比如说,.f文件(源文件),您可以通过遵循那个规则从中生成一个.o文件(目标文件),其中$<表示源文件,$@表示目标文件。 .SUFFIXES "目标"是一种定义后缀规则中可以使用哪些后缀的方式。如果没有前提条件使用它,它会清除内置后缀列表;当使用前提条件时,它将这些添加到其已知后缀列表中,这些后缀可以用于后缀规则。
在GNU make 中,您可以使用更强大、更清晰的%来形成模式规则,例如:
%.o: %.c
    gcc -c -o $@ $<

这相当于后缀规则:

.c.o:
    gcc -c -o $@ $<

请查看GNU Make文档获取更多信息(其中还提到了GNU扩展),或者查看Single Unix规范/POSIX以获取常见且可移植的语法。


是的,%语法可以说更简洁而且毋庸置疑更强大。除了GNU make之外,其他版本的make也支持它(我知道Digital Mars make支持它)。 - Robert Fraser

4

4
如前所述,行.SUFFIXES:将删除所有已知的后缀。这样做是为了:

  • 默认后缀不会干扰您的特殊后缀。
  • 不同的make程序具有不兼容的后缀列表和隐式规则,有时会导致混乱或错误行为 Makefile通用约定

如果您使用GNU make,则最好使用模式规则而不是后缀规则,因为它们(后缀规则)存在于兼容性原因。此外,后缀规则不能拥有自己的前提条件。

因此,您将以以下形式重写后缀规则:

.f.o:
...

作为以下形式的模式规则:

%.o:%.f:
...

请注意,在后缀规则中,前提条件前缀在目标后缀之前出现,而在模式规则中,情况相反(并且更少令人困惑)。

如果您计划更多地使用makefile,请查看书籍使用GNU Make管理项目,该书可以在线获取。


3
第一行.SUFFIXES清除所有“内置”后缀的信息;第二行重新设置后缀.f(传统的Fortran)和.o(目标文件)。当没有其他规则可用时,将使用.DEFAULT规则。最后一条规则使用$(FC)编译器将.f文件编译为.o文件。符号@表示不要回显命令,并使我感到烦恼(我更喜欢看到用于编译的命令)。
在makefile中提取不到*.suffixes,因此无法告诉您它的含义。

0

你也可以使用后缀规则链,例如以下规则,从 gnuplot 文件生成 tex 然后 pdf:

.SUFFIXES: .plt .tex .pdf

# (notice that there should be tabs prefixing the lines after the rule)
%.tex: %.plt
gnuplot -e " \
set format '$$%g$$' ; \
set terminal epslatex standalone color ; \
set output '$@' \
" $<

%.pdf: %.tex
pdflatex $<

all: test.pdf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接