make与makefile

参考资料

makefile介绍

makefile定义整个工程的编译规则,带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译。
makefile一般有两个过程,编译和链接。编译一般获得所有的依赖和中间文件。链接主要是链接函数和全局变量,来最终生成目标文件。

makefile的基本规则

target : prerequisites
	command1
    command2
    command3
  • target就是目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。
  • prerequisites是要生成那个target所需要的文件或是目标。
  • command也就是需要执行的命令,命令要以tab键开头,否则会报错。

这是makefile的一个最小单元,包含了编译的目标和依赖关系。target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。当prerequisites中如果有文件比target文件要新即依赖文件改变,command所定义的命令就会被执行。

一个简单的demo

hello工程有2个头文件(common_def.h,hello.h)和3个c文件(main.c command.c display.c),最终输出hello.o的可执行文件。

all : main.o  command.o  display.o
	cc main.o  command.o  display.o -o hello.o
main.o : main.c common_def.h hello.h
	cc -c main.c
command.o : command.c common_def.h hello.h
	cc -c command.c
display.o : display.c common_def.h hello.h
	cc -c display.c
clean : 
	rm main.o  command.o  display.o

make的执行过程

在shell下执行make命令即可运行当前目录下的Makefile或makefile文件,然后将文件中的第一个目标(target),在上面的例子中是“all”,将其作为最终目标。首先获取执行“all”这个目标的依赖,如main.o则回去查找main.o对应的目标去执行,最终获取到所有的依赖项,然后执行“all”对应的命令。
最后的clean目标没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行。可以通过make clean这样指定命令执行。

变量的使用

将上面的demo修改为使用变量的形式

objs = main.o  command.o  display.o
includes = common_def.h hello.h
all : $(objs)
	cc $(objs) -o hello.o
main.o : main.c $(includes)
	cc -c main.c
command.o : command.c $(includes)
	cc -c command.c
display.o : display.c $(includes)
	cc -c display.c
clean : 
	rm $(objs)

make自动推导

make可以自动推导文件以及文件依赖关系后面的命令,make遇见xxx.o 文件目标时自动把 xxx.c 文件加在依赖关系中,并将 gcc -c xxx.c 作为xxx.o的命令。因此上述demo可修改如下:

objs = main.o  command.o  display.o
all : $(objs)
	cc $(objs) -o hello.o
main.o : $(includes)
command.o : $(includes)
display.o : $(includes)
.PHONY : clean
clean : 
	rm $(objs)

其中.PHONY 表示clean 是个伪目标文件。

makefile书写规则

主要包含两个部分的规则:依赖关系和生成目标的规则。

makefile关键字与命令

判断语句

关键字功能
ifeq判断参数是否相等,相等为 true,不相等为 false。
ifneq判断参数是否不相等,不相等为 true,相等为 false。
ifdef判断是否有值,有值为 true,没有值为 false。
ifndef判断是否有值,没有值为 true,有值为 false。

其它

编译选项

关键字功能
obj-m:编译成模块,把文件作为"模块"进行编译,不会编译到内核,但是会生成一个独立的 “ko” 文件
obj-y:编译到内核
obj-n:不编译

KERNELDIR指的是内核库文件的路径,你的代码中使用的是内核提供的函数,而这些函数也是有具体实现的,在连接成一个内核模块时要说明这些库文件在哪里,方便链接程序把它们连接成一个完成的模块。
“?=”:如果这个KERNELDIR为空说明你没有指定内核库文件的路径,那么它就会给KERNELDIR赋值,因为顶层Makefile通过这个环境变量知道内核库文件在哪里。KERNELDIR=/lib/modules/$(shell uname -r)/build; 其中 shell uname -r 说的是调用shell里头的uname指令 你可以uname -r看看呢是什么,他表示的是内核版本号。一般来说我们构造内核树时,它把内核库统一保存在/lib/modules/内核版本号/build目下。

Makefile里面获取相对路径必须在pwd前面加shell,然后把shell pwd当一个变量来引用,书写形式是:$(shell pwd)

$(MAKE) -C $(KERNELDIR)
转到dir这个目录下面make

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值