ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Windows编译Nginx全指南:工具链、依赖配置与避坑实战

Windows编译Nginx全指南:工具链、依赖配置与避坑实战 简介在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导致命令找不到PerlOpenSSL构建期脚本依赖缺perl时make中途退出NASMOpenSSL汇编优化缺nasm时OpenSSL编译报错PCRE2rewrite正则与location匹配目录名写错直接configure失败zlibgzip压缩模块版本目录和configure参数不一致OpenSSLSSL/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阶段如果探测不到PCRE2Nginx会跳过rewrite相关功能编译出来的二进制没有URL重写能力。zlib负责gzip压缩gzip和gzip_static模块靠它不配的话响应压缩功能直接没有。OpenSSL负责HTTPShttp_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解压。为什么用tarWindows 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 21 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 产物检查确认编出来的是完整Nginxmake 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-optno-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服务默认监听80Windows的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 urlhttp://: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块里配一个内部locationlocation /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_nameNginx按SNI选择证书。这套东西只有自己编出来的带SSL模块的nginx才能完整验证官方exe和docker镜像都不如自己构建灵活。第三个技巧是把编译参数固化成一个build.sh。我的习惯是把configure参数写进脚本连同依赖版本说明一起放进源码目录。换机器时重拉工具包、跑一遍脚本十分钟得到完全一致的二进制不用回忆当初到底用了哪些参数。最后说一个个人习惯现在我拿到这类“必要工具.rar”不会着急解压先看三样东西——依赖源码版本和Nginx版本匹配不匹配、有没有perl和nasm、是MinGW还是MSVC工具链。这三样对了再动手能少翻一半车。Windows编译Nginx这件事工具是死的版本匹配和路径干净是活的把这两点管住编译本身真花不了多少时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表