4. make menuconfig 配置界面详解:Applet 选择、编译选项、安装路径
说实话,很多刚接触 BusyBox 的朋友,一打开 make menuconfig 就懵了。满屏的选项,密密麻麻的,不知道从哪下手。我当年第一次配置的时候,也是对着屏幕发了好一会儿呆。
其实你把它拆开来看,就没那么复杂了。整个配置界面,核心就三块:Applet 选择、编译选项、安装路径。搞懂这三块,你就掌握了 BusyBox 裁剪的命门。
核心观点:make menuconfig 不是让你全选或全不选,而是让你「按需勾选」。多一个功能,就多一份体积,也多一个潜在的攻击面。
4.1 Applet 选择:到底该勾哪些?
进入 make menuconfig 后,你会看到一堆分类:Coreutils、Networking、Shells、Editors 等等。每个分类下面,就是一个个具体的命令,也就是所谓的 Applet。
我个人习惯,先把所有 Applet 全部取消勾选,然后根据项目需求,一个一个往回加。这样做的好处是——你清楚知道每个功能是你主动选进来的,而不是稀里糊涂被带进来的。
小技巧:按 / 键可以搜索 Applet。比如你想找 ping,直接按 / 输入 ping,回车,光标就跳过去了。这个功能我用了好几年才发现,之前都是手动翻菜单,翻得眼花。
举个例子,一个简单的嵌入式 Linux 系统,可能只需要这些:
| 分类 | 推荐保留的 Applet | 说明 |
|---|---|---|
| Coreutils | ls, cp, mv, rm, cat, echo, mkdir, chmod | 文件操作必备,少一个都难受 |
| Shells | ash (默认 shell) | 够用就行,bash 太大了 |
| Networking | ping, ifconfig, route, telnetd | 调试网络时救命用的 |
| Editors | vi (精简版) | 现场改配置文件,没有它你会哭 |
| Init | init, reboot, poweroff | 系统启动和关机必须 |
注意:不要勾选 CONFIG_FEATURE_* 开头的选项,除非你明确知道它干什么用。我曾经在项目里勾了一个 CONFIG_FEATURE_VERBOSE,结果编译出来的 BusyBox 多了 30KB,就为了多打印几行调试信息。得不偿失。
4.2 编译选项:静态还是动态?这是个问题
编译选项这块,我建议重点关注三个地方:
- Build Options → Build BusyBox as a static binary (no shared libs):静态编译。选上之后,BusyBox 不依赖任何动态库,扔到任何 Linux 系统上都能跑。代价是体积会大一些。
- Debugging Options → Build with debug information:调试信息。开发阶段可以勾上,方便 gdb 调试。但发布产品时一定要关掉,否则体积翻倍。
- Cross Compiler prefix:交叉编译工具链前缀。比如你用 arm-linux-gnueabihf-,就在这里填上。我见过有人忘了填这个,编译出来的二进制在目标板上跑不起来,折腾了一下午才发现。
我个人建议,产品发布时用静态编译。为什么?因为动态编译虽然省空间,但你要额外处理 libc 的依赖问题。万一目标板上的 libc 版本和你的编译环境不一致,程序启动就崩。我在一个项目中吃过这个亏,后来老老实实改回静态编译,再也没出过问题。
经验之谈:静态编译的 BusyBox 大约 800KB~1.2MB(取决于你勾了多少 Applet)。对于大多数嵌入式设备来说,这个体积完全可以接受。别为了省那几百 KB 去折腾动态库,不值得。
4.3 安装路径:别装到系统目录去了
配置界面的最后一项,是 Installation Options → BusyBox installation prefix。默认值是 ./_install。
这个路径是什么意思?就是你执行 make install 之后,编译好的 BusyBox 二进制以及所有符号链接,会被放到这个目录下。
我强烈建议你不要修改这个默认值。为什么?
- 如果你改成
/usr/local或/,然后手滑执行了make install,你的开发机上的系统命令会被 BusyBox 覆盖掉。嗯,我身边真有同事干过这事,然后重装了系统。 - 保持
./_install,你可以在开发阶段随时检查生成的文件结构,确认符号链接是否正确。
我的习惯:编译完成后,先检查 _install 目录下的文件列表。比如执行 ls -la _install/bin/,看看 ls、cp 这些命令的符号链接是否指向了 busybox。如果发现某个命令没生成链接,说明对应的 Applet 没勾上,赶紧回去补。
4.4 一个完整的配置流程示例
说了这么多,不如直接上手走一遍。假设我们要为一个 ARM 开发板裁剪 BusyBox:
# 1. 加载默认配置
make defconfig
# 2. 进入菜单配置
make menuconfig
# 3. 设置交叉编译工具链
# 进入:Build Options → Cross Compiler prefix
# 填入:arm-linux-gnueabihf-
# 4. 开启静态编译
# 进入:Build Options → Build BusyBox as a static binary
# 按 Y 选中
# 5. 关闭调试信息
# 进入:Debugging Options → Build with debug information
# 按 N 取消选中
# 6. 按需勾选 Applet(以 Networking 为例)
# 进入:Networking Utilities
# 只保留:ping, ifconfig, route, telnetd
# 其他全部按 N 取消
# 7. 确认安装路径
# 进入:Installation Options → BusyBox installation prefix
# 保持默认:./_install
# 8. 保存退出
# 按 Tab 键选择 Save,回车
# 9. 编译
make -j4
# 10. 安装到 _install 目录
make install
踩坑提醒:我曾经在配置完成后,直接执行 make 忘了加 -j 参数,单核编译等了 20 分钟。后来学乖了,make -j$(nproc) 走起。另外,如果你改了配置,记得先 make clean 再重新编译,否则可能出现旧的目标文件残留。
嗯,到这里,make menuconfig 的核心用法你应该心里有数了。说白了就是三件事:选对 Applet、配好编译选项、定准安装路径。下次打开配置界面,别慌,按这个思路来就行。
一句话总结:BusyBox 裁剪不是做减法,而是做「精准选择」。你选进来的每一个 Applet,都应该有它的用途。