module Makefile

module Makefile

第一种形式

在linux上在进行module编译时makefile最简单的形式如下:

obj-m += scull.o
#这里就一句话,所以make命令就不能省略
#   make -C /usr/src/linux-headers-2.6.31-14-generic/ SUBDIRS=$PWD modules
#注意,SUBDIRS是较老的使用方式,与M等效,建议使用M
#http://tscsh.blog.163.com/blog/static/2003201032013151544087/
#PWD := $(shell pwd)
#clean:
#   $(MAKE) -C /usr/src/linux-headers-2.6.31-14-generic/ M=$(PWD) modules clean
这种形式由于只有一句话,所以不能简单的make,要把make命令全部打出来,如上注释。


第二种形式

稍微复杂的形式如下:

注意,此Makefile文件中有很多变量都是内核树中Makefile文件中定义的,因为module编译必须要链接内核树中的文件,也就要依赖内核树中的Makefile文件:

obj-m := scull.o
KERN_DIR := /lib/modules/$(shell uname -r)/build 
#或者写成
#KERN_DIR := /usr/src/linux-headers-$(shell uname -r)
PWD := $(shell pwd)
all:
#module:
	$(MAKE) -C $(KERN_DIR) M=$(PWD) modules
clean:
	$(MAKE) -C $(KERN_DIR) M=$(PWD) modules clean
#modules_install目标我目前了解到的是会把生成的.ko文件放到/lib/modules/2.6.31-14-generic/extra/文件夹下
modules_install:
	$(MAKE) -C $(KERN_DIR) M=$(PWD) modules_install

obj-m变量指定了要编译的模块,这里赋值为scull.o,最终生成的模块将是scull.ko,make命令中的modules目标就是讲obj-m变量作为要生成的对象的。如果scull.ko依赖于多个.c文件,可以通过引入变量scull-objs来实现,如果scull.ko的实现在两个源文件中scull.c scull2.c,则Makefile中应该加入以下语句:

scull-objs := scull.o scull2.o

当执行make命令时,默认以all为目标,执行$(MAKE) -C $(KERN_DIR) M=$(PWD) modules,KERN_DIR变量内容为内核树的所在路径,-C指令首先改变目录到-C指定的位置,M为内核Makefile文件中指定的变量,作用是在构造modules目标之前返回到模块源码目录,这样会重新读取一遍该Makefile中的变量,最终生成scull.ko。

第三种形式

由于对该模块源码目录下Makefile文件有双次读取,所以我们也可以使用ifneq语句来保证次Makefile中的变量分两次读取,避免重复读取

ifneq ($(KERNELRELEASE),)
obj-m += scull.o
else

KERN_DIR := /lib/modules/$(shell uname -r)/build
#或者写成
#KERN_DIR := /usr/src/linux-headers-$(shell uname -r)
PWD := $(shell pwd)
all:
#module:
        $(MAKE) -C $(KERN_DIR) M=$(PWD) modules
clean:
        $(MAKE) -C $(KERN_DIR) M=$(PWD) modules clean
modules_install:
        $(MAKE) -C $(KERN_DIR) M=$(PWD) modules_install
endif
KERNELRELEASE变量是在内核源码目录的Makefile中定义的,所以条件不成立,首次读取直接读取else后的变量,并在首次读取时将modules作为make目标,返回后的第二次读取,设置obj-m变量,然后生成modules目标。

猜你喜欢

转载自blog.csdn.net/xiaoyink/article/details/79742911