Makefile应用

Makefile实例

在c.c里面,包含一个头文件c.h,在c.h里面定义一个宏,把这个宏打印出来。

c.c:

#include 
#include 

void func_c()
{
	printf("This is C = %d\n", C);
}

c.h

#define C 1

然后上传编译,执行./test,打印出:
在这里插入图片描述
测试没有问题,然后修改c.h
在这里插入图片描述
重新编译,发现没有更新程序,运行结果不变,说明现在的Makefile存在问题。

为什么会出现这个问题呢?首先test依赖c.o,c.o依赖c.c,如果我们更新c.c,会重新更新整个程序。但c.o也依赖c.h,我们更新了c.h,并没有在Makefile上体现出来,导致c.h的更新,Makefile无法检测到。

因此需要添加:

c.o: c.c c.h

现在每次修改c.h,Makefile都能识别到更新操作,从而更新最后输出文件。

我们怎么为每个.c文件添加.h文件呢?对于内核,有几万个文件,不可能为每个文件依次写出其头文件。因此需要做出改进,让其自动生成依赖

gcc -M c.c // 打印出依赖

gcc -M -MF c.d c.c  // 把依赖写入文件c.d

gcc -c -o c.o c.c -MD -MF c.d  // 编译c.o, 把依赖写入文件c.d

修改Makefile

objs = a.o b.o c.o

dep_files := $(patsubst %,.%.d,$(objs))
dep_files := $(wildcard $(dep_files))

test: $(objs)
	gcc -o test $^

ifneq($(dep_files),)
include $(dep_files)
endif 

%.o:%.c
	gcc -c -o $@ $< -MD -MF .$@.d

clean:
	rm *.o test

disclean:
	rm $(dep_files)

.PHONY:clean

首先用obj变量将.o文件放在一块。
利用前面讲到的函数,把obj里所有文件都变为.%.d格式,并且用变量dep_files表示。
利用前面介绍的wildcrad函数,判断dep_files是否存在。

如果dep_files变量不为空,就将其包含进来。

再添加CFLAGS,即编译参数。比如加上编译参数-Werror,把所有的警告当成错误。

CFLAGS = -Werror -Iinclude 
...
%.o:%.c
	gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d

CFLAGS是一个变量,用于存储传递给编译器的编译选项,具体来说,CFLAGS中包含了两个选项:

  1. -Werror:将编译警告(warnings)视为错误(errors)。通常,编译器会生成一些警告,但它们不会阻止程序的编译。使用’-Werror’选项会将这些警告当做错误,如果有任何警告,编译过程将被中断。
  2. -Iinclude:将指定目录’include’添加到头文件搜索路径中。这对于告诉编译器在哪里找到包含的头文件是很有用的。

总体来说,使用双引号“file.h”会首先在当前目录中查找头文件,然后再去系统目录中查找。而使用尖括号只会在系统目录中查找。
选择使用哪一种形式通常取决于头文件是项目内的还是标准库的

你可能感兴趣的:(stm32,Makefile)