欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【uboot】【编译】【conf】conf 可执行程序生成 .config的过程走读

【uboot】【编译】【conf】conf 可执行程序生成 .config的过程走读

2024/10/23 11:42:11 来源:https://blog.csdn.net/qq_28954491/article/details/143092543  浏览:    关键词:【uboot】【编译】【conf】conf 可执行程序生成 .config的过程走读

makefile 文件前面已经分析过了,得到的最终的执行指令是:

scripts/kconfig/conf  --defconfig=arch/../configs/mx6ull_14x14_ddr512_emmc_defconfig Kconfig

.config 编译过程分析

1、scripts/kconfig/conf.c 文件main函数 491行到502行

***************************************源码***************************************
int main(int ac, char **av)
{const char *progname = av[0];int opt;const char *name, *defconfig_file = NULL /* gcc uninit */;struct stat tmpstat;setlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);tty_stdio = isatty(0) && isatty(1) && isatty(2);
/**************************************过程***************************************
入参 
ac = 3
av[0] = scripts/kconfig/conf
av[1] = --defconfig=arch/../configs/mx6ull_14x14_ddr512_emmc_defconfig
av[2] = Kconfig
其他变量定义setlocale(LC_ALL, "");bindtextdomain(PACKAGE, LOCALEDIR);textdomain(PACKAGE);tty_stdio = isatty(0) && isatty(1) && isatty(2);
系统环境相关函数调用,这里不做具体解释
***************************************结果***************************************
ac = 3
av[0] = scripts/kconfig/conf
av[1] = --defconfig=arch/../configs/mx6ull_14x14_ddr512_emmc_defconfig
av[2] = Kconfig
progname = scripts/kconfig/conf
全局变量 tty_stdio = 1
***************************************结束**************************************/

2、scripts/kconfig/conf.c 文件main函数 503 到 556

***************************************源码***************************************while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {if (opt == 's') {conf_set_message_callback(NULL);continue;}input_mode = (enum input_mode)opt;switch (opt) {case silentoldconfig:sync_kconfig = 1;break;case defconfig:case savedefconfig:defconfig_file = optarg;break;case randconfig:{struct timeval now;unsigned int seed;char *seed_env;/** Use microseconds derived seed,* compensate for systems where it may be zero*/gettimeofday(&now, NULL);seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));seed_env = getenv("KCONFIG_SEED");if( seed_env && *seed_env ) {char *endp;int tmp = (int)strtol(seed_env, &endp, 0);if (*endp == '\0') {seed = tmp;}}fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );srand(seed);break;}case oldaskconfig:case oldconfig:case allnoconfig:case allyesconfig:case allmodconfig:case alldefconfig:case listnewconfig:case olddefconfig:break;case '?':conf_usage(progname);exit(1);break;}}
/**************************************过程***************************************
53行的while 循环函数
getopt_long 命令行参数的解析函数
av[1] = --defconfig=arch/../configs/mx6ull_14x14_ddr512_emmc_defconfig 
前面两个横杠属于长参数,返回值是参数在 long_opts 中的位置 8
case 分支走 case defconfig
getopt_long 自带两个全局变量 optarg optind
***************************************结果***************************************
input_mode = 8
optarg = Kconfig
optind = 2
defconfig_file = Kconfig
全局变量 sync_kconfig = 0 (sync_kconfig 的值一直是0,后面会用到)
***************************************结束**************************************/

3、scripts/kconfig/conf.c 文件main函数 557行到 563行

***************************************源码***************************************if (ac == optind) {printf(_("%s: Kconfig file missing\n"), av[0]);conf_usage(progname);exit(1);}name = av[optind];conf_parse(name);
/***************************************过程**************************************
ac = 3, optind = 2 所以程序继续执行
name = av[optind] = av[2] = Kconfig
conf_parse(name); ---> conf_parse(Kconfig)
***************************************结果***************************************
name = Kconfig
流程进入到 conf_parse,入参是 Kconfig
***************************************结束**************************************/

4、scripts/kconfig/conf.c 文件main函数 565行到576行

***************************************源码***************************************if (sync_kconfig) {name = conf_get_configname();if (stat(name, &tmpstat)) {fprintf(stderr, _("***\n""*** Configuration file \"%s\" not found!\n""***\n""*** Please run some configurator (e.g. \"make oldconfig\" or\n""*** \"make menuconfig\" or \"make xconfig\").\n""***\n"), name);exit(1);}}
/**************************************过程***************************************
sync_kconfig = 0,而且一直是 0,这个分支进不去,忽略
***************************************结果***************************************
if 分支不会走
***************************************结束**************************************/

5、scripts/kconfig/conf.c 文件main函数 578行到632行

