我想使用静态模式规则来指定一类目标的默认配方,但为一些特定目标覆盖该配方。
这是一个简单的例子,说明了我正在尝试做的事情。对于包含文件“test.py”的每个目录,我想调用命令“run_test.py”,除非该目录名为“one”,否则我想调用一组不同的命令:
TESTS := $(shell find * -name "test.py" | xargs -I {} dirname {})
.PHONY: $(TESTS)
all: $(TESTS)
$(TESTS): %:
python run_test.py $@
one:
python run_test.py $@ mode=1
python run_test.py $@ mode=2
python check_results.py $@
Run Code Online (Sandbox Code Playgroud)
这有效,但会发出警告:
$ make
Makefile:12: warning: overriding commands for target `one'
Makefile:9: warning: ignoring old commands for target `one'
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以做到这一点,或者消除警告吗?
不,你不能那样做。静态模式规则实际上不是模式规则:相反,它只是编写大量显式规则的简写。
如果您想让大多数目标使用一个配方,但少数目标使用另一个配方,则应该为“大多数”目标定义一个真正的模式规则,而不是静态模式规则,然后使用显式规则来覆盖:
%.o: %.cc
g++ -c $< -o $@
test.o: test.cc
g++ -Wall -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
为什么要使用静态模式规则而不是常规模式规则?
ETA您还可以使用特定于目标的变量:
CFLAGS =
test.o: CFLAGS = -Wall
$(OBJS): %.o: %.cc
g++ $(CFLAGS) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
ETA2好的,这与您原来的示例有很大不同。
我可以看到你有两个明显的选择。一是从名单中删除特殊目标;就像是:
SPECIAL_TESTS := one
TESTS := $(patsubst %/test.py,%,$(shell find * -name "test.py"))
.PHONY: all $(TESTS)
all: $(TESTS)
$(filter-out $(SPECIAL_TESTS),$(TESTS)):
python run_test.py $@
$(SPECIAL_TESTS):
python run_test.py $@ mode=1
python run_test.py $@ mode=2
python check_results.py $@
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用特定于目标的变量来定义整个配方,如下所示:
TEST_RECIPE = python run_test.py $@
one: TEST_RECIPE = python run_test.py $@ mode=1 \
&& python run_test.py $@ mode=2 \
&& python check_results.py $@
TESTS := $(patsubst %/test.py,%,$(shell find * -name "test.py"))
.PHONY: all $(TESTS)
all: $(TESTS)
$(TESTS):
$(TEST_RECIPE)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2046 次 |
| 最近记录: |