为啥这个makefile不构建依赖关系,而只是在使用变量时

Posted

技术标签:

【中文标题】为啥这个makefile不构建依赖关系,而只是在使用变量时【英文标题】:Why is this makefile not building the dependencies, but only when using variables为什么这个makefile不构建依赖关系,而只是在使用变量时 【发布时间】:2021-11-17 21:23:18 【问题描述】:

我有一个 makefile 可以从 yaml 文件生成一些头文件和 cpp 文件。

../api/%.h ../api/%.cpp : ../idl/%.yml
    $(info Generating api files from $<)
    $(IDL_TO_CPP_EXE) --input $< --output $(basename $@)

IDL_HEADERS=$(IDL_INPUTS:../idl/%.yml=../api/%.h)
IDL_CPPS=$(IDL_INPUTS:../idl/%.yml=../api/%.cpp)

all: $(IDL_HEADERS) $(IDL_CPPS)
    $(info The dependencies are $(IDL_HEADERS) $(IDL_CPPS))

IDL_INPUTS +=../idl/common_api/CommonTypes.yml

当我运行它时,它会输出以下内容,但不会生成 .h 和 .cpp 文件。我已经检查过它们不存在,所以这不是时间戳问题。

The dependencies are ../api/common_api/CommonTypes.h ../api/common_api/CommonTypes.cpp
make: Nothing to be done for 'all'.

如果我手动将变量扩展为以下,那么它突然开始工作!日志的控制台输出完全一样,我一直小心避免隐藏字符之类的东西。

all: ../api/common_api/CommonTypes.h ../api/common_api/CommonTypes.cpp
    $(info The dependencies are $(IDL_HEADERS) $(IDL_CPPS))

为什么这个 makefile 使用显式依赖,而不使用变量?

更新:

all: $(IDL_HEADERS) $(IDL_CPPS)
    $(info The dependencies are $^)
    $(info The dependencies should be $(IDL_HEADERS) $(IDL_CPPS))

输出:

The dependencies are
The dependencies should be ../api/common_api/CommonTypes.h ../api/common_api/CommonTypes.cpp
make: Nothing to be done for 'all'.

【问题讨论】:

首先,在all 的配方中,您应该打印$^ 而不是实际变量:自动变量$^ 包含使认为all 具有的实际先决条件。其次,您应该运行 make -d 并检查(非常长的)调试输出,看看为什么 make 认为不需要构建先决条件。 @MadScientist 使用 $^ 很有用。它告诉我它认为先决条件是空的。 【参考方案1】:

结果证明这是一个排序问题。解析all 规则时,我没有设置IDL_INPUTS 变量。 IDL_INPUTS 稍后设置,然后运行 ​​all 规则,显示新的更新值。

【讨论】:

这就是为什么确保您提出的问题中的示例真正显示您所看到的实际问题很重要的原因:在这里,如果您创建示例的方式与您的真实 makefile 相同,我们会立即告诉你出了什么问题。但是,如果您尝试运行您向我们展示的示例,它会正常工作,因此我们无能为力。

以上是关于为啥这个makefile不构建依赖关系,而只是在使用变量时的主要内容,如果未能解决你的问题,请参考以下文章

Makefile学习7————自动生成依赖关系 三颗星

Makefile - 仅当文件不存在时才建立依赖关系

当有更改时,如何在调用子构建时检查依赖关系?

Linux基础项目自动化构建工具——Makefile

为啥在 makefile 中不生成依赖项?

makefile中依赖关系如何写?