makefile处理源文件对头文件的依赖

1.从HelloWorld开始,假设有如下代码hello.c:

#include <stdio.h>
#include "a.h"
#include "b.h"
#include "hello.h"

int main(int argc, char* argv[])
{
    printf("hello world.\n");
    return 0;
}

接着上一篇简单理解makefile我们有如下式子:

CC     = gcc
TARGET = hello
objs   = hello.o a.o b.o

$(TARGET) : $(objs)
    $(CC) -o $@ $^

在上述式子中只有修改源文件才会触发编译,修改头文件是没有反应的。
因为没有添加对.h文件的依赖关系,如下:

hello.o : a.h b.h hello.h

而在实际工作中代码的依赖关系是很复杂的,不可能每个都手动添加,因此需要自动推导依赖关系。

手动执行下述命令:

gcc -MM hello.c
输出结果为
hello.o: hello.c a.h b.h hello.h c.h d.h

2. 有了自动生成依赖关系的命令gcc -MM,我们就要想办法让makefile在执行的过程自动生成依赖,不过在此之前要先掌握两个表达式:

src   = hello.c a.c b.c  #定义变量src
objs  = $(src:.c=.o)     #将变量src中的.c替换成.o,等价于 objs = hello.o a.o b.o
src_d = $(src:.c=.d)     #将变量src中的.c替换成.d
$(变量名:.c=.d) 就是我们要掌握的第一个表达式,第二个为include:
include $src_d     #等价于 include hello.d a.d b.d 
include表示makefile在执行时去寻找hello.d a.d b.d这3个makefile文件,遇到.d文件对应的依赖关系时,
则执行相应的命令,于是我们就有了一个初步的式子:
CC     = gcc
TARGET = hello
src   = hello.c a.c b.c
objs  = $(src:.c=.o)
src_d = $(src:.c=.d)

$(TARGET) : $(objs)
    $(CC) -o $@ $^

%.d : %.c
    gcc -MM $< > $@  # 大于号表示把gcc -MM 命令的输出结果保存到$@即.d文件中
                     # 即为每一个c文件生成包含头文件和自身的依赖文件
include $(src_d)

3. 上述写法只有.c文件改变时对应的.d文件才会更新,如果需要.d也自动更新,则需要如下写法:

CC     = gcc
TARGET = hello
src   = hello.c a.c b.c
objs  = $(src:.c=.o)
src_d = $(src:.c=.d)

$(TARGET) : $(objs)
    $(CC) -o $@ $^

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

include $(src_d)

4.上述$@.$$$-$中的短横线-要去掉,不加上一个符号连续4个$显示不出来。连续4个$会产生一个随机数,大家把rm -f这句话删掉就知道是啥意思了。

更多内容可以参看GNU make网站4.4节 http://www.gnu.org/software/make/manual/make.html#Reading






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值