如何从目标创建 makefile 先决条件

mar*_*llm 1 makefile gnu-make

我正在使用 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 之类的函数。有什么方法可以解决这个限制吗?

Eta*_*ner 5

这些$(shell)版本是错误的,因为它们混淆了执行时间。

命令$(shell)本身在 make 解析时处理,但 的值 $@仅在目标执行时存在。

对于扩展来说也是如此$(basename)

不过,您在这里可以使用的是二次扩展

.SECONDEXPANSION:

a/%.txt: $$(notdir $$@)
        @echo '$$@: $@'
        @echo '$$<: $<'
Run Code Online (Sandbox Code Playgroud)