make -C M=

 
一般用下面的Makefile :
 
# Makefile2.6
 
ifneq ($(KERNELRELEASE),)

obj-m := hello.o  

else

 

PWD  := $(shell pwd)                                    # 指定模块源代码目录

KVER ?= $(shell uname -r)                           # 指定内核源码树版本号
KDIR := /lib/modules/$(KVER)/build             # 指定内核源码目录
 
all:

       $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:

       rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

endif
 
 
KERNELRELEASE 是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容。
 
当make的目标为all时,-C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD) 表明然后返回到当前目录继续读入、执行当前的Makefile。
 
当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。else之前的内容为kbuild语法的语句, 指明模块源码中各文件的依赖关系,以及要生成的目标模块名。
 
每个内核的名字都包含了它的版本号,这也是 uname -r 命令显示的值。

 

 

==================================================================================

 例子分析:


ifeq ($(KERNELRELEASE),) 

# KERNELRELEASE                 這個變數一開始並沒有定義, 所以先跑到這邊

KERNELDIR ?= /root/kernel/2.6/linux-2.6.14 
PWD := $(shell pwd) 

# 如果直接下 make or make modules 會執行這個 rule
# 這個 rule 是在執行 make 指令,不過它有加其他的參數
# -C dir: 執行 make 前先跳到 $(KERNELDIR) ---> 所以此時 make 所讀的 Makefile 為
# $(KERNELDIR)下的 Makefile (也就是原碼樹的 Makefile)
# M=$(PWD): 這是給$(KERNELDIR)下的 Makefile 的一個環境變數 ---> $(KERNELDIR)下的 Makefile
# 中後來會根據這個 M 的值執行 $(M) 下的 Makefile, 所以這個 Makefile 總共被執行 2 次

modules: 
  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 

modules_install: 
  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install 

clean: 
  rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions 

.PHONY: modules modules_install clean 

else 

# 第 2 次時,由於 KERNELRELEASE 已經在$(KERNELDIR)下的 Makefile 被定義所以會跑到 else
# 底下這行是 2.6 的 kbuild 定義的語法,詳情請讀原碼樹的 Documentations/kbuild/modules.txt
  obj-m := hello.o 


endif 

 

 


你可能感兴趣的:(shell,makefile)