makefile

makefile需要了解两个概念,目标和依赖

target:依赖

target是目标,依赖是先决条件,先要完成先决条件之后才可以执行target。

target:是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。文件名以空格分开,可以使用通配符。一般来说,目标基本上是一个文件,但也有可能是多个文件。

        上图中all就是目标,⽬标放在‘:’的前⾯,其名字可以是由字⺟和下划线‘_’组成 。echo “Hello World”就是⽣成⽬标的命令,这些命令可以是任何你可以在你的环境中运⾏的命令以及 make 所定义的函数等等。all ⽬标的定义,其实是定义了如何⽣成 all ⽬标,这我们也称之为规则。

        

        上图中增加一个目标test,一个makefile中可以定义多个目标,如果没有指定的目标,则从第一个目标开始运行,和是否是all目标无关,也就是默认目标。

        上图中all目标后紧跟着test目标,test目标是依赖,也就是先决条件。出现这种⽬标依赖关系时,make⼯具会按 从左到右的先后顺序先构建规则中所依赖的每⼀个⽬标。如果希望构建 all ⽬标,那么make 会在构建它之 前得先构建 test ⽬标,这就是为什么我们称之为先决条件的原因。

        ⼀个规则是由⽬标(targets)、先决条件(prerequisites)以及命令(commands)所组成的。需要指出的是,⽬标和先决条件之间表达的就是依赖关系(dependency),这种依赖关系指明在构建⽬标之前,必须保证先决条件先满⾜(或构建)。⽽先决条件可以是其它的⽬标,当先决条件是⽬标时,其必须先被构建出来。还有就是⼀个规则中⽬标可以有多个,当存在多个⽬标,且这⼀规则是 Makefile 中的第⼀个规则时,如果我们运⾏ make 命令不带任何⽬标,那么规则中的第⼀个⽬标将被视为是缺省⽬标。

        当 make 在运⾏⼀个规则时,我们前⾯已经提到 了⽬标和先决条件之间的依赖关系,make 在检查⼀个规则时,采⽤的⽅法是:如果先决条件中相关的⽂件的时间戳⼤于⽬标的时间戳,即先决条件中的⽂件⽐⽬标更新,则知道有变化,那么需要运⾏规则当中 的命令重新构建⽬标。这条规则会运⽤到所有与我们在 make时指定的⽬标的依赖树中的每⼀个规则。⽐如,对于 simple 项⽬,其依赖树中包括三个规则,make 会检查所有三个规则当中的⽬标(⽂件)与先决条件(⽂件)之间的时间先后关系,从⽽来决定是否要重新创建规则中的⽬标。

        使用假目标,假目标最从常用清净就是避免所定义的目标和的已经存在文件是从重名的情况,假⽬标可以采⽤.PHONY 关键字来定义,需要注意的是其必须是⼤写字⺟。

        

        变量的使用可以提高makefile的可维护性。⼀个变量的定义很简单,就是⼀个名字(变量名)后⾯跟上⼀个等号,然后在等号的后⾯放这个变量所期望的值。对于变量的引⽤,则需要采⽤$(变量名)或者${变量名}这种模式。在这个 Makefile 中,我们引⼊了 CC 和 RM 两个变量,⼀个⽤于保存编译器名,⽽另⼀个⽤于指示删除⽂件的命令是什么。还有就是引⼊了 EXE 和 OBJS 两个变量,⼀个⽤于存放可执⾏⽂件名,可另⼀个则⽤于放置所有的⽬标⽂件名。采⽤变量的话,当我们需要更改编译器时,只需更改变量赋值的地⽅,⾮常⽅便。

静态模式

        obj-m和 和有obj-m+什么区别?

“对象-m:= .o”

内核中的 kbuild 系统将从 mod_name.c 构建 mod_name.o 链接这些文件后将得到内核模块 mod_name.ko。

上面的行可以放在“Kbuild”文件或“Makefile”中。

当模块是从多个源构建时,需要额外的一行列出文件:

<module_name>-y := <src1>.o <src2>.o ...

 如果某个模块目标由多个源文件编译得到,那么可以通过$(<module_name>-objs)或$(<module_name>-y)把这些源文件告诉kbuild。Kbuild能够识别后缀-objs和-y

         #drivers/isdn/i4l/Makefile

         obj-$(CONFIG_ISDN) += isdn.o

         isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o

模块的编译之后的链接有两次,第一次是把上述编译产生的 ".o" 文件组合成一个大的 "testmodule.o":,testmodule.o 虽然是一个 relocatable 的 ELF 文件,但直接 insmod 是不会成功的:还需要第二次链接。这次 link 更复杂一些,依赖于专门的脚本:其过程是将 testmodule.o 和一个 ".mod.o" 后缀的文件 link 起来,形成 ko 文件:

".mod.o" 由 ".mod.c" 编译后来,后者由 Kbuild 系统产生,是 module 的 metadata,包含了版本号、依赖等,主要作用是记录哪些已完成、哪些未完成,以节约 compiling/linking 的整体时间。

正是由于 mod.o 的加持,生成的 ko 文件在 insmod 时才能被内核接纳和解析,实现动态加载。

最终的结果除了 ko,还有一个重要的文件 "Modules.symver",它列出了该 module 所有的 export symbols。

Makefile中的%表示通配符,而*表示任意字符
举例,%.o表示匹配所有的.o文件,注意是用于匹配的。
*.o是表示所有的.o文件。

用途方面:前者一般用作目标,后者一般用作删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值