Makefile实例

文档状态:编辑....




Table of Contents

Instance

以下为内核模块编译链接的一个实例,虽然很多人会写但是对具体的含义还是不太了解,因为我接触的也不够多,所以仅仅是写出自己理解的。

#makefile.hello
ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
KERNELDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
        $(MAKE) -C $(KERNELDIR)  M=$(PWD) modules
clean:
        rm -rf *.o *.mod.c *.mod.o *.ko
endif
PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
    $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) >

$(objtree)/modules.order
    @$(kecho) '  Building modules, stage 2.';
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild
#意思是如果在KBUILD_EXTMOD路径下找到Kbuild就include $(KBUILD_EXTMOD)/Kbuild,
#否则include $(KBUILD_EXTMOD)/Makefile。这个路径正好包括我们自己的代码路径,
#因此,模块顺利的被编译链接。
include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \
             $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile)
#`$(KBUILD_EXTMOD)`是这种鬼啊
# 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

ifeq ("$(origin M)", "command line")
KBUILD_EXTMOD := $(M)
endif
#大致意思就是如果使用make命令且带有命令行参数 M="XXX",那就用M初始化这个KBUILD_EXTMOD := $(M),好了最开始我们设置的M是什么?原来是$(shell pwd),就是一开始执行命令的当前目录,那就好说了,现在我特喵又执行了一次makefile,而这一次我们的KERNELRELEASE已经被定义了,所以只执行obj-m就好了,什么不知道为什么已经定义了,因为-C指向的/lib/modules/$(shell uname -r)/build是一个软连接指向/usr/src/linux,而/usr/src/linux目录下就有一个makefile里面写了
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)
ok至此已经执行到obj-m了

几个命令

这几个命令对模块使用时有用,但是什么用还是不要做伸手党了

问题

Reference