简介:在Windows 10下使用VS2017编译带http-flv扩展的Nginx,常因依赖源码与工具链不齐而卡壳。这份RAR压缩包面向需要完成此类编译工作的开发者,解决了从零搜集匹配版本源码、配置Perl环境与依赖路径的麻烦。包内共28个文件,大小约102.07MB,以conf配置文件、license与readme说明文档、pl辅助脚本、html默认页面及vim/win-utf等编码相关文件为主,并包含编译生成的nginx.exe可执行文件;目录结构保留Nginx原生布局,logs、temp、conf等模块一目了然,便于编译后直接运行调试。内容涵盖Nginx 1.20.2源码、http-flv模块源码、OpenSSL、PCRE、Zlib源码,以及ActivePerl、msys2、sed等必要工具,支持按VS2017工程完整编译出带http-flv扩展的Nginx,省去手动匹配版本和调整编译参数的大量时间。目前已有542人学习查看,适合正在研究Nginx二次开发或流媒体服务的开发者作为一站式参考包;若在编译过程中遇到报错,也能借助包内完整源码与文档定位问题。
1. Windows编译Nginx必要工具:很多人拿到.rar也做不成的事
同样拿到一个写着“Windows编译Nginx必要工具.rar”的压缩包,有人半天跑出nginx.exe,有人解压完就卡住——差别不在工具全不全,而在不知道Windows里编译Nginx和Linux完全是两套逻辑。这个标题真正要解决的是:让你在Windows原生环境,不装虚拟机、不开Docker,也能自己编译出带特定模块的Nginx可执行文件。适合三类人:需要给Nginx集成自定义模块的运维,想用最新特性但官方Windows包滞后的开发者,想摆脱Linux编译环境做自动化构建的团队。先说结论:编译本身十几次命令,麻烦的是工具链识别、依赖目录摆放和三个特别容易踩的隐藏坑。
2. 编译前的工具链选型:MinGW 还是 MSVC,别等报错才后悔
2.1 两条主流路线:MSYS2 与 Visual Studio 的差别
Nginx官方Windows版本是用MSVC编译的,官方文档里也确实有一份基于Visual Studio的构建步骤,但一线做下来,绝大多数人最终走的都是MSYS2加MinGW-w64这条路。原因很简单:Nginx的configure构建体系是按Unix环境写的,MSYS2提供了一个带bash、awk、make、gcc的兼容层,Nginx源码里的./auto/configure脚本在它底下能直接运行。而MSVC路线要求你手工处理PCRE2、zlib、OpenSSL各自的nmake构建,任何一个依赖的环境变量没配对,编译链就断在中途,来回折腾的时间足够用MSYS2把整个Nginx编出两遍。
MSYS2和Cygwin也不是一回事。Cygwin编译出来的exe依赖cygwin1.dll,运行时还得带着一套模拟层;MSYS2下选mingw-w64工具链,生成的是原生Windows PE可执行文件,不依赖额外dll,拷到别的机器直接能跑。选型时记住这句话:日常自己编译、给项目做定向构建,用MSYS2;除非你要写一个必须和MSVC ABI对接的Windows原生C模块,否则没必要碰Visual Studio那条路。
2.2 必要工具清单与“必要工具.rar”里通常有什么
把这类rar包拆开看,里面一般不是一堆安装器,而是三样东西:MSYS2最小环境、Nginx和三个依赖的源码包、一段构建脚本或说明文档。为什么要把它们打包在一起?因为Windows编译Nginx的“必要工具”有固定清单,少一个都会在中途暴露:
| 工具/依赖 | 作用 | 常见坑 |
|---|---|---|
| MSYS2 + mingw-w64 | 提供bash、make、gcc | 没加到PATH导致命令找不到 |
| Perl | OpenSSL构建期脚本依赖 | 缺perl时make中途退出 |
| NASM | OpenSSL汇编优化 | 缺nasm时OpenSSL编译报错 |
| PCRE2 | rewrite正则与location匹配 | 目录名写错直接configure失败 |
| zlib | gzip压缩模块 | 版本目录和configure参数不一致 |
| OpenSSL | SSL/TLS与http_ssl_module | 不指定会编出没有https的nginx |
收到rar包第一件事,确认里面依赖源码版本和你要编译的Nginx版本是否匹配。新版Nginx已经迁移到PCRE2,很多旧教程还教你配PCRE,拿着老工具包去编Nginx 1.25以上版本,configure阶段就会出问题。如果rar包解压后漏了某个工具,不需要重新下载整个包,MSYS2自带pacman包管理器,一条命令补齐:
# 在 MSYS2 bash 里执行,按需补装工具链 pacman -S --needed base-devel \ mingw-w64-x86_64-toolchain \ mingw-w64-x86_64-perl \ mingw-w64-x86_64-nasm参数说明:base-devel提供make、awk、diff等基础构建工具;mingw-w64-x86_64-toolchain是64位gcc全家桶;perl和nasm专门给OpenSSL构建用。注意不要装i686的32位版本,除非你确实需要32位产物,否则后续和系统环境会打架。
2.3 PATH与系统环境变量:先定三个细节
工具装好后,三个细节能让后续少踩很多坑。第一,MSYS2的安装路径必须是纯英文且不带空格,比如C:\msys64。如果rar包解压后目录名带了“必要工具”这类中文,先改成英文短路径再继续,否则configure阶段报错时,你很难分清是路径问题还是依赖问题,这一条是Windows编译Nginx翻车的头号来源。
第二,系统PATH里只需要加C:\msys64\usr\bin,不需要把mingw64的bin目录永久加进去。编译过程全部在MSYS2的bash里进行,它自己会处理工具链路径;在系统PATH里同时挂多个gcc,会让编译器链接混用,警告刷屏还算轻的,链接器直接崩也不少见。第三,设置MAKEFLAGS=-j4这类并行参数。MSYS2下make默认单线程跑Nginx加OpenSSL全量编译,多核机器要等二十分钟以上,export并行参数后能缩短到几分钟。
注意:如果机器上装了Docker,或者经常用Windows启动elasticsearch这类Java服务,系统PATH里可能已经有不少东西。别把MSYS2插在PATH最前面,只在bash里使用它,避免影响其他日常工具。
3. 准备Nginx源码和第三方依赖:PCRE2、zlib、OpenSSL的目录摆放与自动拉取
3.1 先从依赖分工说起:三个源码包各管什么
Nginx在Windows上的编译依赖模型和在Linux上完全一致,三个源码包各司其职。PCRE2负责正则表达式,rewrite模块、location匹配、map指令都依赖它,configure阶段如果探测不到PCRE2,Nginx会跳过rewrite相关功能,编译出来的二进制没有URL重写能力。zlib负责gzip压缩,gzip和gzip_static模块靠它,不配的话响应压缩功能直接没有。OpenSSL负责HTTPS,http_ssl_module需要用到它的库和头文件,这也是“nginx替换ssl证书不生效”一类问题的一大来源——很多人手里的nginx二进制自带模块,但自己编译时忘了指定OpenSSL,编译产物根本不支持https。
这三个依赖在configure阶段的行为也值得说清楚:它们不是用系统里装好的运行库,而是直接编进nginx.exe的。configure传--with-pcre=../pcre2-xx这类参数时,Nginx构建脚本会进入依赖源码目录,把静态库编完再链接进nginx。所以目录名必须和参数完全一致,大小写都不能错。
3.2 用PowerShell脚本把依赖一次性拉下来并校验
如果你拿到的rar包是精简版,缺了某个依赖,可以自己补。下面这个脚本是固定套路:把三个源码包下载到src目录、校验完整性、统一解压。
# prepare-nginx-deps.ps1 # 用法: 在 C:\nginx-build 下执行 ./prepare-nginx-deps.ps1 $ErrorActionPreference = "Stop" $base = "C:\nginx-build" $src = Join-Path $base "src" New-Item -ItemType Directory -Force -Path $src | Out-Null # 版本用变量声明,升级时只改这里 $nginx = "nginx-1.26.2" $pcre2 = "pcre2-10.44" $zlib = "zlib-1.3.1" $openssl = "openssl-3.0.13" $urls = @{ "$nginx.tar.gz" = "https://nginx.org/download/$nginx.tar.gz" "$pcre2.tar.gz" = "https://github.com/PCRE2Project/pcre2/releases/download/$pcre2/$pcre2.tar.gz" "$zlib.tar.gz" = "https://zlib.net/$zlib.tar.gz" "$openssl.tar.gz" = "https://www.openssl.org/source/$openssl.tar.gz" } foreach ($file in $urls.Keys) { $out = Join-Path $src $file if (-not (Test-Path $out)) { Write-Host "Downloading $file ..." Invoke-WebRequest -Uri $urls[$file] -OutFile $out } # 校验压缩包哈希,防止下载截断或被篡改 $hash = Get-FileHash $out -Algorithm SHA256 Write-Host "$file SHA256: $($hash.Hash)" # 统一解压到 src tar -xzf $out -C $src } Write-Host "源码就绪,目录: $src"脚本逻辑分三步:检查文件是否已存在,不存在才下载;下载后立即算SHA256,方便你对照官网发布页的校验值;最后用tar解压。为什么用tar?Windows 10 1803以后系统自带C:\Windows\System32\tar.exe,可以直接解.tar.gz,不需要再装7-Zip。参数说明里有一个坑:Invoke-WebRequest在Windows PowerShell 5.1下走-OutFile时偶尔会提前截断连接,所以哈希校验不能省。解压后顺手删掉压缩包也行,但保留一份能让你下次重新构建时不用再下载。
3.3 目录结构:让configure参数短而稳
目录摆放会直接影响configure命令的写法。我长期用下面这套结构,源码解压后全部保持“名字-版本号”格式,不要嵌套多余目录,不要用带空格的路径:
C:\nginx-build\ msys64\ src\ nginx-1.26.2\ pcre2-10.44\ zlib-1.3.1\ openssl-3.0.13\ logs\ dist\logs放编译日志,dist放最终安装产物。configure里的相对路径从Nginx源码目录出发,../pcre2-10.44这样的写法非常短,也容易检查。如果你把依赖散落在C盘各个目录,configure参数里全是绝对路径,一旦路径带中文或空格,bash会把路径拆成多个词,整个依赖探测直接失败。
4. 在Windows命令行跑通编译:从configure到make的最小操作
4.1 先确认工具版本再动手
编译前先花十秒钟确认工具链是完整的,省得make到一半才发现缺东西。在MSYS2 bash里执行:
# 确认关键工具版本 gcc --version | head -1 perl -v | grep version nasm -v make --version | head -1gcc建议8以上,perl能看到版本信息即可,nasm必须有输出。任何一条提示“command not found”,用前面提到的pacman命令补装。这一步是花十秒钟买十分钟的后悔药,很多人跳过它,最后在OpenSSL阶段被“Missing NASM”卡住,还得回头装。
4.2 最小configure加make命令序列
工具确认无误后,进入Nginx源码目录执行configure。注意这段命令必须在MSYS2的bash里跑,不是在cmd里:
# 在 MSYS2 bash 里执行 cd /c/nginx-build/src/nginx-1.26.2 export MAKEFLAGS=-j4 ./auto/configure \ --with-pcre=../pcre2-10.44 \ --with-zlib=../zlib-1.3.1 \ --with-openssl=../openssl-3.0.13 \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --prefix=/c/nginx-build/dist make make installconfigure参数逐条解释:--with-pcre、--with-zlib、--with-openssl分别指定三个依赖源码的相对路径;--with-http_ssl_module启用HTTPS模块,不加它编译产物不支持SSL;--with-http_v2_module启用HTTP/2;--with-http_stub_status_module提供状态页,后面做验证会用到;--prefix指定make install的落地目录。configure执行完,退出码是0才说明依赖探测全部通过。
make阶段会依次编pcre2、zlib、openssl和nginx本体。看到make[1]: Leaving directory字样基本就成了,然后make install把conf、html、logs和nginx.exe统一放到--prefix指定的目录。如果你不想装到dist,也可以直接从objs/目录里取nginx.exe,但那样conf目录是散的,不如install干净。
4.3 编译日志怎么看:把错误定位到具体依赖
make的输出非常长,尤其是OpenSSL的编译信息会刷几百行。不建议肉眼盯着终端找错误,把输出重定向到文件,再按关键字过滤:
# 编译输出存日志,出错时只看两类信息 make > /c/nginx-build/logs/make.log 2>&1 grep "error:" /c/nginx-build/logs/make.log grep "No such file" /c/nginx-build/logs/make.log前者是真实编译错误,说明源码或工具链问题;后者八成是路径或依赖缺失。有个Windows独有毒点:报错信息经常把Windows路径和MSYS2路径混在一起显示,比如C:/msys64/../openssl-3.0.13/include/openssl/ssl.h。不要被它带偏,先检查configure参数里的相对路径在当前目录下是否成立。
4.4 产物检查:确认编出来的是完整Nginx
make install完成之后,按顺序检查三个东西。第一步用nginx -V确认configure参数都生效了,注意是大写V:
# 1) 查看完整configure参数 /c/nginx-build/dist/nginx.exe -V # 2) 语法检查 /c/nginx-build/dist/nginx.exe -t -p /c/nginx-build/dist/ # 3) 启动并验证 /c/nginx-build/dist/nginx.exe -p /c/nginx-build/dist/ sleep 1 curl -I http://127.0.0.1/nginx -V输出里能看到编译时传入的全部参数,--with-http_ssl_module有没有编进去一目了然。nginx -t检查配置语法,报错会精确到行号。curl -I拿到HTTP/1.1 200才算真正跑通。再强调一次:nginx -v小写只输出版本号,-V大写才有完整configure参数,很多人拿小写的输出截图说“模块没编译进去”,其实是命令用错了。
5. Windows编译Nginx的避坑清单:5次翻车现场与排查路径
这一章列几个我实际踩过、也看同事反复踩的坑。每条按现象、原因、解决的顺序写,可以直接对照排查。
5.1 configure能过,make却在OpenSSL阶段丢头文件
现象:./auto/configure退出码是0,但make跑到openssl目录时报“无法打开 include/openssl/ssl.h”或“openssl/Configure失败”。
原因:OpenSSL 3.x对编译器环境敏感,MSYS2里同时存在多个Perl或NASM版本时,configure脚本选错了执行器。另一个高发原因是--with-openssl指向的目录名和实际解压目录不一致,configure阶段没有真正探测到源码。
解决:先在Nginx源码目录执行ls ../openssl*确认目录名。再分别跑perl -v和nasm -v,确认只存在预期版本。如果机器上确实装了多套Perl,在bash里用export PATH=/mingw64/bin:/usr/bin:$PATH显式指定工具链优先级,把mingw64放到最前面。还有一个有效技巧:configure时加--with-openssl-opt='no-tests',让OpenSSL跳过自带的测试代码编译,能省几分钟,也少一类环境相关报错。
5.2 nginx.exe启动后立刻闪退
现象:双击nginx.exe或者命令行执行后,进程马上退出,任务管理器里看不到nginx进程。
原因:Windows下Nginx不会自动定位自己所在目录,必须用-p参数指定prefix,否则它默认去C:\nginx\conf找配置。闪退还经常是因为logs目录不存在,error.log写不进去,进程直接退出。
解决:用命令行带-p启动,并先跑nginx -t。建议把启动动作固化成一个脚本:
#!/bin/bash # start-nginx.sh 放在 C:\nginx-build 下 NGX_PATH=/c/nginx-build/dist $NGX_PATH/nginx.exe -p $NGX_PATH -c $NGX_PATH/conf/nginx.conf如果依然闪退,去logs/error.log看最后几行。看到bind() to 0.0.0.0:80 failed就走下一个坑的排查流程;看到Unknown directive则说明配置文件语法有问题,回到nginx -t的输出定位。
5.3 80端口被占用:IIS、Docker和系统保留项
现象:启动时日志报bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)。
原因:Windows上80端口被占不一定是进程。IIS的World Wide Web服务默认监听80,Windows的http.sys驱动层还可能存在URL保留项,这两种情况用netstat查不到传统意义上的“LISTENING进程”。装了Docker后,com.docker.backend有时也会抢端口。
解决:先查实际占用,再查系统保留:
# 查看80端口占用进程 netstat -ano | findstr :80 # 查看http.sys保留项 netsh http show urlacl如果是IIS,停掉W3SVC服务;如果是http.sys保留项,执行netsh http delete urlacl url=http://+:80/。临时调试的话,直接把nginx.conf里的listen改成8080更省事。本机多站点开发时,配合本地加虚拟机的多端口Nginx配置,把不同域名指到不同端口,比死磕80端口效率高得多。
5.4 MSYS2的路径转换反杀configure
现象:configure参数明明写了--with-pcre=../pcre2-10.44,输出却提示找不到目录,或者gcc报No such file or directory,路径显示成C:/nginx-build/src/nginx-1.26.2/../pcre2-10.44。
原因:MSYS2会自动做POSIX路径和Windows路径互转。在bash里手写相对路径没事,但configure脚本内部会把参数传给Windows原生的Perl脚本,盘符和分隔符一混,依赖路径就找不到。
解决:保持依赖目录在纯英文短路径里,并且所有操作都在MSYS2 bash中完成,不要从cmd直接调用nginx源码下的configure或perl。极端情况下可以设置export MSYS2_ARG_CONV_EXCL='*'关闭路径转换,但这是下策,正常项目没必要用。
5.5 杀毒软件把nginx.exe当威胁删掉
现象:make install成功,dist/nginx.exe也在,过几分钟再看没了,Windows安全中心提示“已检测到威胁”。偶尔编译到一半,编译器生成的临时exe被锁定,make直接失败。
原因:MinGW编出来的exe没有数字签名,特征码容易被启发式引擎误报。如果用upx压过exe减小体积,误报概率更高。
解决:把C:\nginx-build整个目录加进Windows Defender排除项,病毒和威胁防护设置里加目录即可。第三方杀软同理。注意这只针对受控开发目录,不是让你全局关防护。生成完的exe要上生产服务器时,建议在服务器上重新扫一遍确认干净再部署,这是基本习惯。
6. 编译产物的验证技巧与进阶用途:别只停留在能启动
能稳定编出nginx.exe之后,验证要做细,不能只停在“能启动”。我最常用的验证流程是加状态页检查。编译时如果带了--with-http_stub_status_module,在server块里配一个内部location:
location /status { stub_status on; access_log off; allow 127.0.0.1; deny all; }然后执行curl http://127.0.0.1/status,能看到Active connections、Reading、Writing、Waiting四组计数,说明worker进程和状态模块都正常工作。这个页面在排查nginx mirror超时时间、反向代理后端负载时特别有用,开销也可以忽略。
第二个进阶验证是SSL模块。自己编译最大的价值就是能指定OpenSSL版本,不受官方Windows包滞后限制。验证方式:
openssl s_client -connect 127.0.0.1:443 -servername localhost 2>/dev/null | grep "Protocol"如果做多站点开发,可以按本地加虚拟机的多端口Nginx套路,不同listen端口配不同server_name,Nginx按SNI选择证书。这套东西只有自己编出来的带SSL模块的nginx才能完整验证,官方exe和docker镜像都不如自己构建灵活。
第三个技巧是把编译参数固化成一个build.sh。我的习惯是把configure参数写进脚本,连同依赖版本说明一起放进源码目录。换机器时重拉工具包、跑一遍脚本,十分钟得到完全一致的二进制,不用回忆当初到底用了哪些参数。
最后说一个个人习惯:现在我拿到这类“必要工具.rar”,不会着急解压,先看三样东西——依赖源码版本和Nginx版本匹配不匹配、有没有perl和nasm、是MinGW还是MSVC工具链。这三样对了再动手,能少翻一半车。Windows编译Nginx这件事,工具是死的,版本匹配和路径干净是活的,把这两点管住,编译本身真花不了多少时间。希望帮到你。
本文还有配套的精品资源,点击获取