关于GNU make依赖文件* .d [英] About the GNU make dependency files *.d

查看:237
本文介绍了关于GNU make依赖文件* .d的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在程序的makefile中,必须编写规则来定义每个目标文件的依赖性.考虑目标文件fileA.o.显然,此目标文件取决于源文件fileA.c.但这也将取决于此源文件包含的所有头文件.因此,以下规则应添加到生成文件中:

In the makefile of a program, one has to write rules that define the dependencies of each object file. Consider the object file fileA.o. It is obvious that this object file depends on the source file fileA.c. But it will also depend on all the header files that this source file includes. So the following rule should be added to the makefile:

    # This rule states that fileA.o depends on fileA.c (obviously), but also
    # on the header files fileA.h, fileB.h and fileC.h
    fileA.o: fileA.c fileA.h fileB.h fileC.h

请注意,该规则没有配方.可以在其中添加一个配方,但是严格来说这是没有必要的,因为GNU make可以依靠隐式规则(带有配方)将*.c文件编译为*.o文件.

Note that the rule has no recipe. One could add a recipe to it, but it is strictly speaking not necessary, because GNU make can rely on an implicit rule (with recipe) to compile a *.c file into a *.o file.

无论如何,手动编写此类规则是一项艰巨的任务.想象一下使makefile规则与源代码中的#include语句保持同步的工作.

Anyway, writing such rules manually is a hellish task. Just imagine the work to keep the makefile rules in sync with the #include statements from the source code.

GNU make手册在第4.14章自动生成先决条件"中描述了一种自动执行此过程的方法.该过程开始于为每个源文件生成一个*.d文件.我引用:

The GNU make manual describes in chapter 4.14 "Generating Prerequisites Automatically" a methodology to automate this procedure. The procedure starts with the generation of a *.d file for each source file. I quote:

对于每个源文件 name.c ,都有一个生成文件 name.d ,其中列出了目标文件 name.o 所依赖的文件

For each source file name.c there is a makefile name.d which lists what files the object file name.o depends on.

手册进行:

这是一种模式规则,可从名为 name.c 的C源文件中生成名为 name.d 的必备软件文件(即makefile):

Here is the pattern rule to generate a file of prerequisites (i.e, a makefile) called name.d from a C source file called name.c :

    %.d: %.c
        @set -e; rm -f $@; \
         $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
         sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
         rm -f $@.$$$$

遗憾的是,该手册并未详细说明此规则的实际工作方式.是的,它提供了所需的 name.d 文件,但是为什么呢?规则很模糊.

Sadly, the manual does not explain in detail how this rule actually works. Yes, it gives the desired name.d file, but why? The rule is very obfuscated..

查看此规则时,我感到它的配方只能在Linux上平稳运行.我对吗?有没有办法使该配方也能在Windows上正确运行?

When looking at this rule, I get the feeling that its recipe will only run smoothly on Linux. Am I right? Is there a way to make this recipe run correctly on Windows as well?

非常感谢您的帮助:-)

Any help is greatly appreciated :-)

推荐答案

退出所有错误

@set -e;

删除现有的dep文件($@ =目标= %.d)

Delete existing dep file ($@ = target = %.d)

rm -f $@;

让编译器生成dep文件并输出到后缀为shell pid的临时文件中($< =第一个先决条件= %.c$$$$-> $$-> pid)

Have the compiler generate the dep file and output to a temporary file postfixed with the shell pid ($< = first prerequisite = %.c, $$$$ -> $$ -> pid)

$(CC) -M $(CPPFLAGS) $< > $@.$$$$;

捕获与目标匹配的目标$*.o($* =匹配词根= %),将其替换为目标,然后是依赖文件本身,输出到dep文件

Capture the target matching $*.o ($* = match stem = %), replace it with the target followed by the dependency file itself, output to dep file

sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \

删除温度单位

rm -f $@.$$$$

让我们插入fooCC = gccCPPFLAGS = '',看看make完成扩展后会发生什么:

Let's plug in foo, CC = gcc, and CPPFLAGS = '' to see what happens after make has finished expanding stuff:

foo.d: foo.c
    @set -e; rm -f foo.d; \
     gcc -M foo.c > foo.d.$$; \
     sed 's,\(foo\)\.o[ :]*,\1.o foo.d : ,g' < foo.d.$$ > foo.d; \
     rm -f foo.d.$$

shell本身会将$$扩展为pid,而dep文件中的最终规则将类似于

The shell itself will expand $$ to the pid, and the final rule in the dep file will look something like

foo.o foo.d : foo.c foo.h someheader.h


请注意,这是生成依赖关系的一种非常过时的方法,如果您使用的是GCC或clang,则可以


Note that this is a pretty outdated way of generating dependencies, if you're using GCC or clang you can generate them as part of compilation itself with CPPFLAGS += -MMD -MP.

假设您有一个名为foo的程序:

Say you have a program called foo:

objs := foo.o bar.o
deps := $(objs:.o=.d)

vpath %.c $(dir $(MAKEFILE_LIST))

CPPFLAGS += -MMD -MP

foo: $(objs)

.PHONY: clean
clean: ; $(RM) foo $(objs) $(deps)

-include $(deps)

这就是您所需要的,内置规则将完成其余工作.显然,如果要将目标文件放在不同的文件夹中,或者要在源代码树之外进行构建,事情会有些复杂.

That's all you need, the built-in rules will do the rest. Obviously things will be a little more complicated if you want the object files in a different folder or if you want to build outside the source tree.

vpath指令允许您在其他目录中运行make并在其中创建文件,例如make -f path/to/source/Makefile.

The vpath directive allows you to run make in a different directory and have the files created there, e.g. make -f path/to/source/Makefile.

这篇关于关于GNU make依赖文件* .d的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