menuconfig+Kconfig的简单配置

目录

1.背景

2.管理方案

2.1:.h中直接定义

2.2:.bat+Cmake

2.3:Kconfig

2.3.1 环境安装

2.3.2 代码

2.3.2.1 目录结构

2.3.2.2 ble目录下的Kconfig

2.3.2.3 hardware目录下的Kconfig

2.3.2.4 rtos目录下的Kconfig

2.3.2.5 根目录

2.3.3 执行脚本


1.背景

        在实际项目开发中,通常会有需要去使能/关闭一些代码模块或者修改一些配置参数,最简单的是直接在C中定义一个宏,定义了就把该功能模块进行编译,还可以使用bat+Cmake进行宏的管理,为什么突然想到使用Kconfig进行模块的管控呢,想起之前在团队很多人的时候,就是使用这个进行模块管理的,每个人负责的模块不同,负责人编译对应.config文件并进行提交即可,其他人可以使用GUI界面很直观的进行模块的裁剪。无论是使用最直接的在C文件中定义宏,还是使用bat脚本,一个需要修改C文件,一个bat得带不同的参数,成本上有提高。综合以上所以就使用Kconfig进行管控,方便后续的管理。

2.管理方案

2.1:.h中直接定义

        在module_enable_config.h文件中定义宏,配置值为1或者0。

/**module_enable_config.h*/

#ifndef __MODULE_ENABLE_CONFIG_H__
#define __MODULE_ENABLE_CONFIG_H__

#define NOTIFY_UI_ENABLE   (1)    //1:enable notification UI 0:disenable

#endif

        在main中进行代码宏控制。

/**main.c*/

#include "module_enable_config.h"

void main(void)
{
#if defined(NOTIFY_UI_ENABLE) && NOTIFY_UI_ENABLE == 1
    //enable notification UI
#else
    //disenable
#endif
}

        优点:直白一目了然,打开module_enable_config.h文件修改重新编译即可

        缺点:每次需要使能或者关闭通知功能的时候都需要打开module_enable_config.h文件进行修改,修改完成然后再使用IDE(脚本)进行编译,这样比较麻烦。

2.2:.bat+Cmake

        bat脚本:

@echo off
@echo "build current dir %cd%"

@echo "######################################"
@echo cmake build
@echo "######################################"

set "notify_ui=disenable"
REM Get the version number of the tag

for %%a in (%args%) do (
    if "%%a" == "-notify" (
        set "notify_ui=enable"
        echo "enable notify ui"
    )
)

cmake -S . -B build ^
-D NOTIFY_UI="%notify_ui%" -G Ninja

@echo "######################################"
@echo ninja build
@echo "######################################"

ninja -C build

        CMakeLists.txt:文件


if(${NOTIFY_UI} STREQUAL "enable")
    set(NOTIFY_UI_ENABLE 1)
else()
    set(NOTIFY_UI_ENABLE 0)
endif()

::依赖mg_board.h.in:文件
configure_file(mg_board.h.in ${PROJECT_SOURCE_DIR}/XXX/mg_board.h)

file(GLOB BOARD_APP_SRC
    ${BOARD_APP_DIRS}/XXXX.c
)

############ EXPORT  ###########
set(APP_INC ${APP_INC} ${BOARD_APP_INC} CACHE STRING "" FORCE)
set(APP_SRC ${APP_SRC} ${BOARD_APP_SRC} CACHE STRING "" FORCE)

        mg_board.h.in:文件(Cmake依赖这个文件)

#cmakedefine NOTIFY_UI_ENABLE@NOTIFY_UI_ENABLE@

        自动生成的mg_board.h文件

#define NOTIFY_UI_ENABLE 1            //编译脚本带了-notify参数
/* #undef NOTIFY_UI_ENABLE */         //编译脚本没有带-notify参数(或者 NOTIFY_UI_ENABLE 设置的值为0的时候)

        终端中执行脚本进行编译:./xx.bat -notify     既可以使能 NOTIFY_UI_ENABLE 

        优点:不用自己打开.h文件对宏进行修改,可以自动生成。只要脚本带对应的参数既可。

        缺点:如果需要使能的参数个数很多的时候,脚本后面就会带很多的参数,管理起来就不怎么方便了。

        使用该功能的时候,工程的配置管理得使用Cmake,还得自己编译bat脚本。上诉的bat脚本跟 CMakeLists.txt:文件的例子都是举个例子,并不能直接编译,只是提供一个思路。

