TARGET=test_demo
#CROSS_COMPILE=arm-linux- 不用交叉环境
CC=$(CROSS_COMPILE)gcc
STRIP=$(CROSS_COMPILE)strip
#CFLAGS=-O2
ifeq ($(KERNELRELEASE),) #若KERNELRELEASE没有定义
KERNELDIR ?=/lib/modules/$(shell uname -r)/build #PC驱动路径.
#上面的具体地址也就是 KERNELDIR ?=/usr/src/kernels/2.6.9-42.EL-smp-i686
# KERNELDIR ?=/up-Star2410/kernel/linux-2.6.24.4/ #ARM驱动.
PWD := $(shell pwd) #取当前路径
all: $(TARGET) modules
$(TARGET):
$(CC) -o $(TARGET) $(TARGET).c #用gcc编译应用程序
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
#-C $(KERNELDIR) 指明跳转到内核源码目录下读取那里的Makefile
#M=$(PWD) 表明然后返回到当前目录继续读入、执行当前的Makefile
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions $(TARGET)
.PHONY:modules modules_install clean
#当从内核源码目录返回时,第二次进入Makefile时KERNELRELEASE已被被定义,所以可以执行以下的else语句
else
obj-m : demo.o #obj-m后面为我们要编译的目标名,主makefile这样就会为我们编译该模块了
endif
另一种是倒过来的:
ifneq ($(KERNELRELEASE),) #ifneq就倒过来了,上面是ifeq,所以一开始执行else,
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
看了LDD-3也是上面一种,复制过来看一下
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
Once again, we are seeing the extended GNU make syntax in action. This makefile is read twice on a typical build. When the makefile is invoked from the command line, it notices that theKERNELRELEASE variable has not been set. It locates the kernel source directory by taking advantage of the fact that the symbolic link build in the installed modules directory points back at the kernel build tree. If you are not actually running the kernel that you are building for, you can supply a KERNELDIR= option on the command line, set the KERNELDIR environment variable, or rewrite the line that sets KERNELDIR in the makefile. Once the kernel source tree has been found, the makefile invokes the default: target, which runs a second make command (parameterized in the makefile as $(MAKE)) to invoke the kernel build system as described previously. On the second reading, the makefile sets obj-m, and the kernel makefiles take care of actually building the module.
This mechanism for building modules may strike you as a bit unwieldy and obscure. Once you get used to it, however, you will likely appreciate the capabilities that have been programmed into the kernel build system. Do note that the above is not a complete makefile; a real makefile includes the usual sort of targets for cleaning up unneeded files, installing modules, etc. See the makefiles in the example source directory for a complete example.
总结:
Makefiel要做两件事:
1,如果内核没有被编译,先编译内核。
2,然后编译内核完后,编译模块。
就这么简单。。。。