首先推荐一篇文章“跟我一起写 Makefile(http://blog.csdn.net/haoel/article/details/2886)【1】”,里面深入浅出介绍了makefile的语法。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。(摘自【1】结束)
Kconfig里面的tristate表明(CONFIG_XXXXX)有3个值可以选y,m,n,bool是两个值可以选y,n
depends 表明该配置依赖于另一个配置,只有另一个配置生效,这个配置才会生效。
select表明本配置生效,就会使select对应的配置也生效。
根据$(CONFIG_XXXXX)配置不同,obj-$(CONFIG_XXXXX)分别对应obj-y,obj-m,obj-n.
obj-y:相关配置对应的.c文件会被编译到系统里。
obj-m:编译成相关的模块,生成.ko,可以通过insmod命令加载
obj-n;不会编译到系统里。
而$(CONFIG_XXXXX)的开关是在kernel/arm/arm64/config/msmxxx_defconfig里面定义的
我们一个项目通常对应两个msmxxx_defconfig,一个是msmxxx_defconfig一个是msmxxx-perf_defconfig
msmxxx_defconfig里面有很多debug开关是打开的,msmxxx-perf_defconfig是user版本默认的配置的,所以提交配置两个文件通常都需要提交。
而对于选择哪个defconfig是定义在device/qcom/msmXXX/AndroidBoard.mk里面
上面是一个msm8953_64代码默认的一个配置。从上面我们可以看出当编译user版本用的是perf的config,而userdebug版本会用非perf的config。
Tips:config编译生成的中间文件放在out/target/product/xxxx/obj/KERNEL_OBJ/.config. 如果添加驱动后.c没有编译到,可以到这文件里面确认相关config是否有配置成功。
http://blog.csdn.net/ztguang/article/details/53001985
定义生成内核的规则
TARGET_AUTO_KDIR := $(shell echo $(TARGET_DEVICE_DIR) | sed -e 's/^device/kernel/g')
自动设置的内核目录
比如i9100,那么自动设置的内核目录是
kernel/samsung/i9100
TARGET_KERNEL_SOURCE ?= $(TARGET_AUTO_KDIR)
内核源码目录
默认 kernel//
一般在BoardConfig.mk里配置
KERNEL_SRC := $(TARGET_KERNEL_SOURCE)
内核源码目录
KERNEL_DEFCONFIG := $(TARGET_KERNEL_CONFIG)
编译内核用的配置文件
一般在BoardConfig.mk里配置
VARIANT_DEFCONFIG := $(TARGET_KERNEL_VARIANT_CONFIG)
变量配置
一般在BoardConfig.mk里配置
selinux配置
一般在BoardConfig.mk里配置
KERNEL_OUT := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ
示例:
目标文件的路径:out/target/product/i9100/obj/KERNEL_OBJ
我们生成的目标文件路径在:out/target/product/projectname/obj/KERNEL_OBJ;在该目录下面有driver、framework等。
驱动文件编译后生成主要在的路径是driver目录下。
生成的编译内核的配置文件
KERNEL_CONFIG := $(KERNEL_OUT)/.config
示例:
out/target/product/i9100/obj/KERNEL_OBJ/.config
是否启用uboot
一般在BoardConfig.mk里配置
是否启用无压缩的boot
一般在BoardConfig.mk里配置
KERNEL_MODULES_INSTALL := system
内核模块的安装目录
KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
内核模块的的实际安装目录
out/target/product/i9100/system/lib/modules
ifeq ($(TARGET_KERNEL_MODULES),)
TARGET_KERNEL_MODULES := no-external-modules
endif
创建$(KERNEL_OUT)目录
即目录out/target/product/i9100/obj/KERNEL_OBJ
生成编译内核源代码用的配置文件
$(KERNEL_CONFIG): $(KERNEL_OUT)
$(MAKE) $(MAKE_FLAGS) -C $(KERNEL_SRC) O=$(KERNEL_OUT) ARCH=$(TARGET_ARCH) $(ARM_CROSS_COMPILE) VARIANT_DEFCONFIG=$(VARIANT_DEFCONFIG) SELINUX_DEFCONFIG=$(SELINUX_DEFCONFIG) $(KERNEL_DEFCONFIG)
生成piggy内核
$(KERNEL_OUT)/piggy : $(TARGET_PREBUILT_INT_KERNEL)
$(hide) gunzip -c $(KERNEL_OUT)/arch/$(TARGET_ARCH)/boot/compressed/piggy.gzip > $(KERNEL_OUT)/piggy
安装模块,并清除先前不用的模块所在目录