2.3:Kconfig

2.3.1 环境安装

        安装python后,然后通过py再安装一下两个模块

python -m pip install windows-curses
python -m pip install kconfiglib

2.3.2 代码

2.3.2.1 目录结构

图2.3.2.1.1 

|-->ble
|	|-Kconfig
|
|-->hardware
|	|-Kconfig
|
|-->rtos
|	|-Kconfig
|
|-->scripts
|
|->-ui
|	|-Kconfig
|
|-->.config(自动生成)
|-->genconfig.py(执行脚本)
|-->Kconfig
|-->Kconfig.Mozart
|-->mozart_config.h(自动生成)
2.3.2.2 ble目录下的Kconfig

Kconfig:

choice MOZART_BLE_SDK_CONFIGURATION
    prompt "Ble System"
    default 1565_SDK_ENABLE

    config 1565_SDK_ENABLE
        bool "1565 SDK"
        help
            Select 1565 SDK

    choice 1565_VERSION
        prompt "1565 version"
        default 1565_VERSION_3_1
        depends on 1565_SDK_ENABLE

        config 1565_VERSION_3_1
            bool "3.1"
            help
                Select 1565 version 3.1

        config 1565_VERSION_3_9
            bool "3.9"
            help
                Select 1565 version 3.9
    endchoice

    config OTHER_BLE_SDK_ENABLE
        bool "Other Ble Sdk"
        help
            Select Other Ble Sdk
endchoice
2.3.2.3 hardware目录下的Kconfig

Kconfig:

choice MOZART_HARDWARE_CONFIGURATION
    prompt "Hardware Configuration"
    default 1005_ENABLE

config 1005_ENABLE
    bool "1005"
    help
        1006的硬件描述

config 1006_ENABLE
    bool "1006"
    help
        1006的硬件描述

endchoice
2.3.2.4 rtos目录下的Kconfig

Kconfig:

#menu "Kernel Selection"

choice MOZART_KERNEL_CONFIGURATION
    prompt "kernel System"
    default FREE_RTOS_ENABLE

config FREE_RTOS_ENABLE
    bool "free_rtos"
    help
        free_rtos系统描述.

config THREADX_ENABLE
    bool "threadx"
    help
        threadx系统描述.

endchoice

#endmenu
2.3.2.5 根目录

genconfig.py(这个脚本在安装py的时候就有了,找到安装路径找里面的genconfig.py,也可以)

#!/usr/bin/env python3

# Copyright (c) 2018-2019, Ulf Magnusson
# SPDX-License-Identifier: ISC

"""
Generates a header file with #defines from the configuration, matching the
format of include/generated/autoconf.h in the Linux kernel.

Optionally, also writes the configuration output as a .config file. See
--config-out.

The --sync-deps, --file-list, and --env-list options generate information that
can be used to avoid needless rebuilds/reconfigurations.

Before writing a header or configuration file, Kconfiglib compares the old
contents of the file against the new contents. If there's no change, the write
is skipped. This avoids updating file metadata like the modification time, and
might save work depending on your build setup.

By default, the configuration is generated from '.config'. A different
configuration file can be passed in the KCONFIG_CONFIG environment variable.

A custom header string can be inserted at the beginning of generated
configuration and header files by setting the KCONFIG_CONFIG_HEADER and
KCONFIG_AUTOHEADER_HEADER environment variables, respectively (this also works
for other scripts). The string is not automatically made a comment (this is by
design, to allow anything to be added), and no trailing newline is added, so
add '/* */', '#', and newlines as appropriate.

See https://www.gnu.org/software/make/manual/make.html#Multi_002dLine for a
handy way to define multi-line variables in makefiles, for use with custom
headers. Remember to export the variable to the environment.
"""
import argparse
import os
import sys

