我正在使用 GNU make,并且正在尝试根据目标创建先决条件。我希望先决条件是目标的基本名称。所以,当我运行这个时:
make a/b/foo.txt
Run Code Online (Sandbox Code Playgroud)
它应该运行这个:
cp foo.txt a/b/foo.txt
Run Code Online (Sandbox Code Playgroud)
这些都不起作用:
a/%.txt: $(basename $@)
cp $< $@
a/%.txt: $(@F)
cp $< $@
a/%.txt: $(shell basename $@)
cp $< $@
a/%.txt: $(basename %)
cp $< $@
a/%.txt: $(shell basename %)
cp $< $@
Run Code Online (Sandbox Code Playgroud)
我已经看到 % 在目标和先决条件中使用,所以我知道将先决条件基于目标是正常的。我也在先决条件中看到了变量,所以这也是正常的。但似乎特殊变量 $@ 和 $(@F) 在先决条件中不可用,以及诸如 basename 和 shell 之类的函数。有什么方法可以解决这个限制吗?
这些$(shell)版本是错误的,因为它们混淆了执行时间。
命令$(shell)本身在 make 解析时处理,但 的值
$@仅在目标执行时存在。
对于扩展来说也是如此$(basename)。
不过,您在这里可以使用的是二次扩展:
.SECONDEXPANSION:
a/%.txt: $$(notdir $$@)
@echo '$$@: $@'
@echo '$$<: $<'
Run Code Online (Sandbox Code Playgroud)