Makefile编译原理 自动生成依赖关系

一.编译行为带来的缺陷

预处理器将头文件中的代码直接插入源文件

编译器只通过预处理后的源文件产生目标文件

因此,规则中以源文件为依赖,命令可能无法执行

Makefile编译原理 自动生成依赖关系_第1张图片

实验:

func.h

#ifndef FUNC_H
#define FUNC_H

#define HELLO "Hello D.T."

void foo();

#endif

func.c

#include "stdio.h"
#include "func.h"

void foo()
{
    printf("void foo() : %s\n", HELLO);
}

main.c

#include 
#include "func.h"

int main()
{
    foo();
	
    return 0;
}	

makefile

OBJS := func.o main.o

hello.out : $(OBJS)
	#链接
	@gcc -o $@ $^
	@echo "Target File ==> $@"
	
#通过 规则中的模式替换  为  func.o main.o 和两个目标生成真真正正的规则。
$(OBJS) : %.o : %.c
	#编译
	@gcc -o $@ -c $^



mhr@ubuntu:~/work/makefile1$ make
Target File ==> hello.out
mhr@ubuntu:~/work/makefile1$ 

修改 func.h头文件,makefile中的目标不会被执行

#ifndef FUNC_H
#define FUNC_H

#define HELLO "Hello makefile"

void foo();

#endif

mhr@ubuntu:~/work/makefile1$ make
make: 'hello.out' is up to date.
mhr@ubuntu:~/work/makefile1$ 

居然没有发生变化!并不是我们期望的 Hello makefile。为什么?因为这个makefile 并没有考虑目标文件对头文件的间接依赖,所以说 就算改动了头文件,make 也不知道,makefile 中描述的规则只会去查看源文件是否比目标文件更新,结果源文件没改动,所以不会重新编译。

修改 makefiel ,直接在makefile中添加 func.h 依赖

OBJS := func.o main.o

hello.out : $(OBJS)
	@gcc -o $@ $^
	@echo "Target File ==> $@"
	
$(OBJS) : %.o : %.c func.h
	@gcc -o $@ -c $<



mhr@ubuntu:~/work/makefile1$ make
Target File ==> hello.out
mhr@ubuntu:~/work/makefile1$ 

直接在makefile中添加 func.h 依赖,这样一来,通过上面模式规则所生成的真正规则当中,每一个.o 文件都会依赖到 .h 头文件。

这样做的弊端:

头文件作为依赖条出现于每个目标对应的规则中

当头文件改动,任何源文件都将被重新编译(编译低效)

当项目中头文件数量巨大时,makefile将很难维护。

解决办法:

通过命令自动生成对头文件的依赖

将生成的依赖自动包含进makefile中

当头文件改动后,自动确认需要重新编译的文件

你可能感兴趣的:(Linux驱动,linux,算法,运维)