在程序的makefile中,必须编写定义每个目标文件的依赖关系的规则 . 考虑目标文件 fileA.o
. 很明显,此目标文件取决于源文件 fileA.c
. 但它也将取决于此源文件包含的所有头文件 . 因此,应将以下规则添加到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
文件 .
无论如何,手动编写这样的规则是一项地狱般的任务 . 想象一下使makefile规则与源代码中的#include语句保持同步的工作 .
GNU make手册在第4.14章"Generating Prerequisites Automatically"中描述了一种自动执行此过程的方法 . 该过程从为每个源文件生成 *.d
文件开始 . 我引用:
对于每个源文件name.c,都有一个makefile name.d,它列出了目标文件name.o所依赖的文件 .
手册进行:
以下是从名为name.c的C源文件生成名为name.d的先决条件文件(即makefile)的模式规则:
%.d: %.c
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
遗憾的是,该手册没有详细解释这条规则是如何实际运作的 . 是的,它提供了所需的 name.d 文件,但为什么呢?该规则非常混淆..
在查看此规则时,我感觉它的配方只能在Linux上顺利运行 . 我对吗?有没有办法让这个配方在Windows上正确运行?
任何帮助是极大的赞赏 :-)
1 回答
退出所有错误
删除现有的dep文件(
$@
= target =%.d
)让编译器生成dep文件并输出到后缀为pid的临时文件(
$<
= first prerequisite =%.c
,$$$$
- >$$
- > pid)捕获与
$*.o
匹配的目标($*
= match stem =%
),将其替换为目标后跟依赖文件本身,输出到dep文件删除temp dep
让我们插入
foo
,CC = gcc
和CPPFLAGS = ''
来看看make完成扩展后会发生什么:shell本身会将
$$
扩展为pid,而dep文件中的最终规则将类似于请注意,这是一种非常过时的生成依赖关系的方法,如果您正在使用GCC或clang,则可以generate them作为编译本身的一部分
CPPFLAGS += -MMD -MP
.假设您有一个名为
foo
的程序:这就是你所需要的,内置规则将完成其余的工作 . 显然,如果您希望将对象文件放在不同的文件夹中,或者您希望在源树之外构建,那么事情会更复杂一些 .
vpath
指令允许您在另一个目录中运行make并在那里创建文件,例如make -f path/to/source/Makefile
.