对多个源进行一个编译调用,但不包括标头



对于 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.vhdr.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头文件。如果没有,它将停止。否则,它将:

  1. 仅通过触摸它们来构建过时的标记文件(仅构建它们(可能并行(此 Makefile 是并行安全的(。
  2. 构建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

笔记:

  1. $(TAGS): .%.tag: %.v hdr.vh是静态模式规则
  2. 当然,如果您希望将标记文件与源树分开,则可以将它们存储在专用的子目录中:

    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)
    
  3. 在上一版本中,| $(TAGSDIR)是仅限订单的先决条件。

我不知道这是否更好,但是...修改标头后,您可以touch源:

SOURCES := src1.v src2.v src3.v
verilog.timestamp: $(SOURCES) | hdr.vh
xmvlog $?
$(SOURCES): hdr.vh
@touch $@

(请注意,$?不包括仅限订单的先决条件。