对于 verilog 编译,一次编译许多 verilog 文件是有利的 - 它们被编译成一个数据库(没有 .o 文件(。我发现我可以创建一个规则,例如:
SOURCES := src1.v src2.v src3.v
verilog.timestamp: $(SOURCES) hdr.vh
xmvlog $(if $(filter-out $(SOURCES),$(?)),$(SOURCES),$(filter $(?),$(SOURCES)))
这只允许重新编译过时的文件(或者在标头过期时重新编译所有文件(。感觉很丑 - 有没有更好的方法来完成这项任务?
正如 Beta 所建议的,在这种情况下,$?
自动变量可能很方便,因为它扩展为比目标更新的所有先决条件的列表(仅订单先决条件除外(。但我们仍然需要解决您的另一个问题:您的 Verilog 编译器不会为每个编译的 Verilog 源生成一个二进制文件。此外,如果自上次编译foo.v
或hdr.vh
头文件以来已修改foo.v
,您希望重新编译 Verilog 源文件foo.v
。有一种纯粹的让步方式,包括使用空文件作为标记,每个Verilog源文件一个,加上整个项目的一个:
SOURCES := $(wildcard *.v)
TAGS := $(patsubst %.v,.%.tag,$(SOURCES))
all: verilog.timestamp
.PHONY: all
$(TAGS): .%.tag: %.v hdr.vh
touch $@
verilog.timestamp: $(TAGS)
xmvlog $(patsubst .%.tag,%.v,$?)
touch $@
clean::
rm -f $(TAGS) verilog.timestamp
说明:为了构建all
(默认和虚假目标(,make 将尝试构建verilog.timestamp
。因此,它将查看是否有任何$(TAGS)
已过期,即早于相应的 Verilog 源文件或hdr.vh
头文件。如果没有,它将停止。否则,它将:
- 仅通过触摸它们来构建过时的标记文件(仅构建它们(可能并行(此 Makefile 是并行安全的(。
- 构建
verilog.timestamp
.扩展配方时,就在将其传递给 shell 之前,make 将用与刚刚重建的标记文件相对应的所有 Verilog 源文件替换$(patsubst .%.tag,%.v,$?)
,因此比verilog.timestamp
更新。最后,它会触verilog.timestamp
.
示范:
$ make clean
rm -f .src3.tag .src2.tag .src1.tag verilog.timestamp
$ make -j8
touch .src3.tag
touch .src2.tag
touch .src1.tag
xmvlog src3.v src2.v src1.v
touch verilog.timestamp
$ make -j8
make: Nothing to be done for 'all'.
$ touch src1.tag
$ make -j8
touch .src1.tag
xmvlog src1.v
touch verilog.timestamp
$ touch hdr.vh
$ make -j8
touch .src3.tag
touch .src2.tag
touch .src1.tag
xmvlog src3.v src2.v src1.v
touch verilog.timestamp
笔记:
$(TAGS): .%.tag: %.v hdr.vh
是静态模式规则当然,如果您希望将标记文件与源树分开,则可以将它们存储在专用的子目录中:
SOURCES := $(wildcard *.v) TAGSDIR := .tags TAGS := $(patsubst %.v,$(TAGSDIR)/.%.tag,$(SOURCES)) all: $(TAGSDIR)/verilog.timestamp .PHONY: all $(TAGS): $(TAGSDIR)/.%.tag: %.v hdr.vh | $(TAGSDIR) touch $@ $(TAGSDIR)/verilog.timestamp: $(TAGS) | $(TAGSDIR) xmvlog $(patsubst $(TAGSDIR)/.%.tag,%.v,$?) touch $@ $(TAGSDIR): mkdir -p $@ clean:: rm -rf $(TAGSDIR)
在上一版本中,
| $(TAGSDIR)
是仅限订单的先决条件。
我不知道这是否更好,但是...修改标头后,您可以touch
源:
SOURCES := src1.v src2.v src3.v
verilog.timestamp: $(SOURCES) | hdr.vh
xmvlog $?
$(SOURCES): hdr.vh
@touch $@
(请注意,$?
不包括仅限订单的先决条件。