makefile 中的百分比运算符不适用于子文件夹

Percent operator in makefile isn't working for subfolder

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

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

当前目录下任何扩展名为.sv(system 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 中,如果我用这个替换上面的目标,它会失败并显示错误“没有规则来制作目标”:

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

我做错了什么?

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

$(BUILD_DIR):                                                                                                                          
   mkdir -p $@

好的,我不知道为什么,但它突然开始工作了。

如果对其他人有帮助,这是我的全部Makefile:

CC=g++    
VCC=verilator    
VFLAGS=-Wall -cc -build --trace    
STD=-std=c++17    
CFLAGS=-I$(VERILATOR_ROOT)/include -Iobj_dir obj_dir/*.o $(VERILATOR_ROOT)/include/verilated.cpp $(VERILATOR_ROOT)/include/verilated_vcd_c.cpp        
BUILD_DIR=build    
MODULES=alu comp zero_ext pcmodule pcadder extend register_file inst_rom    
SIMS=sim_alu sim_zero_ext sim_extend sim_register_file sim_inst_rom                
                                                                                   
.PHONE: all clean $(BUILD_DIR)                                                     
                                                                                   
all: $(MODULES) $(addprefix $(BUILD_DIR)/,$(SIMS))                                 
                                                                                  
$(BUILD_DIR)/sim_%: sim_%.cc % | $(BUILD_DIR)                                     
  $(CC) $(STD) $(CFLAGS) -o $@ $< -Wall -Wno-sign-compare                         
                                                                                  
$(MODULES): % : %.sv                                                  
  $(VCC) $(VFLAGS) $^                                                   
                                                                        
$(BUILD_DIR):                                                           
  mkdir -p $@                                                           
                                                                        
clean:                                                                  
  rm -rf build; rm -rf obj_dir      

你的:

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

规则是一个非终结符match-anything pattern rule。来自 GNU make 文档:

A non-terminal match-anything rule cannot apply to a prerequisite of an implicit rule.

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

必须谨慎使用“任意匹配”模式规则,因为它们的处理方式与其他模式规则不同。在您的回答中,您使用了静态模式规则:

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

而不是匹配任何模式规则,这解决了问题。静态模式规则仅匹配 $(MODULES).

中列出的目标