1. autoconf.h文件
老版本的Linux内核中,执行 make menuconfig 后,编译系统会去 defconfig 文件中读取默认配置,然后把所有的配置信息保存到源码顶层目录下的 .config 文件中,然后将 .config 中的内容转换为C语言能识别的宏定义更新到编译目录下的 include/generated 目录下的 autoconf.h文件中。比如会将CONFIG_XXX = y 的定义转换为 #define CONFIG_XXX 1 的模式写到 autoconf.h 文件当中,CONFIG_XXX = m 的定义转换为 #define CONFIG_XXX_MODULE 1 的模式写到 autoconf.h 文件当中。autoconf.h文件是被自动包含,不需要C代码文件中显式包含。在内核源码的根目录下的Makefile中实现了自动包含,顶层Makefile中相关的内容如下:
# Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iarch/$(hdr-arch)/include/generated -Iinclude $(if $(KBUILD_SRC), -I$(srctree)/include) -include include/generated/autoconf.h ...... export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
在 LINUXINCLUDE 赋值的最后一行包含了autoconf.h文件,然后通过 export 导出给其它的Makefile文件使用。
新内核中(4.14)中$(Q)test -e include/generated/autoconf.h
注意:在Makefile文件中统一使用 CONFIG_XXX,就算是编译成模块,也是 obj-$(CONFIG_XXX) 而不是 obj-$(CONFIG_XXX_MODULE)。但是若是编译成模块,在生成的 autoconf.h 中就变成了#define CONFIG_XXX_MODULE 1 了。
2. 代码中使用生成的宏做判断
// kconfig.h /* * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 * otherwise. For boolean options, this is equivalent to * IS_ENABLED(CONFIG_FOO). */ #define IS_BUILTIN(option) __is_defined(option) /* * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0 * otherwise. */ #define IS_MODULE(option) __is_defined(option##_MODULE) /* * IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled * code can call a function defined in code compiled based on CONFIG_FOO. * This is similar to IS_ENABLED(), but returns false when invoked from * built-in code when CONFIG_FOO is set to 'm'. */ #define IS_REACHABLE(option) __or(IS_BUILTIN(option), __and(IS_MODULE(option), __is_defined(MODULE))) /* * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', 0 otherwise. */ #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option))
使用 #if IS_ENABLED(XXX) 就等于 __is_defined(XXX) || __is_defined(XXX_MODULE), 无论编译进内核还是编译成模块都有效。
本文参考链接:https://www.cnblogs.com/hellokitty2/p/9101744.html