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).
中列出的目标
在我的 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).
中列出的目标