4、默认配置与菜单配置:make defconfig、make menuconfig、配置项分类详解
说实话,很多新手拿到BusyBox源码,第一反应就是直接make。结果呢?编译出来的东西要么大得离谱,要么缺这缺那。我刚开始干嵌入式那会儿也犯过这毛病——总觉得配置嘛,随便搞搞就行。直到有一次产品上线,发现Flash空间就差那么200KB,死活塞不进去。从那以后,我再也不敢小看配置这一步了。
今天咱们就聊聊BusyBox的两种核心配置方式:默认配置和菜单配置。说白了,一个帮你快速起步,一个让你精细打磨。
4.1 make defconfig:快速上手的“安全牌”
make defconfig 这命令,我建议每个新手都先跑一遍。它生成的是BusyBox官方推荐的“通用默认配置”。
核心作用:生成一个包含大多数常用Applet的.config文件,适合通用嵌入式环境。
怎么用?简单得很:
$ cd busybox-1.36.0/
$ make defconfig
$ ls -l .config
-rw-r--r-- 1 root root 45678 Mar 15 10:00 .config
跑完之后,你会在源码根目录看到一个.config文件。这个文件就是BusyBox的“灵魂”——所有编译开关都在里面。
我个人习惯是:拿到一个新板子,先make defconfig打个底,然后再根据硬件资源做裁剪。为什么?因为默认配置覆盖了90%的常见场景,你直接在上面改,比从零开始配省事多了。
小技巧:如果你用的是特定架构(比如ARM、MIPS),可以试试make ARCH=arm defconfig。BusyBox会加载对应架构的优化配置。
4.2 make menuconfig:精细裁剪的“手术刀”
默认配置只是起点。真正要裁剪到“多一个功能嫌多,少一个功能嫌少”的程度,还得靠make menuconfig。
这玩意儿是基于ncurses的文本菜单界面。你需要在宿主机上装好依赖:
$ sudo apt-get install libncurses5-dev # Ubuntu/Debian
$ sudo yum install ncurses-devel # CentOS/RHEL
然后运行:
$ make menuconfig
界面长这样(我画了个示意图):
┌──────────────────────── BusyBox Configuration ─────────────────────────┐
│ Arrow keys navigate the menu. <Enter> selects submenus --->. │
│ Highlighted letters are hotkeys. Pressing <Y> includes, <N> excludes.│
│ Press <Esc><Esc> to exit, <?> for Help. │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ Busybox Settings ---> │ │
│ │ Coreutils ---> │ │
│ │ Shells ---> │ │
│ │ Networking Utilities ---> │ │
│ │ Linux System Utilities ---> │ │
│ │ ... │ │
│ └────────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
操作方式:
- 方向键:上下移动光标
- Enter:进入子菜单
- Y:选中(编译进BusyBox)
- N:排除(不编译)
- M:编译为模块(BusyBox里较少用)
- ?:查看帮助
注意:我曾经遇到过有人把init功能给关了,结果系统启动到一半就挂了。所以,不确定的功能不要乱关。先查帮助文档,或者留个备份。
4.3 配置项分类详解
BusyBox的配置项看着多,其实分类很清晰。我把它归纳成三大类:
4.3.1 全局设置(Busybox Settings)
这一层控制的是BusyBox本身的编译行为。比如:
| 配置项 | 说明 | 我的建议 |
|---|---|---|
| CONFIG_PREFIX | 安装路径(默认./_install) | 改成你目标系统的根目录 |
| CONFIG_FEATURE_INSTALLER | 是否支持安装模式 | 建议开启,方便部署 |
| CONFIG_FEATURE_SUID | 支持SUID权限 | 看需求,一般嵌入式关掉 |
| CONFIG_STATIC | 静态编译 | 我强烈建议开启,避免动态库依赖问题 |
嗯,这里要注意CONFIG_STATIC。我在项目中遇到过,动态编译的BusyBox放到目标板上,结果libc.so版本不对,直接报FATAL: kernel too old。从那以后,我只要做嵌入式,一律静态编译。
4.3.2 功能模块(Applet分类)
这是裁剪的重点。BusyBox把Applet分成了十几个大类:
- Coreutils:核心工具(cp、mv、rm、ls等)—— 基本必选
- Shells:Shell支持(ash、hush、msh)—— 至少选一个
- Networking:网络工具(ping、ifconfig、telnet等)—— 按需选
- Linux System Utilities:系统工具(mount、umount、dmesg等)—— 建议全选
- Process Utilities:进程工具(ps、top、kill等)—— 调试必备
- Editors:编辑器(vi、sed、awk)—— 看空间,能省则省
你想想看,一个完整的Linux系统可能有几百个命令。但在嵌入式里,你可能只需要30-50个。怎么选?我的经验是:
- 先列需求清单:你的系统启动脚本用到了哪些命令?
- 再考虑调试:留几个常用的调试工具(ps、top、ping)
- 最后砍掉冗余:比如有了
vi,就别要nano了
4.3.3 特性开关(Feature Flags)
每个Applet下面还有子选项,控制具体行为。比如ls命令:
--- ls
[*] Enable color support (NEW)
[*] Enable -a option
[*] Enable -l option
[*] Enable -h option
[*] Enable -R option
[ ] Enable -S option (sort by size)
这些开关直接影响二进制大小。我做过测试:
| 配置策略 | BusyBox体积 | 说明 |
|---|---|---|
| 全功能(defconfig) | 约1.2MB | 适合开发板 |
| 中等裁剪 | 约600KB | 适合量产产品 |
| 极限裁剪 | 约300KB | 适合Flash极小的设备 |
核心原则:每个开关都问自己一句——“这个功能,我的产品真的需要吗?”
4.4 配置项之间的依赖关系
这里有个坑,我踩过好几次。BusyBox的配置项不是独立的,它们之间有依赖关系。比如:
- 你要用
mount,必须先开启CONFIG_MOUNT - 你要用
mount -o loop,还得开启CONFIG_FEATURE_MOUNT_LOOP - 你要用
mount -t nfs,还得开启CONFIG_FEATURE_MOUNT_NFS
为什么会这样?因为BusyBox的设计哲学是“最小化”。每个特性都独立开关,你不需要的就不编译。
我曾经在裁剪时,把CONFIG_FEATURE_MOUNT_LOOP关了,结果挂载镜像文件时一直报错。查了半天才发现是依赖没开。所以,改配置前,先看看依赖链。
4.5 我的配置工作流
最后,分享一个我用了多年的配置流程:
make defconfig—— 生成基准配置make menuconfig—— 按需求裁剪make—— 编译测试- 检查体积:
ls -lh busybox - 功能验证:
./busybox ls --help - 循环2-5步,直到满意
记住,裁剪不是一蹴而就的。我一般会迭代3-5轮,才能得到一个既小又好用的配置。
保存配置:裁剪完成后,记得把.config备份一份。我习惯命名为config_myproduct_v1,方便后续复用。
好了,关于默认配置和菜单配置,今天就聊到这儿。下一节咱们会深入.config文件的结构,看看那些CONFIG_XXX到底是怎么控制编译的。
可可精品资料库