1. 项目概述
在嵌入式视频监控和直播系统中,RTMP协议因其低延迟、高稳定性和广泛的浏览器兼容性成为主流选择。作为一款轻量级高性能Web服务器,Nginx通过第三方模块nginx-rtmp-module实现了对RTMP协议的支持,使其成为嵌入式视频流处理的理想解决方案。
本项目基于STM32MP157开发板,详细记录从源码交叉编译Nginx(含RTMP模块)到最终部署的全过程。与常规PC环境编译不同,嵌入式场景需要解决三个核心问题:
- 依赖库的交叉编译(OpenSSL/Zlib/PCRE)
- Nginx自身对交叉编译工具链的适配
- 针对ARM架构的特定优化
最终生成的Nginx可执行文件体积控制在3MB以内,内存占用低于10MB,完全满足STM32MP157这类资源受限设备的运行需求。
2. 环境准备与依赖库处理
2.1 工具链配置
使用ARM官方提供的gcc-arm-9.2工具链,需确认以下环境变量设置正确:
bash复制export PATH=$PATH:/usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin
export CROSS_COMPILE=arm-none-linux-gnueabihf-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
注意:工具链路径需根据实际安装位置调整,建议通过
arm-none-linux-gnueabihf-gcc -v验证工具链有效性
2.2 依赖库下载与解压
创建统一工作目录并获取所有必需组件:
bash复制mkdir -p /home/RTMP_Project/nginx_cross/src
cd /home/RTMP_Project/nginx_cross/src
# RTMP模块
git clone https://github.com/arut/nginx-rtmp-module.git
# 其他依赖
wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz
wget https://zlib.net/fossils/zlib-1.2.13.tar.gz
wget -O pcre-8.45.tar.gz https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz/download
wget http://nginx.org/download/nginx-1.20.0.tar.gz
# 解压所有压缩包
for f in *.tar.gz; do tar -zxvf "$f"; done
关键组件版本选择依据:
- OpenSSL 1.1.1w:长期支持版本,安全性更新持续到2023年9月
- Nginx 1.20.0:稳定分支,与RTMP模块兼容性已验证
- PCRE 8.45:传统正则库版本,Nginx官方推荐
3. Nginx交叉编译实战
3.1 源码级修改
3.1.1 编译系统适配
修改auto/cc/name文件第21行,注释掉退出指令:
c复制# 原内容: test -z "$NGX_PLATFORM" && { echo "$0: error: cannot detect platform" >&2; exit 1; }
# 修改为:
test -z "$NGX_PLATFORM" && { echo "$0: error: cannot detect platform" >&2; } # exit 1;
3.1.2 类型大小检测
修改auto/types/sizeof文件:
makefile复制# 第15行修改为固定值
ngx_size=4
# 第36行指定交叉编译器
$CC -> arm-none-linux-gnueabihf-gcc
3.2 配置与编译
生成Makefile的配置命令:
bash复制./configure \
--prefix=/home/RTMP_Project/nginx_cross/install \
--with-http_ssl_module \
--with-http_mp4_module \
--with-http_v2_module \
--with-openssl=../openssl-1.1.1w \
--with-openssl-opt="no-asm no-tests linux-generic32" \
--without-http_upstream_zone_module \
--add-module=../nginx-rtmp-module \
--with-cc=${CROSS_COMPILE}gcc \
--with-cpp=${CROSS_COMPILE}cpp \
--with-pcre=../pcre-8.45 \
--with-zlib=../zlib-1.2.13
关键参数解析:
no-asm:禁用汇编优化,避免x86指令集混入linux-generic32:针对32位ARM的通用优化without-http_upstream_zone_module:减少不必要的模块
3.3 Makefile深度修改
3.3.1 PCRE编译规则
修改objs/Makefile中PCRE部分:
makefile复制../pcre-8.45/Makefile: objs/Makefile
cd ../pcre-8.45 \
&& if [ -f Makefile ]; then $(MAKE) distclean; fi \
&& CC="$(CC)" CFLAGS="-O2 -fomit-frame-pointer -pipe" \
./configure --disable-shared --host=arm-linux-gnueabihf
3.3.2 OpenSSL编译优化
makefile复制../openssl-1.1.1w/.openssl/include/openssl/ssl.h: objs/Makefile
cd ../openssl-1.1.1w \
&& if [ -f Makefile ]; then $(MAKE) clean; fi \
&& ./Configure --prefix=$(PWD)/../openssl-1.1.1w/.openssl \
no-shared no-threads no-asm no-tests linux-generic32 \
&& $(MAKE) CC=arm-none-linux-gnueabihf-gcc \
&& $(MAKE) install_sw LIBDIR=lib
3.4 头文件补丁
在objs/ngx_auto_config.h末尾添加:
c复制#ifndef NGX_HAVE_SYSVSHM
#define NGX_HAVE_SYSVSHM 1
#endif
4. 编译与部署
4.1 执行编译
bash复制make -j$(nproc)
make install
成功编译后,安装目录结构如下:
code复制install/
├── conf/ # 配置文件
├── html/ # 默认网页
├── logs/ # 日志目录
└── sbin/nginx # 主程序
4.2 目标板部署
- 将整个install目录拷贝到开发板
- 添加执行权限:
bash复制chmod +x /usr/local/nginx/sbin/nginx - 测试运行:
bash复制
/usr/local/nginx/sbin/nginx -t
5. 常见问题排查
5.1 编译错误:undefined reference to shmget
解决方案:
- 确认
ngx_auto_config.h中已定义NGX_HAVE_SYSVSHM - 检查内核配置是否启用System V IPC
5.2 运行时报SSL相关错误
可能原因:
- OpenSSL库未正确部署
- 证书路径配置错误
处理步骤:
bash复制# 检查openssl库
ldd /usr/local/nginx/sbin/nginx | grep ssl
# 确认证书路径
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /usr/local/nginx/conf/cert.key \
-out /usr/local/nginx/conf/cert.crt
5.3 高并发场景崩溃
优化建议:
- 调整worker进程数:
nginx复制worker_processes 2; # 根据CPU核心数设置 - 限制连接数:
nginx复制events { worker_connections 1024; }
6. 性能优化技巧
6.1 二进制瘦身
编译后可使用strip移除调试符号:
bash复制arm-none-linux-gnueabihf-strip objs/nginx
6.2 内存池优化
修改src/core/ngx_palloc.c:
c复制#define NGX_MAX_ALLOC_FROM_POOL (4096 * 2) # 默认4K调整为8K
6.3 日志分级输出
生产环境建议关闭debug日志:
nginx复制error_log logs/error.log warn;
在STM32MP157开发板上实测数据:
- 内存占用:8.3MB(空载)
- 1080P推流CPU占用:35-45%
- 启动时间:< 1s
