浅析Kbuild系统
Kbuild1
Kbuild: the Linux Kernel Build System
Linux 内核采用统一的代码基础,却可以在大到服务器,小到微型的嵌入式设备上使用,其高度可裁剪、可定制化的构建在业界都是一流的。Linux 在 2.6 版本之后采取了 Kbuild 系统进行系统的配置和构建。在新的构建系统下,首先编译系统会读取 Linux 内核顶层的 Makefile,然后根据读到的内容第二次读取 Kbuild Makefile 来编译内核。
从配置和编译 Linux Kernel 所使用的命令来看,Linux Kernel 的配置和编译体系总体上还是基于 GNU Make 的,没有另外使用其他的编译工具(比如 Scons、CMake等)。但 Linux Kernel 实现了 Kconfig
和 Kbuild
,用于辅助内核的配置和编译。Kconfig
,顾名思义就是 Linux内核的配置(Kernel config),Kbuild
系统需要与 Kconfig
配合使用。
长篇的描述网上已经很多了,这里描述一下如何搭建和使用一个简要的 Kbuild 系统。
搭建Kbuild2
The Linux Kernel Build System has four main components:
Config symbols: compilation options that can be used to compile code conditionally
in source files and to decide which objects to include in a kernel image or its modules.
Kconfig files: define each config symbol and its attributes, such as its type, description and dependencies.
Programs that generate an option menu tree (for example, make menuconfig) read the menu entries from these files.
.config file: stores each config symbol's selected value. You can edit this file manually or use one of the many
make configuration targets, such as menuconfig and xconfig, that call specialized programs to build a tree-like
menu and automatically update (and create) the .config file for you.
Makefiles: normal GNU makefiles that describe the relationship between source files and the commands
needed to generate each make target, such as kernel images and modules.
我们先不管抽象的定义,搭建的时候会有相应的文件对应到上面四个 components。
目录结构
创建一个目录,结构如下,里面有两个文件夹,其中 include
下有 config
和 generated
两个文件夹,这几个文件夹 (include config generated
) 都是自动生成的,其中的文件也都是自动生成的。实际发现必须建立 include config generated
目录才能生成成功,否则会报 *** Error during update of the configuration.
的错误。scripts
文件夹下的两个可执行文件拷贝自 Linux 源码目录下的./scripts/kconfig/
,比较新版本的 Linux 可能 conf
和 mconf
在构建过程才会生成,因此需要先构建一下 Linux 才行。
剩余需要手动添加的文件为 hello.c, Kconifg, Makefile, myprint.c, myprint.h
。
示例源码
// hello.c
#include <stdio.h>
#include "autoconf.h"
#include "myprint.h"
void main()
{
#ifdef CONFIG_ARM
printf("ARM PLAT!\n");
#endif
#ifdef CONFIG_x86
printf("x86 PLAT!\n");
#endif
#ifdef CONFIG_MYPRINT
myprint();
#endif
}
// myprint.c
#include <stdio.h>
void myprint(void)
{
printf("This is mytest!\n");
}
// myprint.h
void myprint(void);
通过源码中的条件编译选项,我们可以控制哪些代码逻辑生效,Kbuild
系统可以自动生成上述条件编译宏,这些宏默认位于 autoconf.h
里。
Kconfig文件
使用 Kbuild 通常是这个过程。
1. make *config,比如 menuconfig, defconfig
2. make 程序会读取目录树下的 Kconfig 文件,以 GUI 或者命令行的方式获得用户的配置,这一步会生成一个 .config 文件。
3. 运行 Kbuild 提供的 conf 程序,生成 config 和 generated 目录下的各个文件。
4. 用户使用的时候包含其中的 autoconf.h 即可。
Kconfig 的语法可以参考 linux 目录下 Documentation/kbuild/kconfig-language.txt
。
mainmenu "Kbuild Test Configuration"
menu "TEST_KBUILD"
config ARM
tristate "enable gcc arm"
config x86
bool "enable gcc x86"
config MYPRINT
bool "enable myprint.c"
help
this is a test
endmenu
Makefile
Makefile 里可以使用宏 CONFIG_XXX
来控制是否包含相应的目标。这些宏包含在 auto.conf
里,由 Kbuild
系统自动生成,可以在 Makefile
里包含这个头文件。
TARGET=hello
# 这一句在 make defconfig / menuconfig 生成相应的文件后再添加
# 添加在这里只是为了展示 Makefile 可以通过 CONFIG_MYPRINT 来控制文件编译与否
include ./include/config/auto.conf
LDFLAGS= -I./include/generated
obj-y := hello.c
obj-$(CONFIG_MYPRINT) += myprint.c
all: $(TARGET)
$(TARGET): $(obj-y) FORCE
gcc $(LDFLAGS) -o $@ $(obj-y)
echo $@
echo $(obj-y)
defconfig:
./scripts/conf Kconfig
./scripts/conf -s --syncconfig Kconfig
menuconfig:
./scripts/mconf Kconfig
./scripts/conf -s --syncconfig Kconfig
clean:
rm $(TARGET)
PHONY +=FORCE
FORCE:
.PHONY: $(PHONY)
运行 make defconfig
配置写到了 .config
文件中,内容如下。
#
# Automatically generated file; DO NOT EDIT.
# Kbuild Test Configuration
#
#
# TEST_KBUILD
#
CONFIG_ARM=y
CONFIG_x86=y
# CONFIG_MYPRINT is not set
include/config/auto.conf
文件内容和 .config
内容并无二致。把不是 y
的以及冗余的信息删除了而已。
#
# Automatically generated file; DO NOT EDIT.
# Kbuild Test Configuration
#
CONFIG_x86=y
CONFIG_ARM=y
include/generated/autoconf.h
文件内容如下。这个文件实际上是 ./conf --syncconfig Kconfig
生成的,并且名字和存放的位置可以通过环境变量 KCONFIG_AUTOHEADER
来指定。默认是在当前目录下的 include/generated/autoconf.h
。如可以通过这个命令指定生成的文件为 kconfig.h
,KCONFIG_AUTOHEADER=kconfig.h ./conf --syncconfig Kconfig
,如此一来 include
目录下将没有 generated
目录。
/*
*
* Automatically generated file; DO NOT EDIT.
* Kbuild Test Configuration
*
*/
#define CONFIG_x86 1
#define CONFIG_ARM 1
conf 其他命令选项
./conf: Kconfig file missing
Usage: ./conf [-s] [option] <kconfig-file>
[option] is _one_ of the following:
--listnewconfig List new options
--helpnewconfig List new options and help text
--oldaskconfig Start a new configuration using a line-oriented program
--oldconfig Update a configuration using a provided .config as base
--syncconfig Similar to oldconfig but generates configuration in
include/{generated/,config/}
--olddefconfig Same as oldconfig but sets new symbols to their default value
--defconfig <file> New config with default defined in <file>
--savedefconfig <file> Save the minimal current configuration to <file>
--allnoconfig New config where all options are answered with no
--allyesconfig New config where all options are answered with yes
--allmodconfig New config where all options are answered with mod
--alldefconfig New config with all symbols set to default
--randconfig New config with random answer to all options
--yes2modconfig Change answers from yes to mod if possible
--mod2yesconfig Change answers from mod to yes if possible
总结
总结一下 Kbuild
系统包含的四个 components。
- Config symbols:
CONFIG_XXX
,由 Kconfig 文件描述。最后生成源码可用的autoconf.h
。 - Kconfig files:
Kconfig
文件,描述了有哪些选项及其依赖等。 - .config file:
.config
,由make menuconfig
等生成的文件,里面列出了各选项的取值。 - Makefiles:
Makefile
,描述待构建目标及其依赖、命令等。
更多推荐
所有评论(0)