首页 > 解决方案 > `make single-target` 命令如何在带有 `include 指令`的 makefile 中工作

问题描述

我试图弄清楚如何makefile使用makemake sometarget指挥。据我所知,makefile它将首先读取整个makefile,然后它会尝试更新命令中指定的目标。然后如果makefileinclude directive,它会读取makefile,然后尝试更新包含文件,如果包含文件更新则重新读取makefile. 我的理解适用于make命令,但对“制作单目标”命令有问题。

也许我的理解makefile是错误的,我需要一些建议。

我在 Ubuntu 16.04 上使用 GNU Make 4.1 测试了我的玩具 makefile。

项目树是:

.
├── bar.mk
└── Makefile

0 directories, 2 files

bar.mk

$(warning "Reading from file: bar.mk") 

Makefile

include bar.mk
include BUILD.mk
$(warning Finished include)

all: test
    touch $@

test:
    @echo "target is test"

$(warning new warning)

BUILD.mk: bar.mk
    touch $@

.PHONY: clean
clean:
    rm -rf all BUILD.mk

当我使用make test命令时,结果是:

bar.mk:1: "Reading from file: bar.mk"
Makefile:3: Finished include
Makefile:11: new warning
target is test

项目树是:

.
├── bar.mk
├── BUILD.mk
└── Makefile

0 directories, 3 files

它不重新读取makefile,并且从 bash 输出中,它不执行touch BUILD.mk命令,BUILD.mk文件是如何创建的?

标签: makefile

解决方案


据我所知,makefile它将首先读取整个makefile,然后它会尝试更新命令中指定的目标。然后如果makefileinclude directive,它会读取makefile,然后尝试更新包含文件,如果包含文件更新则重新读取makefile.

不,这不太对:

  • makeinclude在处理指令之前,不会将主 makefile 读到底。相反,当它在处理 makefile 时遇到include指令时,它会中断该 makefile 的处理以立即读取并处理包含的文件。输出的前两行的顺序表明正在发生这种情况。

  • 在读取和处理整个 makefile 和所有included 文件之后,GNUmake会检查是否有任何相关的 makefile 可以并且应该被重建。(请注意,其他make实现不一定这样做。)如果是这样,那么它会执行所有此类重建,然后从头开始重新启动。

  • 只有在所有 makefile 稳定后,才会在命令行上指定目标或构建默认目标。

它不重新读取makefile,并且从 bash 输出中,它不执行touch BUILD.mk命令,BUILD.mk文件是如何创建的?

这些结论似乎完全基于报告的输出,但您似乎只查看与第二次通过 makefile 相对应的输出尾部。没有理由相信它BUILD.mk是通过make执行规则来创建的,完整的输出实际上反映了我。

不过,那只是在你make不在BUILD.mk的情况下跑步。如果您再次运行它,BUILD.mk将不会再次构建它,因为它已经存在并且比它的先决条件更新,因此整个 makefile 只会读取一次。也许您只考虑这样一次运行的输出而使自己感到困惑。


推荐阅读