【问题标题】:GNU Make get parent target nameGNU Make 获取父目标名称
【发布时间】:2015-07-31 18:19:38
【问题描述】:

在 gnu make 中,有没有办法获取启动整个链的原始目标并引导执行到当前配方?

.PHONY : all clean common
all: common
clean: common

common:
    @echo $@
    @echo $(MAKECMDGOALS)
    @for a in $$(ls); do \
        if [ -d $$a ]; then \
            echo -C $$a $(MAKECMDGOALS); \
            #$(MAKE) -C $$a $(MAKECMDGOALS); \
        fi; \
    done;
    @echo "Done!"

和上面的例子一样,当我运行“make all”或“make clean”时,我可以使用 $(MAKECMDGOALS) 来判断从命令行传递了哪个目标。但是,如果有人将其称为“make clean all”,那么“common”会被调用一次,我们会得到“make: Nothing to be done for `clean'”。

那么,有没有办法在每次引用它作为目标的先决条件时调用“common”,并计算出原始目标名称,以便将其传递到下一个 make 中?尽管 'common' 是一个 PHONY 目标,但它只被调用一次,我不知道为什么。

我有以下选择,但我认为第一个是最整洁的

生成文件 1

just_a_func = @echo "just_a_func from " $(1)

.PHONY : all clean
all:
    @echo $@ " enter"
    $(call just_a_func, $@)

clean:
    @echo $@ " enter"
    $(call just_a_func, $@)

生成文件 2

.PHONY : all clean common
all:
    @echo $@ " enter"
    $(MAKE) -f makefile common

clean:
    @echo $@ " enter"
    $(MAKE) -f makefile common

common:
    @echo $@ " enter"

【问题讨论】:

  • 这是需要简单委托给子目录 makefile 的一些顶级“驱动程序”makefile 的全部吗?
  • 这不应该运行common 配方两次。将touch $@ 添加到配方中是否可以解决该问题?
  • 如果有人调用make clean all,那么……你想让Make做什么?
  • @EtanReisner,你是对的,这一次运行“常见”,这是我的实际问题之一,但在原始问题中没有表达。现已更正。
  • 我不相信你可以让 make 多次运行给定的目标。在这里使用canned recipe 可能是最好的主意。 (基本上是您在 makefile 1 中的内容。)(请注意 make 调用中逗号周围的空格。它并不总是将它们剥离。)至于原始目标,您可以获得的最接近的是 target-specific variables

标签: makefile gnu-make


【解决方案1】:

这让我印象深刻,因为这里有两个问题,一个在标题中,另一个在详细说明问题时滑入。

在回答如何回答标题中的问题:获取导致更改的目标时,请使用remake

例如,使用您提供的 Makefile:

$ remake -X -f Makefile
GNU Make 4.1+dbg0.91
...
Reading makefiles...
Updating makefiles....
Updating goal targets....
 File 'PHONY' does not exist.
   File 'all' does not exist.
-> (/tmp/Makefile:5)
common:
remake<0> T
=>#0  common at /tmp/Makefile:5
  #1  all at /tmp/Makefile:2
  #2  PHONY at /tmp/Makefile:1
remake<1> quit

$ remake -X -f Makefile clean
GNU Make 4.1+dbg0.91
...
Reading makefiles...
Updating makefiles....
Updating goal targets....
 File 'clean' does not exist.
-> (/tmp/Makefile:5)
common:
remake<0> T
=>#0  common at /tmp/Makefile:5
  #1  clean at /tmp/Makefile:3
remake<1>

上面我们碰巧从我们要检查的目标开始。如果不是这种情况,您可以使用“断点”命令设置断点,然后“继续”运行,直到达到该目标。

【讨论】:

    猜你喜欢
    • 2019-10-27
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多