【问题标题】:How does make file execute the dynamic targets?make 文件如何执行动态目标?
【发布时间】:2019-10-11 18:23:08
【问题描述】:

我正在尝试理解生成文件,而动态目标的使用似乎很混乱。我无法理解这些动态目标是如何在生成文件中调用的。

我尝试通过打印 shell 命令(make V=1)来调试以下内容,但我无法消除我的疑虑。我看到正在构建文件/1、文件/2、文件/3 和文件/4,但我没有看到任何循环或对该目标的多次调用。我还尝试查看https://www.gnu.org/software/make/manual/html_node/Implicit-Rules.html 文档,但也没有在那里获得任何相关信息。任何关于这种动态目标及其执行的解释都会非常有帮助。

PROGS= \
    path/to/file/1 \
    path/to/file/2
EXTRA_PROGS= \
    path/to/file/3 \
    path/to/file/4 
GO_BIN_BUILD=$(SOME_COMMAND_TO_BUILD_GO_BINARY)
GO_BIN_BUILD_DEPS=$(SOME_COMMAND_TO_BUILD_GO_DEPENDENCIES)

CTF_INTEGRATION_TESTS=$(foreach root,$(CTF_DIRS),$(root)/$(notdir $(root)).suite)
$(PROGS) $(EXTRA_PROGS) $(CTF_INTEGRATION_TESTS): $(GO_BIN_BUILD_DEPS) #the dynamic target in question.
    $(GO_BIN_BUILD)

【问题讨论】:

  • 你说的动态目标是什么意思?您是指由隐式规则(例如模式规则)创建的目标吗?我没有看到您的 makefile 中定义了任何模式规则。
  • @MadScientist,如果我犯了任何错误,请原谅我,但 $(PROGS) $(EXTRA_PROGS) $(CTF_INTEGRATION_TESTS): $(GO_BIN_BUILD_DEPS) 不是动态目标吗?使用变量值构造的目标。我对语法很陌生,如果问题包含错误的信息,我会删除它,
  • 只是“动态目标”不是 make 手册或 POSIX 规范中使用的术语,所以我不知道您的意思。
  • 您是在问目标是如何被调用的,或者规则是如何构建这些文件的?
  • @Beta,我试图了解如何调用这些规则。我的印象是这些目标就像程序中的函数一样,它们在被调用之前不会做任何事情。

标签: makefile build gnu-make


【解决方案1】:

我不认为这条规则意味着你认为它的意思:

$(PROGS) $(EXTRA_PROGS) $(CTF_INTEGRATION_TESTS): $(GO_BIN_BUILD_DEPS)
        $(GO_BIN_BUILD)

首先,make 将展开第一行中的所有变量(第二行是一个配方,因此在 make 想要构建目标之前它不会展开)。

因此,您会得到如下结果:

path/to/file/1 path/to/file/2 path/to/file/3 path/to/file/4 a/a.suite b/b.suite : dep1 dep2 dep3

其中a/a.suiteb/b.suiteforeach 函数的结果(在不知道CTF_DIRS 变量的值的情况下我无法说出实际值可能是什么)和dep1dep2 , dep3 是运行 SOME_COMMAND_TO_BUILD_GO_DEPENDENCIES 的结果,我认为这是一些 $(shell ...) 命令。

这被解释为您为每个具有相同配方的文件声明了单独的规则,如下所示:

path/to/file/1 : dep1 dep2 dep3
        $(GO_BIN_BUILD)
path/to/file/2 : dep1 dep2 dep3
        $(GO_BIN_BUILD)
path/to/file/3 : dep1 dep2 dep3
        $(GO_BIN_BUILD)
path/to/file/4 : dep1 dep2 dep3
        $(GO_BIN_BUILD)
a/a.suite : dep1 dep2 dep3
        $(GO_BIN_BUILD)
b/b.suite : dep1 dep2 dep3
        $(GO_BIN_BUILD)

【讨论】:

  • 谢谢。我假设一旦存在(构建/处理)相应的依赖项,就会调用所有这些扩展目标。在这种情况下,依赖项将是其他一些 go 文件,因此一旦这些文件存在,目标就会被构建,对吗?
  • 也许也许不会。 make 并非总是在 makefile 中构建每个目标。 Make 通过命令行选择首先构建的目标,例如,如果您运行make a/a.suite,它将只构建该文件。如果在命令行上没有请求目标,则将构建 makefile 中的 first 显式目标(及其所有先决条件)。如果在上述之前你的 makefile 中没有其他目标,那么只会构建 path/to/file/1(在构建其先决条件之后),不会有其他任何东西。
猜你喜欢
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多