***************************************源码***************************************switch (input_mode) {case defconfig:if (!defconfig_file)defconfig_file = conf_get_default_confname();if (conf_read(defconfig_file)) {printf(_("***\n""*** Can't find default configuration \"%s\"!\n""***\n"), defconfig_file);exit(1);}break;case savedefconfig:case silentoldconfig:case oldaskconfig:case oldconfig:case listnewconfig:case olddefconfig:conf_read(NULL);break;case allnoconfig:case allyesconfig:case allmodconfig:case alldefconfig:case randconfig:name = getenv("KCONFIG_ALLCONFIG");if (!name)break;if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {if (conf_read_simple(name, S_DEF_USER)) {fprintf(stderr,_("*** Can't read seed configuration \"%s\"!\n"),name);exit(1);}break;}switch (input_mode) {case allnoconfig:	name = "allno.config"; break;case allyesconfig:	name = "allyes.config"; break;case allmodconfig:	name = "allmod.config"; break;case alldefconfig:	name = "alldef.config"; break;case randconfig:	name = "allrandom.config"; break;default: break;}if (conf_read_simple(name, S_DEF_USER) &&conf_read_simple("all.config", S_DEF_USER)) {fprintf(stderr,_("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),name);exit(1);}break;default:break;}
/**************************************过程***************************************
input_mode = 8,走 defconfig 分支
defconfig_file = Kconfig
conf_read(defconfig_file) ---> conf_read(Kconfig)
***************************************结果***************************************
进入到函数 conf_read 入参是 Kconfig,读取根目录下面的 Kconfig 文件
***************************************结束**************************************/

6、scripts/kconfig/conf.c 文件main函数 634行到 644行

***************************************源码***************************************if (sync_kconfig) {if (conf_get_changed()) {name = getenv("KCONFIG_NOSILENTUPDATE");if (name && *name) {fprintf(stderr,_("\n*** The configuration requires explicit update.\n\n"));return 1;}}valid_stdin = tty_stdio;}
/**************************************过程***************************************
sync_kconfig = 0,而且一直是 0,这个分支进不去,忽略
***************************************结果***************************************
if 分支不会走
***************************************结束**************************************/

7、scripts/kconfig/conf.c 文件main函数 646行到685行

***************************************源码***************************************switch (input_mode) {case allnoconfig:conf_set_all_new_symbols(def_no);break;case allyesconfig:conf_set_all_new_symbols(def_yes);break;case allmodconfig:conf_set_all_new_symbols(def_mod);break;case alldefconfig:conf_set_all_new_symbols(def_default);break;case randconfig:/* Really nothing to do in this loop */while (conf_set_all_new_symbols(def_random)) ;break;case defconfig:conf_set_all_new_symbols(def_default);break;case savedefconfig:break;case oldaskconfig:rootEntry = &rootmenu;conf(&rootmenu);input_mode = silentoldconfig;/* fall through */case oldconfig:case listnewconfig:case olddefconfig:case silentoldconfig:/* Update until a loop caused no more changes */do {conf_cnt = 0;check_conf(&rootmenu);} while (conf_cnt &&(input_mode != listnewconfig &&input_mode != olddefconfig));break;}
/**************************************过程***************************************
input_mode = 8, 走 defconfig 分支
进入到 conf_set_all_new_symbols 函数,
入参 def_default 定义在 scripts/kconfig/lkc.h 52行值是 0
enum conf_def_mode {def_default,def_yes,def_mod,def_no,def_random
};
所以 conf_set_all_new_symbols(0)
***************************************结果***************************************
进入到函数 conf_set_all_new_symbols(0) 入参是 0
***************************************结果**************************************/

8、scripts/kconfig/conf.c 文件main函数

***************************************源码***************************************if (sync_kconfig) {/* silentoldconfig is used during the build so we shall update autoconf.* All other commands are only used to generate a config.*/if (conf_get_changed() && conf_write(NULL)) {fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));exit(1);}if (conf_write_autoconf()) {fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));return 1;}} else if (input_mode == savedefconfig) {if (conf_write_defconfig(defconfig_file)) {fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),defconfig_file);return 1;}} else if (input_mode != listnewconfig) {if (conf_write(NULL)) {fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));exit(1);}}return 0;
}
/**************************************过程***************************************
sync_kconfig = 0
input_mode = 8 所以走  else if (input_mode != listnewconfig) 分支
执行 conf_write 函数,入参是 NULL
***************************************结果***************************************
进入函数 conf_write,入参是 0
***************************************结果**************************************/

9、scripts/kconfig/conf.c 文件main函数

***************************************源码***************************************/**************************************过程******************************************************************************结果******************************************************************************结果**************************************/

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com