Windows系统编译64位Nginx

今天随便检查了下服务器,才发现服务器上用了这么久的Nginx居然还是32位的。又去Nginx官网看了看,只给Windows系统提供32位的预编译Nginx可执行程序。没有办法,只能自己编译了(顺便加上后量子密钥交换机制的支持)。

参考了网络上的教程和官方文档

安装Visual Studio

需要用Visual Studio的编译工具NMake来编译Nginx,自然先要下载Visual Studio。此处使用Visual Studio 2022

在安装程序中,选择“使用C++的桌面开发”。

安装必要工具

比较简单,安装向导一路Next就好了。

下载库源代码

暂时不要解压。

编译前准备

克隆一下Nginx的源代码:

git clone https://github.com/nginx/nginx.git

进入Nginx源代码文件夹,创建文件夹objs/lib/

cd nginx
mkdir objs
mkdir objs/lib
cd objs/lib

把上面下载的3个压缩包都解压到objs/lib/中,应该会有如下文件夹结构:

nginx/
└─ objs/
  └─ lib/
    ├─ openssl-=OpenSSL版本=/
    ├─ zlib-=zlib版本=/
    └─ pcre2-=PCRE2版本=/

打开“x64 Native Tools Command Prompt for VS 2022”,输入cl.exe,得到cl.exe的版本号:

> cl.exe
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.44.35217 版
版权所有(C) Microsoft Corporation。保留所有权利。

用法: cl [ 选项... ] 文件名... [ /link 链接选项... ]

我这的版本号是19.44.35217

编辑文件auto\cc\msvc,找到下面这条指令:

NGX_MSVC_VER=`$NGX_WINE $CC 2>&1 | grep 'C/C++.* [0-9][0-9]*\.[0-9]' 2>&1 \
                                 | sed -e 's/^.* \([0-9][0-9]*\.[0-9].*\)/\1/'`

直接把后面的值改为刚才得到的版本号即可:

NGX_MSVC_VER="19.44.35217"

再找到这条指令:

# stop on warning
CFLAGS="$CFLAGS -WX"

注释或者删除它,防止遇到警告时停止。

# stop on warning
# CFLAGS="$CFLAGS -WX"

然后配置OpenSSL进行64位的编译。编辑文件auto\lib\openssl\makefile.msvc,按照下表修改:

原文 替换为
perl Configure $(OPENSSL_TARGET) no-shared no-threads perl Configure VC-WIN64A no-shared no-threads
ms\do_ms.bat ms\do_win64a.bat
ms\do_ms ms\do_win64a

然后用MSYS2来生成Makefile,随便打开个MSYS2的命令行,导航到nginx,运行如下命令[1]

auto/configure \
    --with-cc=cl \
    --builddir=objs \
    --with-debug \
    --prefix= \
    --conf-path=conf/nginx.conf \
    --pid-path=logs/nginx.pid \
    --http-log-path=logs/access.log \
    --error-log-path=logs/error.log \
    --sbin-path=nginx.exe \
    --http-client-body-temp-path=temp/client_body_temp \
    --http-proxy-temp-path=temp/proxy_temp \
    --http-fastcgi-temp-path=temp/fastcgi_temp \
    --http-scgi-temp-path=temp/scgi_temp \
    --http-uwsgi-temp-path=temp/uwsgi_temp \
    --with-cc-opt=-DFD_SETSIZE=1024 \
    --with-pcre=objs/lib/pcre2-=PCRE2版本= \
    --with-zlib=objs/lib/zlib-=zlib版本= \
    --with-select_module \
    --with-http_v2_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_stub_status_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_auth_request_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_slice_module \
    --with-mail \
    --with-stream \
    --with-openssl=objs/lib/openssl-=OpenSSL版本= \
    --with-http_ssl_module \
    --with-mail_ssl_module \
    --with-stream_ssl_module \
    --with-stream_ssl_preread_module \
    --with-openssl-opt="no-asm no-tests enable-ktls"

可以参考Nginx文档来选择添加或减少编译的模块。

自定义模块

如果要添加非官方的模块,就把模块源代码克隆到objs/lib/文件夹里,然后添加编译参数:

--add-module="objs/lib/<模块1源代码>" \
--add-module="objs/lib/<模块2源代码>" \
...
关于QUIC模块

本来想要添加HTTP/3 QUIC支持的,但Nginx在Windows上的UDP架构是完全损坏的,所以编译会出错,希望以后可以支持吧。

开始编译

打开“x64 Native Tools Command Prompt for VS 2022”,导航到nginx,执行:

nmake

然后只需等它编译完成就好啦,最终的可执行文件是objs/nginx.exe

最后会有一个找不到命令“sed”的错误,不用担心,Nginx其实已经编译好了。


  1. 编译参数和官方构建的参数基本一致,OpenSSL编译选项加了enable-ktls来支持后量子加密,还有添加SSL预读模块。 ↩︎