准备
基本与windows下编译nginx需要的一致。
-
git。
用于通过github下载源码。
-
Visual Studio 2015+。
我用的是Visual Studio 2019社区版。需要注意的是,安装的时候必须安装“使用C++的桌面开发”,不需要安装“通用Windows平台开发”,因为需要里面的
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat
修改编译环境,从而能够调用nmake。 -
perl。
可能只是openssl编译需要perl支持。
-
nginx源码。
github地址:
https://github.com/nginx/nginx.git
,最好切换到最新的稳定版本。我用的是branches/stable-1.16
分支
本地地址:D:\projects\github\nginx
-
nginx-module-vts源码。
github地址:
https://github.com/vozlt/nginx-module-vts.git
本地地址:D:\projects\github\nginx-module-vts
-
openssl源码。
github地址:
https://github.com/openssl/openssl
,不能使用最新版,根据其他教程经验,我用的是OpenSSL_1_0_1-stable
分支。
本地地址:D:\projects\github\openssl
-
pcre源码。
github上没有,需要从pcre网站下载。不能使用pcre2。pcre版本最新的即可。我下载的8.43版本。
解压后本地地址是:D:\projects\download\pcre-8.43
-
zlib源码。
github上没有,需要从zlib网站下载。下载最新的即可,我下载的是1.2.11版本。
解压后本地地址是:D:\projects\download\zlib-1.2.11
注意: 很多教程都要求下载MinGW,其实是为了用msys,用于生成windows下MakeFile。实际上,git的终端本身就是msys,所以不再需要MinGW。
编译
在git命令行中切换到nginx目录。创建编译后目录build
。执行以下命令,生成MakeFile。
auto/configure --with-cc=cl \
--builddir=build \
--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 \
--with-cc-opt=-DFD_SETSIZE=1024 \
--with-pcre=D:/projects/download/pcre-8.43 \
--with-zlib=D:/projects/download/zlib-1.2.11 \
--with-openssl=D:/projects/github/openssl \
--with-select_module --with-http_ssl_module \
--with-http_sub_module \
--add-module=D:/projects/github/nginx-module-vts
注意: 所有windows目录的反斜杠\
要改成斜杠/
,或者双反斜杠\\
。
打开x86 Native Tools Command Prompt for VS 2019
,切换到目录C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build
,执行vcvars32.bat
。执行一次即可,下次再打开时,会提示已经切换到32位环境[vcvarsall.bat] Environment initialized for: 'x86'
,就不需要执行了。
切换到nginx目录,执行nmake /f build/Makefile
。
完成后,会在build目录中生成nginx.exe。即使生成了nginx.exe,编译时也会报错。如果是以下类型的报错,基本上就已经生成了nginx.exe。
正在搜索库
正在搜索 C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86\kernel32.lib:
正在搜索 C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86\user32.lib:
正在搜索 C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86\advapi32.lib:
正在搜索 C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86\ws2_32.lib:
正在搜索 D:\projects\download\pcre-8.43\pcre.lib:
正在搜索 D:\projects\github\openssl\openssl\lib\ssleay32.lib:
正在搜索 D:\projects\github\openssl\openssl\lib\libeay32.lib:
正在搜索 C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86\gdi32.lib:
正在搜索 C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86\crypt32.lib:
正在搜索 D:\projects\download\zlib-1.2.11\zlib.lib:
正在搜索 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\lib\x86\LIBCMT.lib:
已完成库搜索
sed -e "s|%PREFIX%||" -e "s|%PID_PATH%|/logs/nginx.pid|" -e "s|%CONF_PATH%|/conf/nginx.conf|" -e "s|%ERROR_LOG_PATH%|/logs/error.log|" < docs/man/nginx.8 > build/nginx.8
'sed' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
NMAKE : fatal error U1077: “sed”: 返回代码“0x1”
Stop.
异常
- 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include “ngx_config.h”
cl -c -O2 -W4 -WX -nologo -MT -Zi -Fdbuild/nginx.pdb -DFD_SETSIZE=1024 -DNO_SYS_TYPES_H -Yungx_config.h -Fpbuild/ngx_config.pch -I src/core -I src/event -I src/event/modules -I src/os/win32 -I D:/projects/download/pcre-8.43 -I D:/projects/github/openssl/openssl/include -I D:/projects/download/zlib-1.2.11 -I build -I src/http -I src/http/modules -Fobuild/addon/src/ngx_http_vhost_traffic_status_module.obj D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_module.c
ngx_http_vhost_traffic_status_module.c
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_module.c(1105): fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "ngx_config.h"”?
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\HostX86\x86\cl.EXE"”: 返回代码“0x2”
Stop.
修改build/MakeFile,搜索对应源文件名,找到以下内容:
build/addon/src/ngx_http_vhost_traffic_status_module.obj: $(ADDON_DEPS) \
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_module.c
$(CC) -c $(CFLAGS) -Yungx_config.h -Fpbuild/ngx_config.pch $(ALL_INCS) \
-Fobuild/addon/src/ngx_http_vhost_traffic_status_module.obj \
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_module.c
将其中的-Yungx_config.h -Fpbuild/ngx_config.pch
删除掉。同时把其他类似ngx_http_vhost_traffic_stat*
的语句同样处理。
- “ngx_atomic_t”: 忽略强制转换中的顶级 volatile 变量
cl -c -O2 -W4 -WX -nologo -MT -Zi -Fdbuild/nginx.pdb -DFD_SETSIZE=1024 -DNO_SYS_TYPES_H -I src/core -I src/event -I src/event/modules -I src/os/win32 -I D:/projects/download/pcre-8.43 -I D:/projects/github/openssl/openssl/include -I D:/projects/download/zlib-1.2.11 -I build -I src/http -I src/http/modules -Fobuild/addon/src/ngx_http_vhost_traffic_status_limit.obj D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c
ngx_http_vhost_traffic_status_limit.c
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(126): error C2220: 警告被视为错误 - 没有生成“object”文件
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(126): warning C4197: “ngx_atomic_t”: 忽略强制转换中的顶级 volatile 变量
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(148): warning C4197: “ngx_atomic_t”: 忽略强制转换中的顶级 volatile 变量
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(239): warning C4197: “ngx_atomic_t”: 忽略强制转换中的顶级 volatile 变量
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(360): warning C4197: “ngx_atomic_t”: 忽略强制转换中的顶级 volatile 变量
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(366): error C2059: 语法错误:“{”
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(366): error C2065: “n”: 未声明的标识符
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(366): error C2059: 语法错误:“)”
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(368): error C2059: 语法错误:“if”
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(371): error C2059: 语法错误:“else”
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(375): error C2059: 语法错误:“return”
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_limit.c(376): error C2059: 语法错误:“}”
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\HostX86\x86\cl.EXE"”: 返回代码“0x2”
Stop.
这里涉及两个问题:
i. 126~360行:“ngx_atomic_t”: 忽略强制转换中的顶级 volatile 变量
。
因为ngx_http_vhost_traffic_status_node_member
方法定义返回的是ngx_atomic_uint_t
类型,被强转为ngx_atomic_t
,把变量类型改成ngx_atomic_uint_t
即可。
有一个地址需要改某个结构体中size的类型为ngx_atomic_uint_t
。
ii. 366~376行:语法错误:“{”
等
在ngx_http_vhost_traffic_status_module.h
文件中,ngx_http_vhost_traffic_status_string_to_group
是个宏,可能vc不支持宏内自定义参数吧,有知道的请不吝赐教!
#define ngx_http_vhost_traffic_status_string_to_group(s) (unsigned) ( \
{ \
unsigned n = NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_NO; \
if (*s == 'N' && *(s + 1) == 'O') { \
n = NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_NO; \
} else if (*s == 'U' && *(s + 1) == 'A') { \
n = NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_UA; \
} else if (*s == 'U' && *(s + 1) == 'G') { \
n = NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_UG; \
} else if (*s == 'C' && *(s + 1) == 'C') { \
n = NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_CC; \
} else if (*s == 'F' && *(s + 1) == 'G') { \
n = NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_FG; \
} \
n; \
} \
)
改成以下代码即可:
#define ngx_http_vhost_traffic_status_string_to_group(s) ( \
(*s == 'N' && *(s + 1) == 'O')?NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_NO: \
(*s == 'U' && *(s + 1) == 'A')?NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_UA: \
(*s == 'U' && *(s + 1) == 'G')?NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_UG: \
(*s == 'C' && *(s + 1) == 'C')?NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_CC: \
(*s == 'F' && *(s + 1) == 'G')?NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_FG: \
NGX_HTTP_VHOST_TRAFFIC_STATUS_UPSTREAM_NO \
)
- “ngx_lock_fd”未定义;假设外部返回 int
cl -c -O2 -W4 -WX -nologo -MT -Zi -Fdbuild/nginx.pdb -DFD_SETSIZE=1024 -DNO_SYS_TYPES_H -I src/core -I src/event -I src/event/modules -I src/os/win32 -I D:/projects/download/pcre-8.43 -I D:/projects/github/openssl/openssl/include -I D:/projects/download/zlib-1.2.11 -I build -I src/http -I src/http/modules -Fobuild/addon/src/ngx_http_vhost_traffic_status_dump.obj D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c
ngx_http_vhost_traffic_status_dump.c
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(28): error C2220: 警告被视为错误 - 没有生成“object”文件
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(28): warning C4013: “ngx_lock_fd”未定义;假设外部返回 int
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(35): error C2065: “ngx_lock_fd_n”: 未声明的标识符
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(35): warning C4047: “函数”:“const char *”与“int”的间接级别不同
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(35): warning C4024: “ngx_log_error”: 形参和实参 4 的类型不同
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(35): error C2143: 语法错误: 缺少“)”(在“字符串”的前面)
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(35): error C2059: 语法错误:“)”
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(42): warning C4013: “ngx_unlock_fd”未定义;假设外部返回 int
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(49): error C2065: “ngx_unlock_fd_n”: 未声明的标识符
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(49): warning C4047: “函数”:“const char *”与“int”的间接级别不同
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(49): warning C4024: “ngx_log_error”: 形参和实参 4 的类型不同
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(49): error C2143: 语法错误: 缺少“)”(在“字符串”的前面)
D:/projects/github/nginx-module-vts/src/ngx_http_vhost_traffic_status_dump.c(49): error C2059: 语法错误:“)”
NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\HostX86\x86\cl.EXE"”: 返回代码“0x2”
Stop.
在文件ngx_http_vhost_traffic_status_dump.c
中将ngx_http_vhost_traffic_status_file_lock
和ngx_http_vhost_traffic_status_file_unlock
方法中的代码全部注释。因为只有linux的nginx中有这个ngx_lock_fd
方法,win32中没有这个方法。
配置
修改conf/nginx.conf
文件,修改以下内容:
- http段增加
vhost_traffic_status_zone;
- http->server段增加
vhost_traffic_status_filter_by_set_key $uri uris::$server_name;
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
详细使用方法参见文档:https://github.com/vozlt/nginx-module-vts
使用
访问http://localhost/status