KERNELDIR=/lib/modules/2.6.28-11-generic/build
PWD:=$(shell pwd)
INSTALLDIR=/home/wk/hello/install
obj-m:= hello.o
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
cp hello.ko $(INSTALLDIR)
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
以上是简单的hello模块的编译时的makefile
关于PWD:=$(shell pwd):
《跟我一起写 Makefile》里面找到这么一段:
八、shell函数
shell函数也不像其它的函数。顾名思义,它的参数应该就是操作系统Shell的命令。它和反引号“`”是相同的功能。这就是说,shell函数把执行操作系统命令后的输出作为函数返回。于是,我们可以用操作系统命令以及字符串处理命令awk,sed等等命令来生成一个变量,如:
contents := $(shell cat foo)
files := $(shell echo *.c)
注意,这个函数会新生成一个Shell程序来执行命令,所以你要注意其运行性能,如果你的Makefile中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。特别是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想像的多得多。
关于obj-m:= hello.o
目标定义是Kbuild Makefile(kernel build Makefile)的主要部分,也是核心部分。
主要是定义了要编译的文件,所用的选项,以及到哪些子目录(在这里就是代码中INSTALLIDR)去执行递归操作。
最简单的Kbuild makefile 只包含一行:
例子:
obj-y += foo.o 该例子告诉Kbuild在这目录里,有一个名为foo.o的目标文件。foo.o将从foo.c 或foo.S文件编译得到。如果foo.o要编译成一模块,那就要用obj-m了。所采用的形式如下:
例子:
obj-$(CONFIG_FOO) += foo.o
(关于:=是表示前面变量不能使用后面定义的变量,而+=是追加的意思,在这里都可以使用。)
$(CONFIG_FOO)可以为y(编译进内核) 或m(编译成模块)。若二者都不是,就不会被编译链接了。
-C是表示进入$(KERNELDIR)目录执行makefile,而M不是makefile的选项,是内核根目录下的Makefile中使用的变量。
# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
ifdef SUBDIRS
KBUILD_EXTMOD ?= $(SUBDIRS)
endif
ifdef M //如果没有定义或赋值M,此处M未定义(undefined)
ifeq ("$(origin M)", "command line") //如果定义了,此句用来判断M是否从命令行来
KBUILD_EXTMOD := $(M)
endif
endif
.PHONY: modules modules_install clean
这个含义是定义三个伪目标。
以上均是摘抄并总结得到,如有问题,大家可以提出错误!