每天一篇Makefile(一)

来源:互联网 发布:绿岸网络2017 编辑:程序博客网 时间:2024/06/05 15:44

前言

网络上有很多讲解Makefile的文章和博文,看完之后感觉挺简单的,但是真正让我们自己写一份Makefile,又感觉很困难,没办法完成这项“简单”的任务。O(∩_∩)O哈哈~。
这种学习方法有点像我们很多人在学习英语是一样的。我们经常看语法,感觉都看懂了,但是其实还是不懂。考出来的成绩也不如意。所以我希望用一种新的方式去分享知识,与大家共同成长。水平有限,如有错误,还请指出。


好,进入正题,来看我们今天的要讲的Makefile:


ifneq ($(KERNELRELEASE),)obj-m := hello.oelseKDIR := /home/friendly210/linux-3.8all:make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-clean:rm -f *.ko *.o *.mod.o *.mod.c *.symversendif


上面这份Makefile是用来编译hello驱动的,是一份比较简单的Makefile。


1、ifneq () ... else.... endif : 条件语句,如果ifneq后面的值不相等,则执行接下来的语句,否则则执行else后面的语句。endif表示条件语句的结束,括号中传入两个参数值。和ifneq类似的条件语句还有ifeq, ifdef,ifndef。如果有一些C语言的基础,很容易理解这里的条件语句,看一下名字就能知道是干嘛的了。跟C语言的预编译语句基本相似。


2、KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,我们可以使用$(变量名)来获取变量的值。所以第一行意思就是:当KERNELRELEASE不为空时就执行obj-m := hello.o, 否则就执行else后面的语句。


3、obj-m 和KDIR 是定义的两个变量, 使用:= 来进行赋值,使用:= 赋值时,不能引用定义在其后面的变量。暂时先了解,以后会与其他赋值符号进行对比。


4. all和clean是两个label,当我们使用make all编译时就执行all标签后面的语句,clean也是同理。


5. make命令是用来编译的, -C表示切换目录,在寻找 Makefile 之前会切换到指定的目录目录。 M是makefile脚本中的一个变量,意思是返回到当前目录继续读入、执行当前的Makefile。 modules表示编译成模块,   ARCH是一个变量,它用来表示编译目标的架构。CROSS_COMPILE用于指定make所使用的交叉编译工具。


6.clean后面是一条rm命令,就是删除所有编译生成的文件。


7.obj-m表示把该模块编译成单独的模块,就是编译成一个.ko的文件。可以通过insmod来挂接模块驱动。


8.make执行流程:当使用make进行编译时,一开始KERNELRELEASE还没有定义,所以跑到else,执行make命令,因为KDIR定义为kernel的根目录,所以跑到kernel根目录下找Makefile,此时KERNELRELEASE已经定义,所以obj-m := hello.o被执行,内核根据Kbuild语法编译出.ko文件。(Kbuild如何执行我们暂时不去关心,只要知道它会根据obj-m的定义去编译出.ko文件即可)



总结:这是一个编译驱动的通用模板,以后改一下obj-m的值就ok了,但是不是绝对喔,如果比较复杂的驱动,可就不好说了。O(∩_∩)O哈哈~。希望对你有所帮助。



原创粉丝点击