驱动模块(5)_autoconf.h

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), 无论编译进内核还是编译成模块都有效。

 

posted on 2018-05-28 18:56  Hello-World3  阅读(598)  评论(0编辑  收藏  举报

导航