Reputation: 2734
Having a Makefile
like:
list_of_targets := $(PREFIX)/target1.xv $(PREFIX)/target2.xv ...
$(list_of_targets): | dirs
$(PREFIX)/%.xv: %.sv $(src_dependencies)
$(CMD) -o $@ $(params) $^
.PHONY: dirs
dirs:
@mkdir -p $(PREFIX)
How can I make all the targets in list_of_targets
.DELETE_ON_ERROR
?
I have tried the following:
.DELETE_ON_ERROR: $(PREFIX)/%.xv
$(PREFIX)/%.xv: %.sv $(src_dependencies)
...
and
.DELETE_ON_ERROR: $(list_of_targets)
$(list_of_targets): ...
and
.DELETE_ON_ERROR: $(PREFIX)/target1.xv
This doesn't work either:
.DELETE_ON_ERROR: $(PREFIX)/target1.xv
$(PREFIX)/target1.xv: $(src_dependencies)
$(CMD) -o $@ $(params) $^
Note: I have double checked that my build command returns 2
as error code. I have tried .DELETE_ON_ERROR
with a simple test target and it works.
I have tried adding a exit 1
to the pattern I'm executing and it does delete the file. It's like if Makefile
could not detect the error returned by the compilation tool. But I'm sure it returns 2
.
Here there is a summary of my actual Makefile
. It uses Icarus Verilog
to build some fpga test benches.
PREFIX ?= ./build
SRC := ../src
SRCRV := $(SRC)/riscv
INC := ../include
TSRCRV := ./riscv
TESTUTILS := ./test-utils
RISCV_TEST_DIR := $(PREFIX)/riscv
CC := gcc
VV := iverilog
RANDOM := $(shell bash -c 'echo $$RANDOM')
tests := $(PREFIX)/mem_tb.xv \
$(PREFIX)/alu_logic_tb.xv \
$(PREFIX)/alu_add_tb.xv \
$(PREFIX)/alu_subs_tb.xv \
$(PREFIX)/alu_cmp_tb.xv
riscv_tests := $(RISCV_TEST_DIR)/lw_tb.xv \
$(RISCV_TEST_DIR)/sw_tb.xv \
$(RISCV_TEST_DIR)/or_tb.xv \
$(RISCV_TEST_DIR)/and_tb.xv \
$(RISCV_TEST_DIR)/sub_tb.xv \
$(RISCV_TEST_DIR)/xor_tb.xv \
$(RISCV_TEST_DIR)/sll_tb.xv \
$(RISCV_TEST_DIR)/srl_tb.xv \
$(RISCV_TEST_DIR)/sra_tb.xv \
$(RISCV_TEST_DIR)/beq_tb.xv \
$(RISCV_TEST_DIR)/bne_tb.xv \
$(RISCV_TEST_DIR)/blt_tb.xv \
$(RISCV_TEST_DIR)/bge_tb.xv \
$(RISCV_TEST_DIR)/bltu_tb.xv \
$(RISCV_TEST_DIR)/bgeu_tb.xv \
$(RISCV_TEST_DIR)/addi_tb.xv \
$(RISCV_TEST_DIR)/jal_tb.xv \
$(RISCV_TEST_DIR)/slt_tb.xv \
$(RISCV_TEST_DIR)/sltu_tb.xv \
$(RISCV_TEST_DIR)/jalr_tb.xv \
$(RISCV_TEST_DIR)/auipc_tb.xv \
$(RISCV_TEST_DIR)/datapath_tb.xv \
$(RISCV_TEST_DIR)/controller_tb.xv
tests_waves := $(addsuffix .vcd,$(tests))
riscv_tests_waves := $(addsuffix .vcd,$(riscv_tests))
common_src := $(SRC)/alu.sv \
$(SRC)/mem.sv \
$(SRC)/utils.sv
riscv_src := $(SRCRV)/datapath.sv \
$(SRCRV)/riscv_single_top.sv \
$(SRCRV)/controller.sv
#
# Build al tests and execute them without generating wave dumps
#
.DELETE_ON_ERROR:
test: $(tests) $(riscv_tests)
$(foreach test,$^,vvp $(test) -none;)
wavedumps: $(tests_waves) $(riscv_tests_waves)
all: test wavedumps
$(tests): | dirs
$(riscv_tests): | dirs
$(wavedumps): | dirs
$(PREFIX)/%.xv: %.sv $(common_src)
$(VV) -o $@ -g2012 -DSEED=$(RANDOM) -I$(INC) -Wall -Wno-timescale -DVCD="\"[email protected]\"" $^
$(RISCV_TEST_DIR)/%.xv: $(TSRCRV)/%.sv $(common_src) $(riscv_src)
$(VV) -o $@ -g2012 -DSEED=$(RANDOM) -I$(INC) -Wall -Wno-timescale -DVCD="\"[email protected]\"" $^
$(PREFIX)/%.xv.vcd: $(PREFIX)/%.xv
$(VVP) $<
$(RISCV_TEST_DIR)/%.xv.vcd: $(RISCV_TEST_DIR)/%.xv
$(VVP) $<
$(PREFIX)/2scomp: $(TESTUTILS)/2scomp.c dirs
$(CC) -o $@ -std=c11 $<
.PHONY: clean
clean:
@rm -rf $(PREFIX)/*
.PHONY: dirs
dirs:
@mkdir -p $(PREFIX)
@mkdir -p $(RISCV_TEST_DIR)
Let's say I execute:
make build/riscv/addi_tb.xv
The above command is successful. Then I modify riscv/addi_tb.sv
(dependency of the above target) to generate an error on purpose. I get this message:
iverilog -o build/riscv/addi_tb.xv -g2012 -DSEED=5478 -I../include -Wall -Wno-timescale -DVCD="\"build/riscv/addi_tb.xv.vcd\"" riscv/addi_tb.sv ../src/alu.sv ../src/mem.sv ../src/utils.sv ../src/riscv/datapath.sv ../src/riscv/riscv_single_top.sv ../src/riscv/controller.sv
riscv/addi_tb.sv:23: syntax error
riscv/addi_tb.sv:22: error: Invalid module instantiation
make: *** [Makefile:82: build/riscv/addi_tb.xv] Error 2
However, the above doesn't delete build/riscv/addi_tb.xv
, trying it with any of the combinations exposed above. I have tried adding .DELETE_ON_ERROR
at the beginning of the file as well.
Upvotes: 0
Views: 158
Reputation: 101041
The .DELETE_ON_ERROR:
special target acts like a standalone boolean flag
for the entire make process and all targets in it. It's not possible to apply it to a single target or subset of targets. The docs say:
If .DELETE_ON_ERROR is mentioned as a target anywhere in the makefile, then make will delete the target of a rule if it has changed and its recipe exits with a nonzero exit status, just as it does when it receives a signal. See Errors in Recipes.
It could be clearer, I suppose, but that's what it says.
Prerequisites are ignored, so I can't explain whatever behavior you are seeing, which you don't actually describe clearly.
Here's a test:
$ cat Makefile
.DELETE_ON_ERROR:
foo:
touch $@
exit 1
$ make
touch foo
exit 1
make: *** [Makefile:4: foo] Error 1
make: *** Deleting file 'foo'
What part of this doesn't work for you?
Upvotes: 1