c++ - 为什么makefile强制覆盖目标
问题描述
我需要通过这种方式调用 make:
bin ?= bar
all: ${bin}
objects := 1.o 2.o
$(objects): %.o: ./%.cpp
▸ g++ -c $< -o $@
foo: FORCE
▸ bin=foo\
▸ ▸ $(MAKE)·
${bin}: ${objects}
▸ g++ ${objects} -o ${bin}
FORCE:
即默认目标是 bar,但 foo 目标再次调用 make 并使用 bin=foo 变量。问题是当目标 foo 被覆盖时(在第二次调用期间)它总是运行(链接)如果我使用另一个目标名称可以避免这种情况:
foo_bla_bla: FORCE
▸ bin=foo\
▸ ▸ $(MAKE)
在这种情况下, foo 文件将仅在目标文件发生变化时才被链接(对,我需要)。但是我需要为此目标使用相同的名称来调用
make foo
并通过这种方式获取 foo bin。那么为什么覆盖 foo 目标需要伪造链接呢?
解决方案
您不会通过丢弃有关目标的完整信息来覆盖目标。您正在覆盖目标的配方:丢弃旧配方并用新配方替换它。您将收到关于此的警告(最好在您的问题中显示这一点)。
目标的先决条件foo
仍然保留,因此FORCE
第一个目标的先决条件foo
仍然存在。因此,foo
目标总是被重建。
这不是处理这个问题的好方法。更好一点的是检查的值,bin
如果不是,则只定义递归目标foo
:
ifneq ($(bin),foo)
foo: FORCE
▸ $(MAKE) bin=foo
endif
但比这更好的是根本不使用递归。你为什么需要它?为什么不直接说:
bar foo: ${objects}
▸ g++ ${objects} -o ${bin}
推荐阅读
- python - 我如何用 pafy 为进度条制作线程
- c# - 使用 C# 在图像中查找表
- java - 无法从 START_OBJECT 令牌中反序列化 java.io.File 的实例
- laravel - 如何正确设置文件发布 PhpUnit
- java - @PreUpdate 上的 Stackoverflow
- .htaccess - 添加 www 的 htaccess 条件。仅当它在 url 中不包含字符串时才到 url
- ios - 打开 VC 并从 Firebase 获取数据时应用“冻结”
- fabricjs - fabricjs - 将 SVG 内联样式应用于对象
- python - 在 Spark 中将多个字符串映射到一个键
- django - 在 Django 中使用 for 循环保存多个列值