makefile对多个源(不包含头文件)的一个编译调用

时间:2018-08-28 00:34:02

标签: makefile

对于verilog编译,一次编译许多verilog文件是有利的-它们会被编译到数据库中(没有.o文件)。我发现我可以创建如下规则:

SOURCES := src1.v src2.v src3.v
verilog.timestamp: $(SOURCES) hdr.vh
    xmvlog $(if $(filter-out $(SOURCES),$(?)),$(SOURCES),$(filter $(?),$(SOURCES)))

这仅允许重新编译过时的文件(或在标头过期时将所有文件重新编译)。感觉很丑-有更好的方法来完成此任务吗?

2 个答案:

答案 0 :(得分:1)

正如Beta所建议的那样,$?自动变量在这种情况下可以派上用场,因为它会扩展为比目标更新的所有先决条件的列表(仅订购先决条件除外)。但是,我们仍然需要解决您的另一个问题:您的Verilog编译器不会为每个编译的Verilog源生成单个二进制文件。此外,如果自上次编译foo.v以来foo.vhdr.vh头文件已被修改,您想重新编译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。扩展配方时,make会将其传递到外壳之前,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.vhstatic pattern rule
  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)order-only prerequisite

答案 1 :(得分:0)

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

SOURCES := src1.v src2.v src3.v

verilog.timestamp: $(SOURCES) | hdr.vh
    xmvlog $?

$(SOURCES): hdr.vh
    @touch $@

(请注意,$? does not include order-only prerequisites。)