import kconfiglib


DEFAULT_SYNC_DEPS_PATH = "deps/"


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=__doc__)

    parser.add_argument(
        "--header-path",
        metavar="HEADER_FILE",
        help="""
Path to write the generated header file to. If not specified, the path in the
environment variable KCONFIG_AUTOHEADER is used if it is set, and 'config.h'
otherwise.
""")

    parser.add_argument(
        "--config-out",
        metavar="CONFIG_FILE",
        help="""
Write the configuration to CONFIG_FILE. This is useful if you include .config
files in Makefiles, as the generated configuration file will be a full .config
file even if .config is outdated. The generated configuration matches what
olddefconfig would produce. If you use sync-deps, you can include
deps/auto.conf instead. --config-out is meant for cases where incremental build
information isn't needed.
""")

    parser.add_argument(
        "--sync-deps",
        metavar="OUTPUT_DIR",
        nargs="?",
        const=DEFAULT_SYNC_DEPS_PATH,
        help="""
Enable generation of symbol dependency information for incremental builds,
optionally specifying the output directory (default: {}). See the docstring of
Kconfig.sync_deps() in Kconfiglib for more information.
""".format(DEFAULT_SYNC_DEPS_PATH))

    parser.add_argument(
        "--file-list",
        metavar="OUTPUT_FILE",
        help="""
Write a list of all Kconfig files to OUTPUT_FILE, with one file per line. The
paths are relative to $srctree (or to the current directory if $srctree is
unset). Files appear in the order they're 'source'd.
""")

    parser.add_argument(
        "--env-list",
        metavar="OUTPUT_FILE",
        help="""
Write a list of all environment variables referenced in Kconfig files to
OUTPUT_FILE, with one variable per line. Each line has the format NAME=VALUE.
Only environment variables referenced with the preprocessor $(VAR) syntax are
included, and not variables referenced with the older $VAR syntax (which is
only supported for backwards compatibility).
""")

    parser.add_argument(
        "kconfig",
        metavar="KCONFIG",
        nargs="?",
        default="Kconfig",
        help="Top-level Kconfig file (default: Kconfig)")

    args = parser.parse_args()


    kconf = kconfiglib.Kconfig(args.kconfig, suppress_traceback=True)
    kconf.load_config()

    if args.header_path is None:
        if "KCONFIG_AUTOHEADER" in os.environ:
            kconf.write_autoconf()
        else:
            # Kconfiglib defaults to include/generated/autoconf.h to be
            # compatible with the C tools. 'config.h' is used here instead for
            # backwards compatibility. It's probably a saner default for tools
            # as well.
            kconf.write_autoconf("mozart_config.h")
    else:
        kconf.write_autoconf(args.header_path)

    if args.config_out is not None:
        kconf.write_config(args.config_out, save_old=False)

    if args.sync_deps is not None:
        kconf.sync_deps(args.sync_deps)

    if args.file_list is not None:
        with _open_write(args.file_list) as f:
            for path in kconf.kconfig_filenames:
                f.write(path + "\n")

    if args.env_list is not None:
        with _open_write(args.env_list) as f:
            for env_var in kconf.env_vars:
                f.write("{}={}\n".format(env_var, os.environ[env_var]))


def _open_write(path):
    # Python 2/3 compatibility. io.open() is available on both, but makes
    # write() expect 'unicode' strings on Python 2.

    if sys.version_info[0] < 3:
        return open(path, "w")
    return open(path, "w", encoding="utf-8")


if __name__ == "__main__":
    main()

Kconfig:

mainmenu "Mozart Configuration"

source "Kconfig.Mozart"

Kconfig.Mozart

menu "Software Configuration"
    source "ui/Kconfig"
    source "rtos/Kconfig"
    source "ble/Kconfig"
endmenu

menu "hardware Configuration"
    source "hardware/Kconfig"
endmenu

2.3.3 执行脚本

        在powershell窗口下执行menuconfig,配置好自己想要的配置。

图2.3.3.1

        配置完之后就会自动生成.config文件;然后再执行genconfig.py脚本,就会自动生成C中可以用的.h文件了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值