makefile 中的自动依赖生成
Posted
技术标签:
【中文标题】makefile 中的自动依赖生成【英文标题】:Autodependency generation in makefiles 【发布时间】:2015-06-05 15:05:51 【问题描述】:我试图了解在给定链接中的 makefile 中如何生成自动依赖关系,但我无法理解以下代码:
DEPDIR = .deps
df = $(DEPDIR)/$(*F)
SRCS = foo.c bar.c ...
%.o : %.c
@$(MAKEDEPEND); \
cp $(df).d $(df).P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(df).d >> $(df).P; \
rm -f $(df).d
$(COMPILE.c) -o $@ $<
-include $(SRCS:%.c=$(DEPDIR)/%.P)
我是从this link. 得到的,我知道它会生成依赖文件,但我无法理解这一行的作用:
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(df).d >> $(df).P; \
有人可以解释一下这段代码吗,这么多通配符让我很困惑,我是 makefile 的新手。
【问题讨论】:
【参考方案1】:这是许多不同的命令,所以将其分解。
-e 's/#.*//'
删除以#
开头的所有内容(注释?预处理器指令?)
-e 's/^[^:]*: *//'
删除任何具有:
的所有内容,直到:
。
-e 's/ *\\$$//'
从行尾删除续行斜杠(和它们之前的空格)。
-e '/^$$/ d'
删除所有空白行。
-e 's/$$/ :/'
在每行末尾添加 :
。
这会为每个列出的依赖文件添加明确的目标,以便“知道”如何构建它们以避免“没有规则来制作目标”错误。您在an earlier section 的链接中解释了这里的推理。
简而言之,这将创建一个带有原始先决条件列表的 .P 文件,然后通过获取每一行来添加目标,删除任何现有的目标信息和任何行继续符 (\) 字符,然后添加目标分隔符 (:)结束。这适用于我在下面建议的 MAKEDEPEND 值;您可能需要修改您可能使用的其他依赖生成器的翻译。
【讨论】:
非常感谢,但是 contiki makefile 中的代码有点不同,在 contiki makefile 中,cp $(df).d $(df).P;
不是 cp $(@:.o=.d) $(@:.o=.$$$$);
。第一个只是将依赖文件复制成 .P 格式,但第二个代码是做什么的?如果你能帮助我,那就太好了。
$(@:.o=.d)
扩展为 $@
的值,结尾的 .o
替换为 .d
。同样$(@:.o=.$$$$)
扩展为$@
的值,尾随.o
替换为.$$
(shell 然后扩展为当前shell 的PID)。这是一个临时文件,可能在该规则期间使用,以避免在进程完成(原子更新)之前覆盖目标文件。【参考方案2】:
这并不是要回答您的实际问题,但既然您说您是 GNU make 的新手,我认为传播存在一种更简单的方法来处理自动依赖项不会造成任何伤害。
当今的编译器(如 GCC 或 Clang)可以在编译代码时为您执行此操作!
只需向它们传递一个预处理器标志:
# Preprocessor flags
CPPFLAGS += -MMD
并将生成的文件包含到 Makefile 中:
-include $(wildcard *.d)
你已经完成了。
您可以了解更多关于预处理器选项here for GCC,Clang 只是镜像这些选项。
一个比较好的例子也是here。
【讨论】:
你能给我一个链接,我可以在这里阅读更多关于这个标志及其工作原理的信息吗? 见我的附录。我个人每天都使用-MMD -MP
。以上是关于makefile 中的自动依赖生成的主要内容,如果未能解决你的问题,请参考以下文章