首页 > 解决方案 > makefile 中的百分比运算符不适用于子文件夹

问题描述

在我的Makefile中,我有以下目标:

%: %.sv
  $(VCC) $(VFLAGS) $^

当前目录中具有扩展名.sv(系统verilog)的任何文件都在此捕获。如果我运行以下命令,这将非常有效:

make alu

我为构建模拟C++文件设置了目标,这些文件依赖于上面的特定系统 verilog 目标:

$(BUILD_DIR)/sim_alu: sim_alu.cc alu | $(BUILD_DIR)
   $(CC) $(STD) $(CFLAGS) -o $@ $< -Wall -Wno-sign-compare

当我运行以下命令时,这些工作正常:

make build/sim_alu

但是扩展这一点,同样Makefile,如果我用这个替换上面的目标,它会失败并出现错误“No rule to make target”:

$(BUILD_DIR)/sim_%: sim_%.cc % | $(BUILD_DIR)
   $(CC) $(STD) $(CFLAGS) -o $@ $< -Wall -Wno-sign-compare

我究竟做错了什么?

编辑:仅供参考,BUILD_DIR创建如下:

$(BUILD_DIR):                                                                                                                          
   mkdir -p $@

标签: makefile

解决方案


您的:

%: %.sv
    $(VCC) $(VFLAGS) $^

rule 是一个非终端匹配任何模式规则。来自 GNU make 文档:

非终端匹配任何规则不能应用于隐式规则的先决条件。

这就是为什么您的第二个模式规则不适合构建的原因$(BUILD_DIR)/sim_alu:它的先决条件之一 ( alu) 是您的 match-anything 模式规则的目标。但是 match-anything 模式规则不适用,并且您没有其他规则(无论是否隐含)来构建alu. 所以 make 不知道如何构建alu,因此也不知道如何构建$(BUILD_DIR)/sim_alu

Match-anything 模式规则必须小心使用,因为它们的处理方式与其他模式规则不同。在您的回答中,您使用了静态模式规则:

$(MODULES): % : %.sv
    $(VCC) $(VFLAGS) $^

而不是 match-anything 模式规则,这解决了这个问题。静态模式规则仅匹配 $(MODULES) 中列出的目标。


推荐阅读