我在 Makefile 中定义了一些变量,当我需要构建我的软件时,我将这些变量传递给编译器。但是,我需要确保这些变量满足 Makefile 级别的某些布尔标识。我目前正在做类似以下的事情。
SHELL := /bin/bash
NUMBER := 1
all: test.x
%.x: %.c ASSERT
@echo "Compiling $< -> $@ with NUMBER=$(NUMBER)."
@gcc $< -D NUMBER=$(NUMBER) -o $@
ASSERT: Makefile
@if (( $(NUMBER) < 0 || $(NUMBER) > 4 )); then \
echo "ERROR: NUMBER must be positive and less than 4."; \
exit 1; \
fi
@echo "Ran ASSERT. No errors found."
上述设置的问题是它总是运行编译配方,即使目标已经存在并且没有任何改变。
如何正确运行 Makefile 断言,以便仅当 Makefile 变量发生变化时才创建目标?
你说过你所有的目标文件都依赖于先决条件ASSERT
。该先决条件不存在,因此 make 将尝试创建它。一旦 make 尝试创建它,它将被视为“非常新”,因此任何依赖它的目标都将被视为过时并重建。
然后下一次 make 运行时,它看到先决条件 ASSERT
不存在,所以它会尝试创建它,它会被认为是“非常新的”。等等等等
如果您不想重建所有内容,那么您的 ASSERT
配方必须在成功时创建文件 ASSERT
:
ASSERT: Makefile
@...
@touch $@
@echo "Ran ASSERT. No errors found."
请记住,如果您运行 make NUMBER=10
而不是编辑 makefile,这不会有任何影响。由于 makefile 未更改,ASSERT
不会过时,因此不会调用其配方。