使用linux menuconfig来配置你的项目

使用linux menuconfig来配置你的项目

从使用C语言至今我自己写过不少轮子,比如说C语言本身不提供的各种数据结构的库。常用的比如说链表,队列之类的。有时项目中的C代码会遇到需要用到这些数据结构的地方。每次都是临时去网上去找一个对应数据结构的demo,再根据实际需要来改写成符合项目需要的各种接口。
有的时候不是不想写这些代码,只不过在写的时候想起自己之前写过类似的轮子,但是找不到了从而觉得很操蛋。
那为什么不从现在开始管理并保存自己写过的轮子呢?

menuconfig是linux内核以及Uboot使用非常广泛的项目配置工具。它提供了一个图形界面与用户交互,可以通过选中或者取消其中的一些配置项来灵活的配置内核以及uboot的相关功能。

作为一个linux驱动开发者,menuconfig是更是绕不开的一座大山,因为如果你想要使能内核的一个驱动,就必须要去厘清相关Kconfig文件中的配置项依赖关系,成功选中对应的配置之后如果编译不通过,还需要清楚的了解你一共打开了哪些配置项,这些配置项在Makefile中决定了哪些文件的编译?

要了解这些东西,光靠一两篇Kconfig语法的博客或者makefile语法的博客是远远不够的,那为什么模仿内核不自己来写一个类似的框架呢,从实践中来彻底搞明白这一套框架的运行逻辑。
menuconfig示意

一个简单的menuconfig框架

我目前的想法是把类似数据结构之类的接口管理起来,这些接口是可以随时通过配置移植到任意项目中直接使用的,如果你的一些不是接口的类似一整个程序的工程想要保存也是可以的,通过放在menuconfig工程中,然后添加Kconfig使得在配置menuconfig的时候可以写入一些关于这个项目的介绍文字并且指示他的路径。后续我会考虑用tristate变量来实现类似内核的模块化编译共功能,例如如果选中‘M’了,就把接口编译成动态库或者静态库。目前只实现了编译’y’或者不编译‘n’

mconf 软件获取

要实现自己的menuconfig,首先现在任意一个版本的linux源码或者uboot源码,直接make menuconfig然后退出:
在这里插入图片描述
可以看到内核makefile是调用了很多文件编译并生成了mconf这个软件,再利用该软件,打开了内核根路径下的Kconfig文件来调用启动的menuconfig。

所以直接去scripts/kconfig/路径下把mconf软件复制到我们的工程里面。

demo编写

实现一个简单的demo,main.c模拟主程序,mian.c打印一个字符串,证明main.c运行了,然后main.c中条件编译driver1和driver2中封装的函数,通过menuconfig灵活配置达到只执行配置了的函数的目的。
项目目录结构:
在这里插入图片描述

Kconfig文件的编写

这里只是实现了一个简单的Kconfig,具体语法请自行百度。

根目录Kconfig:
mainmenu "Demo"

source "driver1/Kconfig"

menu "xlf_test"

config XLF_TEST
    tristate "xlf tristate"
    default m
	help
	  This is a dumb module for testing mmiotrace. It is very dangerous
	  as it will write garbage to IO memory starting at a given address.
	  However, it should be safe to use on e.g. unused portion of VRAM.

	  Say N, unless you absolutely know what you are doing.

endmenu

source "driver2/Kconfig"

XLF_TEST这个配置项并没有使用,放在这里只是测试tristate这个变量能不能正常使用。

driver1/Kconfig:
menu "Device Driver1"

# input before char - char/joystick depends on it. As does USB.

config DEV_DRIVER_F
    tristate "Test module for mmiotrace"
    default m
	help
	  This is a dumb module for testing mmiotrace. It is very dangerous
	  as it will write garbage to IO memory starting at a given address.
	  However, it should be safe to use on e.g. unused portion of VRAM.

	  Say N, unless you absolutely know what you are doing.

endmenu

driver2/Kconfig:
menu "Device Driver2"

# input before char - char/joystick depends on it. As does USB.

config DEV_DRIVER_S
        bool "device driver2"
        default n
        help
          xulf add this config to release "depends on" state of next menu.

endmenu

实际效果展示

在这里插入图片描述
Kconfig的功能实现了只是第一步,上述的步骤成功实现后仅仅实现了通过menuconfig更改配置后,更改后的配置项被记录到.config文件中的步骤。接下来要怎么引用.config中的配置结果到工程中,才是重点。

makefile编写
#引用.config文件中的配置项内容
CONFIG_PATH = .config
-include $(CONFIG_PATH)

#基础文件main.c
SRCS := main.c

#如果menuconfig配置了这个选项为y,则编译相应文件,并为CFLAG添加这个宏
ifeq ($(DEV_DRIVER_F), y)
SRCS += driver1.c
CFLAGS += -DDEV_DRIVER_F
endif

#如果menuconfig配置了这个选项为y,则编译相应文件,并为CFLAG添加这个宏
ifeq ($(DEV_DRIVER_S), y)
SRCS += driver2.c
CFLAGS += -DDEV_DRIVER_S
endif

OBJS	= $(SRCS:%.c=%.o)

TARGET = menuconfig_test

INCLUDE := -I ./include  

VPATH := driver1 driver2
.PHONY:clean distclean defconfig

all: $(TARGET)

$(TARGET): $(OBJS)
	gcc $^ $(INCLUDE) $(CFLAGS) -o $@
	rm *.o

%.o: %.c
	gcc $(INCLUDE) $(CFLAGS) -c $< -o $@

menuconfig:
	mconf Kconfig

defconfig:
	rm -f *.config
	cp $@ .config


clean:
	rm -f *.o
	rm -f $(TARGET)

distclean:
	rm -f .config*


main.c
#include <stdio.h>
#include "driver1.h"
#include "driver2.h"

int main()
{
    printf("main output.\n");

#ifdef DEV_DRIVER_F
    driver1_output();
#endif

#ifdef DEV_DRIVER_S
    driver2_output();
#endif

    return 0;
}

最终的实现效果:

在这里插入图片描述

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值