menuconfig深度定制--Apple的学习笔记

一,前言

上一篇menuconfig界面二次开发--Apple的学习笔记已经完成了menuconfig基于win10的编译及简单修改。menuconfig生成的.config文件主要用来作为makefile工程的输入配置项,采用标准的Kconfig语法。然后我想将menuconfig生成的配置文件非makefile工程也可以使用,就是变成类似于lvgl中的lv_conf.h中#define xxx 1宏定义这样的文件,也可以理解为像FreeRTOSConfig.h中的配置文件。

二,自定义menuconfig需求关键点分析

为了要满足生成#define xxx xxx的文件,并且要能load之前的配置文件,否则这个工具的二次开发是没有应用价值的。所以.config中原来的is not set我还需要保留,用星号注释来保留。这样便于复用原来的导入配置文件的解析代码。另外,将井号改成c语言的注释。
修改前,配置文件为.config

#
# Automatically generated file; DO NOT EDIT.
# AppleCai_Menu
#
# CONFIG_EXPERIMENTAL is not set
# CONFIG_DEFAULT_SMALL is not set
CONFIG_DEFAULT_TASK_STACKSIZE=512
# CONFIG_HOST_LINUX is not set
CONFIG_HOST_MACOS=y
# CONFIG_HOST_WINDOWS is not set
# CONFIG_HOST_OTHER is not set

修改后,配置文件为Appleconfig.h

/***
** Automatically generated file; DO NOT EDIT.
** AppleCai_Menu
***/
#define EXPERIMENTAL    T
/* #define  DEFAULT_SMALL is not set */
#define DEFAULT_TASK_STACKSIZE  1024
/* #define  HOST_LINUX is not set */
/* #define  HOST_MACOS is not set */
#define HOST_WINDOWS    T
/* #define  HOST_OTHER is not set */
/* #define  TOOLCHAIN_WINDOWS is not set */

三,源码中的关键修改点

这个源码写的是不错的,属于解耦型,所以改起来很容易,我通过搜索关键字就能找到要修改的地方。
3.1 文件名修改

const char *conf_get_configname(void)
{
    char *name = getenv("KCONFIG_CONFIG");
    //return name ? name : ".config";  /* modify by apple */
    return name ? name : "Appleconfig.h";
}

3.2 输出格式修改
对应输出CONFIG_的宏定义改成了#define,其中is not set用注释保留,编译load文件的时候使用,等于y或m变成输出T。因为宏定义就是true和falue没有module方式加载的概念,所以制作配套Kconfig的时候需要留意。 此软件已经添加了m按键的输入屏蔽。要么选中要么不择。

static void
kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
{

    switch (sym->type) {
    case S_BOOLEAN:
    case S_TRISTATE:
        if (*value == 'n') {
            bool skip_unset = (arg != NULL);
#if 0  // by apple
            if (!skip_unset)
                fprintf(fp, "# %s%s is not set\n",
                    CONFIG_, sym->name);
#endif
            if (!skip_unset)
                fprintf(fp, "/* %s%s is not set */\n",
                    CONFIG_, sym->name);
            return;
        }
        break;
    default:
        break;
    }
    #if 0  /* modify output value by apple */
    fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);  
    #else
    if((*value=='y')||(*value=='m'))
    {
        fprintf(fp, "%s%s   T\n", CONFIG_, sym->name);
    }
    else
    {
        fprintf(fp, "%s%s   %s\n", CONFIG_, sym->name, value);
    }
    #endif
}

抬头注释的格式修改

static void
kconfig_print_comment(FILE *fp, const char *value, void *arg)
{
    const char *p = value;
    size_t l;
    fprintf(fp, "/*");      /* by apple for modify header */
    for (;;) {
        l = strcspn(p, "\n");
        //fprintf(fp, "#");
        fprintf(fp, "**");  /* by apple for modify header */
        if (l) {
            fprintf(fp, " ");
            xfwrite(p, l, 1, fp);
            p += l;
        }
        //fprintf(fp, "\n");    /* by apple for modify header */
        if (*p++ == '\0')
        {
            fprintf(fp, "*/"); /* by apple for modify header */
            fprintf(fp, "\n");  /* by apple for modify header */
            break;
        }
        else
        {
            fprintf(fp, "\n");    /* by apple for modify header */
        }
    }
}

3.3 输入解析
对原来每行的首字母井号的检测变成了斜杠的检查

    while (compat_getline(&line, &line_asize, in) != -1) {
        conf_lineno++;
        sym = NULL;
        //if (line[0] == '#') {    /* by apple */
        if (line[0] == '/') {

原来的等于y在define的h文件中直接变成True用T单个字符表示。

    case S_BOOLEAN:
        if (p[0] == 'T') {
        //if (p[0] == 'y') {  /* by apple */
            sym->def[def].tri = yes;
            sym->flags |= def_flags;
            break;
        }

原来的=y改成了4个空格。

        } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
            //p = strchr(line + strlen(CONFIG_), '=');  /* by apple */
            p = strchr(line + strlen(CONFIG_), '    ');

3.4 整体颜色风格替换
# define COLOR_BLUE COLOR_RED //1 modify by apple for change color

四,运行效果

至于提示文本信息我都没改,有实际应用的时候可以再修改,通过搜索关键字改起来非常简单的,现在我只是觉得自制menuconfig工具比较好玩,所以玩下深度定制。
我验证生成的配置文件内容是正确的,并且load配置文件后为我上次配置的内容,至少对应如下kconfig文件,我验证下来是正确的。

#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#

config EXPERIMENTAL
    bool "Prompt for development and/or incomplete code/drivers"

config DEFAULT_SMALL
    bool "Default to smallest size"
    default n
    ---help---
        When options are present, the default value for certain options will
        be the one the results in the smallest size (at a loss of features).
        The default is a fuller feature set at a larger size.

        NOTE: This option does not prevent you from overriding the default
        to select another alternative.  Nor does it affect the settings that
        have already been selected in your configuration file.  This applies
        only to new settings that require a default value.

config DEFAULT_TASK_STACKSIZE
    int "The default stack size for tasks"
    default 8192 if ARCH_SIM
    default 2048
    ---help---
        The default stack size for tasks.

choice
    prompt "Build Host Platform"
    default HOST_LINUX

config HOST_LINUX
    bool "Linux"

config HOST_MACOS
    bool "macOS"

config HOST_WINDOWS
    bool "Windows"

config HOST_OTHER
    bool "Other"

endchoice

config TOOLCHAIN_WINDOWS
    bool
    default n
    depends on HOST_WINDOWS
    ---help---
        Selected internally if the selected Windows environment is compatible
        with the use of Windows native toolchains.

我的配置界面,亮眼吧~


image.png

保存后


image.png

重新运行AppleCai_MenuConfig.exe会自动load配置文件,也可以选load按钮加载配置文件
image.png

五,小结

我以前自制的python工具都是用的模板作为输入,python解析模板就是基于正则表达式,而今天又掌握一个基于Kconfig的配置文件工具。Kconfig的解析部分不是我关注的,因为使用标准Kconfig语法。我主要深度定制的是配置文件的生成及导入解析,经过我这样一修改,其实还是有一定应用价值的。
我现在突然想到很多游戏框架完成后,修改下图片及参数又变成另外一个游戏了,我今天的定制也是类似的,站在了巨人的肩膀上,分分钟一个工具就制作完成了,哈哈~

你可能感兴趣的:(menuconfig深度定制--Apple的学习笔记)