Nginx源码不能直接交叉编译,必须修改configure脚本以跳过运行时探测、硬编码类型大小(如ngx_size="4")、替换gcc为$CC,并交叉编译zlib/PCRE/OpenSSL后显式指定路径。

Nginx 源码不能直接交叉编译,必须修改构建脚本并适配目标平台特性。核心难点不在编译本身,而在 configure 脚本的非交叉感知设计——它默认调用本地编译器运行测试程序,而 ARM 上生成的二进制在 x86 主机上根本无法执行。
准备匹配的交叉工具链
选择与目标设备 ABI 和 libc 版本一致的工具链是前提。例如:
- ARM32(如 i.MX6、全志 H3):用
arm-linux-gnueabihf-前缀工具链(如 Linaro GCC 9.4+) - ARM64(如 RK3566、树莓派 4/5):用
aarch64-linux-gnu-前缀工具链 - 验证方式:
aarch64-linux-gnu-gcc -v或arm-linux-gnueabihf-gcc -v,确认输出含 target 架构信息 - 避免混用:工具链的 libc(glibc/musl)版本需尽量贴近目标板系统,可用
readelf -A /lib/ld-linux-aarch64.so.1查看目标系统 ABI 特性
修改 Nginx 构建脚本以支持交叉编译
configure 默认不识别 $CC 环境变量,且大量依赖运行时探测(如 int 大小、系统调用支持),必须手动干预:
- 编辑
auto/cc/name:将硬编码的gcc替换为$CC,并在末尾 echo 正确编译器名(如echo arm-linux-gnueabihf-gcc) - 编辑
auto/types/sizeof:跳过所有编译+运行测试逻辑,直接写死关键类型大小,例如:ngx_size="4"(ARM32)或ngx_size="8"(ARM64);ngx_ptr_t="8";ngx_off_t="8" - 编辑
auto/feature:注释掉所有ngx_feature_test块,防止因无法运行测试程序而退出 - 可选但推荐:在
src/os/unix/ngx_errno.h中补充#define NGX_SYS_NERR 134(根据目标内核头文件asm/errno.h确认实际值)
预编译依赖库并指定路径
Nginx 依赖 zlib、PCRE、OpenSSL,这些也必须交叉编译,不能复用主机库:
-
zlib:进入源码目录,执行
./configure --prefix=/path/to/install/zlib --host=aarch64-linux-gnumake && make install -
PCRE:同理,
--host=arm-linux-gnueabihf或对应目标;启用 JIT 可加--enable-jit -
OpenSSL:使用
./Configure linux-aarch64 no-shared no-asm --prefix=...(ARM64)或linux-armv4(ARM32);避免用 3.x 版本,1.1.1 系列兼容性更稳 - 配置 Nginx 时显式指向这些库:
--with-zlib=/path/to/zlib \<br> --with-pcre=/path/to/pcre \<br> --with-openssl=/path/to/openssl
执行配置与编译
确保环境变量就位后运行 configure:
- 设置:
export CC=aarch64-linux-gnu-gcc、export NGX_PLATFORM=linux - 执行:
./configure \<br> --prefix=/usr/local/nginx \<br> --with-http_ssl_module \<br> --with-zlib=/path/to/zlib \<br> --with-pcre=/path/to/pcre \<br> --with-openssl=/path/to/openssl \<br> --crossbuild=linux:<br>aarch64
(部分新版支持该 flag,但非必需) - 成功后运行
make即可生成 ARM 可执行文件;make install会复制到--prefix指定路径(建议先设为本地临时目录,再整体同步到目标板) - 检查产物:
file objs/nginx应显示ELF 64-bit LSB pie executable, ARM aarch64或对应架构
整个过程不复杂但容易忽略细节,关键是让 configure 放弃“运行测试”,转为信任人工指定的平台参数。


















