Ubuntu 22.04 编译安装 Apache NuttX 13.1.0 指南
在 Ubuntu 22.04 上编译安装 Apache NuttX 13.1.0,覆盖 sim 模拟器目标与 STM32 ARM 交叉编译目标的完整实测指南。
Ubuntu 22.04 编译安装 Apache NuttX 13.1.0 指南
目标:在一台 Ubuntu 22.04 服务器上从官方源码包编译 Apache NuttX 13.1.0:先构建 sim 模拟器目标并运行 NSH 采集验证,再以 gcc-arm-none-eabi 完成 STM32 交叉编译,全流程已在 Ubuntu 22.04 实测通过。
一、环境信息
| 项目 | 内容 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(内核 6.8.0-138-generic) |
| 系统架构 | x86_64(amd64) |
| 编译工具链 | gcc 11.4.0、GNU Make 4.3、flex 2.6.4、bison 3.8.2、gperf 3.1、genromfs |
| 配置工具 | python 3.10.12 + kconfiglib 14.1.0(menuconfig/olddefconfig 等) |
| 交叉工具链 | arm-none-eabi-gcc 10.3.1(apt 包 gcc-arm-none-eabi) |
| NuttX 版本 | 13.1.0(apache-nuttx-13.1.0.tar.gz 与 apache-nuttx-apps-13.1.0.tar.gz) |
| 源码布局 | /opt/nuttx/nuttx 与 /opt/nuttx/apps 同级 |
| 产物 | nuttx(sim:x86-64 ELF;stm32f4discovery:ARM 32 位 ELF) |
说明:NuttX 是 Apache 旗下实时操作系统,采用自研的 Makefile + Kconfig 构建体系;apps 是官方应用仓库(NSH、示例、网络应用等),与 nuttx 源码同级目录放置即可被构建系统发现。
💡 技术拓展:RTOS 构建系统怎么选?NuttX 自研体系(Kconfig + Make,本文实测)零额外依赖,配置项即 C 宏;Zephyr 的 CMake + west 依赖重但生态新;Mynewt 的 newt 自带包管理(见本站 Mynewt 系列)。NuttX 的特点是用
tools/configure.sh <板>:<配置>一条命令落配置,再用一条 make 出固件,学习曲线最平。本文全部围绕 NuttX 自研构建体系展开。
二、前置条件与依赖安装
2.1 安装编译工具
apt-get update
apt-get install -y gcc g++ make libncurses-dev flex bison gperf genromfs git wget curl unzip
回显(输出节选):
Setting up gperf (3.1-1build1) ...
Setting up genromfs (0.5.2-2) ...
验证:
gcc --version | head -1
make --version | head -1
gperf --version | head -1
回显:
gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
GNU Make 4.3
GNU gperf 3.1
2.2 安装 Kconfig 工具链(含关键排障)
NuttX 配置阶段依赖 kconfig-tweak、menuconfig、olddefconfig 等命令。Ubuntu 22.04 没有 kconfig-frontents 软件包(apt-cache policy 查询为空),可用 pip 的 kconfiglib:
apt-get install -y python3-pip
pip3 install kconfiglib
ls /usr/local/bin/ | grep -E "menuconfig|olddefconfig|savedefconfig" | head
回显(输出节选):
defconfig
menuconfig
olddefconfig
savedefconfig
踩坑一:kconfiglib 不提供 kconfig-tweak。tools/configure.sh 调用的 sethost.sh 直接执行 kconfig-tweak,实测缺它时报 kconfig-tweak: command not found。kconfiglib.py 无按文件名分发的能力(实测符号链接为 kconfig-tweak 后执行报语法错误),需写一个最小替换脚本覆盖 sethost.sh 用到的 4 种调用(--file/--enable/--disable/--set-str/--set-val):
cat > /usr/local/bin/kconfig-tweak <<'EOF'
#!/bin/bash
# Minimal kconfig-tweak replacement for NuttX sethost.sh
f=.config; mode=""; sym=""; val=""
while [ $# -gt 0 ]; do
case "$1" in
--file) f="$2"; shift 2;;
--enable|--disable|--set-str|--set-val) mode="$1"; sym="$2"; shift 2;;
*) val="$1"; shift;;
esac
done
base="${sym#CONFIG_}"
case "$mode" in
--enable)
sed -i "s|^# ${base} is not set|${sym}=y|; s|^${sym}=n$|${sym}=y|" "$f"
grep -q "^${sym}=" "$f" || echo "${sym}=y" >> "$f" ;;
--disable)
sed -i "s|^${sym}=y$|# ${base} is not set|" "$f" ;;
--set-str)
if grep -q "^${sym}=" "$f"; then sed -i "s|^${sym}=.*$|${sym}=\"${val}\"|" "$f"; else echo "${sym}=\"${val}\"" >> "$f"; fi ;;
--set-val)
if grep -q "^${sym}=" "$f"; then sed -i "s|^${sym}=.*$|${sym}=${val}|" "$f"; else echo "${sym}=${val}" >> "$f"; fi ;;
esac
exit 0
EOF
chmod +x /usr/local/bin/kconfig-tweak
解说:sethost.sh 在 Linux 宿主上只做“禁用 WINDOWS/MACOS/BSD 宏、启用 HOST_LINUX 与 SIM_X8664_SYSTEMV、olddefconfig”几个动作,上述脚本完全覆盖其调用面。补齐后 configure.sh 正常走通。
踩坑二:xxd 缺失导致链接失败。sim:nsh 配置启用了 /etc romfs 镜像,构建时把 init.rc 经 genromfs 打包后用 xxd 转 C 数组;Ubuntu 默认无 xxd,实测链接报大量 undefined reference to romfs_img:
apt-get install -y vim-common
which xxd
回显:
/usr/bin/xxd
注意:若曾在缺 xxd 状态下编译过,中间产物 etctmp.c 已是坏文件且时间戳较新不会被重生成,需删除 boards/sim/sim/sim/src/etctmp.c 后重编(详见 FAQ Q3)。
三、获取源码并校验
mkdir -p /opt/nuttx && cd /opt/nuttx
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-13.1.0.tar.gz
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-13.1.0.tar.gz.sha512
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-apps-13.1.0.tar.gz
wget https://dlcdn.apache.org/nuttx/13.1.0/apache-nuttx-apps-13.1.0.tar.gz.sha512
官方 .sha512 为多行无文件名格式,逐包校验:
for f in apache-nuttx-13.1.0.tar.gz apache-nuttx-apps-13.1.0.tar.gz; do
wget -q https://dlcdn.apache.org/nuttx/13.1.0/$f.sha512 -O - | sha512sum -c -
done
回显:
apache-nuttx-13.1.0.tar.gz: OK
apache-nuttx-apps-13.1.0.tar.gz: OK
解说:dlcdn 的 .sha512 文件内容为“摘要 空格 文件名”单行格式,恰好能被 sha512sum -c 直接校验,两个包实测均为 OK。本地留存基线值:
sha256sum apache-nuttx-13.1.0.tar.gz apache-nuttx-apps-13.1.0.tar.gz
回显:
3f0fd8c0289b01865fdec3bba3d7747635b8f568fb8d6450b1a98aa0a3438d33 apache-nuttx-13.1.0.tar.gz
86fdee110058f0303041b9b62d467aa0795a5f11a3caeeab108c558ebba45ac4 apache-nuttx-apps-13.1.0.tar.gz
解压为标准布局(nuttx/ 与 apps/ 同级):
tar xzf apache-nuttx-13.1.0.tar.gz
tar xzf apache-nuttx-apps-13.1.0.tar.gz
mv apache-nuttx-apps-13.1.0 apps
ls
回显:
apache-nuttx-13.1.0.tar.gz apps nuttx apache-nuttx-apps-13.1.0.tar.gz
解说:主线包解压后目录名就是 nuttx/(无版本前缀);apps 包解压为 apache-nuttx-apps-13.1.0/,重命名为 apps 即成标准布局。构建系统按 ../apps 相对路径找应用仓库。
四、配置 sim 模拟器目标
cd /opt/nuttx/nuttx
./tools/configure.sh sim:nsh
回显(输出节选):
Copy files
Select the host platform: Linux
Refreshing...
解说:configure.sh 做三件事——拷贝 boards/sim/sim/sim/configs/nsh/defconfig 为 .config、执行 sethost.sh 调整宿主宏、olddefconfig 补齐依赖项。生成物为 .config 与 Make.defs:
grep -E "CONFIG_HOST_LINUX=|CONFIG_SIM_X8664_SYSTEMV=|CONFIG_NSH_LIBRARY" .config | head -3
回显:
CONFIG_HOST_LINUX=y
CONFIG_NSH_LIBRARY=y
解说:HOST_LINUX 确认宿主设置成功;NSH_LIBRARY 表示 NSH shell 已并入配置。如需改配置,用 make menuconfig(kconfiglib 的 menuconfig,实测可用)保存退出即可。
五、编译与运行验证
5.1 编译
make -j$(nproc)
回显(输出节选):
LD: nuttx
make: Leaving directory '/opt/nuttx/nuttx'
验证产物:
ls -l nuttx
回显:
-rwxr-xr-x 1 root root 4663747 Oct 14 17:36 nuttx
解说:sim 目标产物约 4.5MB,是宿主 x86-64 可执行文件(ELF64),直接可运行。
5.2 运行 NSH
NuttX sim 本就是设计为在 Linux 开发机上直接运行的官方特性,执行产物即进入交互式 NSH:
./nuttx
回显:
NuttShell (NSH) NuttX-13.1.0
nsh> uname -a
NuttX 13.1.0 2b5c0de5e9 Oct 14 2026 17:36:14 sim sim
nsh>
解说:banner 表明版本 13.1.0、目标板 sim、架构 sim。把命令写进文件管道喂入即可批量执行(NSH 命令实测明细见本系列《Apache NuttX 13.1.0 NSH 常用命令详解》)。
5.3 systemd 托管说明
NuttX sim 是开发期工具,不建议作为系统服务常驻;如确需后台挂起,用 tmux/screen 会话托管即可,不写 systemd 单元(固件模拟进程无守护化价值)。
六、ARM 交叉编译方案
6.1 安装交叉工具链
apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi
arm-none-eabi-gcc --version | head -1
回显:
arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1 20210621 (release)
6.2 切换目标并编译
make distclean
./tools/configure.sh stm32f4discovery:nsh
make -j$(nproc)
回显(输出节选):
LD: nuttx
验证产物架构:
ls -l nuttx nuttx.hex
arm-none-eabi-readelf -h nuttx | grep -E "Class|Machine|Entry"
arm-none-eabi-size nuttx
回显:
-rwxr-xr-x 1 root root 276056 Oct 14 17:41 nuttx
-rw-r--r-- 1 root root 257696 Oct 14 17:41 nuttx.hex
Class: ELF32
Machine: ARM
Entry point address: 0x8000189
text data bss dec hex filename
90711 884 4604 96199 177c7 nuttx
解说:ELF32 + ARM 确认是 STM32 固件;text 90711 字节说明 nsh 精简配置体积约 89KB;nuttx.hex 是烧录用 Intel HEX。distclean 会清掉 sim 配置与产物,两个目标切换需重编(FAQ Q7 给出共存技巧)。烧录不属本文范围,产物可交由 st-flash/openocd 流程。
七、方案对比
| 维度 | sim:nsh(本文主线) | stm32f4discovery:nsh(交叉编译) | 其他 ARM 板 |
|---|---|---|---|
| 工具链 | 宿主 gcc 11.4.0 | arm-none-eabi-gcc 10.3.1 | 按芯片选 |
| 产物形态 | x86-64 ELF,直接运行 | ARM ELF32 + hex,烧录 | 同左 |
| 运行验证 | 开发机上直接跑 NSH | 需真机/仿真器 | 需真机 |
| 配置入口 | tools/configure.sh sim:nsh | tools/configure.sh stm32f4discovery:nsh | 同格式 |
| 适用阶段 | 逻辑开发/测试/学习 | 真机部署 | 真机部署 |
| 实测结论 | 通过 | 编译通过(未烧录) | — |
解说:NuttX 官方推荐工作流即“sim 先行、真机收尾”; boards/ 下 500+ 板级配置都以 <板>:<配置> 形式可用,切换成本只有一条命令。
八、常见问题(FAQ)
Q1:configure.sh 报 kconfig-tweak: command not found? A:Ubuntu 22.04 无 kconfig-frontents 包。pip3 install kconfiglib 提供了 menuconfig/olddefconfig 但不含 kconfig-tweak,按 2.2 节脚本补一个最小实现即可;只依赖 sed/grep,无需编译。
Q2:make 链接报 undefined reference to romfs_img? A:sim:nsh 需要把 init.rc 打包进 romfs,构建规则调用 xxd 而 Ubuntu 默认没装。apt-get install vim-common 后重编;若之前失败过,还要删掉 boards/sim/sim/sim/src/etctmp.c 这个坏中间产物再编(时间戳问题导致它不会自动重生成)。
Q3:装了 xxd 还是链接失败? A:检查 Makefile 里 romfs 目标的中间文件(etctmp.c/etctmp)是否残留坏内容。rm -f boards/sim/sim/sim/src/etctmp.c 后 make 重新走一遍生成链即可,实测恢复正常。
Q4:运行 ./nuttx 报错或卡住? A:sim 目标以交互方式运行,管道喂命令时注意最后加 exit;若报 tcsetattr 类错误,确认 stdin 是终端或管道(重定向文件也支持)。图形类 sim 配置(nx/uikit)才需要 X 环境,nsh 无需。
Q5:make menuconfig 中文乱码或方向键无效? A:确认终端 UTF-8 且 libncurses-dev 已装;kconfiglib 的 menuconfig 是 Python 实现,对终端兼容性好于老 kconfig-frontents,实测方向键/空格/ESC 正常。
Q6:如何恢复改乱的 .config?
A:make distclean 彻底清空后重新 configure.sh;或用 make olddefconfig 按当前 .config 补齐缺失项。想导出精简 defconfig 用 make savedefconfig(kconfiglib 版可用)。
Q7:sim 和 arm 目标能共存吗? A:同一源码树同一时刻只有一份 .config,切目标需 make distclean + configure.sh。要共存就复制两份源码目录(如 /opt/nuttx/nuttx 与 /opt/nuttx-arm/nuttx),代价是磁盘与重复编译时间。
Q8:交叉编译产物怎么确认没用错工具链? A:arm-none-eabi-readelf -h nuttx 看 Machine 应为 ARM(实测 0x28)、Class 为 ELF32;宿主 gcc 产物则是 x86-64 ELF。Entry point 与链接脚本(ld.script)匹配即说明目标选对。
Q9:apps 仓库放哪里才被识别? A:与 nuttx/ 同级并命名为 apps/(实测 mv apache-nuttx-apps-13.1.0 apps)。构建系统按固定相对路径引用,放别处会在 make 阶段报找不到 apps 相关目标。
Q10:如何卸载? A:见下节。
九、卸载
cd /opt/nuttx/nuttx
make distclean
rm -rf /opt/nuttx
pip3 uninstall -y kconfiglib
apt-get purge -y gcc-arm-none-eabi
解说:distclean 恢复源码树到发布状态;删除源码目录、pip 包与交叉工具链即完全卸载;kconfig-tweak 包装脚本一并删除(rm -f /usr/local/bin/kconfig-tweak)。
十、参考链接
- NuttX 13.1.0 官方发行页:https://dlcdn.apache.org/nuttx/13.1.0/
- NuttX 官方文档:https://nuttx.apache.org/docs/latest/
- NuttX 快速入门(Ubuntu 依赖清单):https://nuttx.apache.org/docs/latest/quickstart/install.html
- boards/ 板级配置仓库说明:https://nuttx.apache.org/docs/latest/components/boards.html
- kconfiglib 项目:https://github.com/ulfalizer/Kconfiglib