最近想学习下nginx的源码,之前在linux环境编译安装过多次,在windows环境还是第一次尝试,遇到了不少问题,记录一下。可惜的是编译成功后,在最后运行的时候还是会报错,如果有人遇到类似的问题希望能帮忙解答下
环境安装
Nginx是使用C++编写的,所以我们首先需要的就是一个C++编译器,我选择通过MinGW安装gcc,然后进行编译,IDE选择的VS code。
1. gcc安装
首先安装MinGW,从https://sourceforge.net/projects/mingw/files/Installer/下载mingw-get-setup.exe 并安装,具体的安装过程可以参考博客MinGW安装教程,作者写的非常详尽了,我是之前自己安装过,就没有重新安装了
完成MinGW的安装后,就可以下载、安装、管理 MinGW 和相关的组件了。
我需要安装的有如下三个红色框内的组件msys-base,mingw32-base,mingw32-gcc-g++
(安装完全后组件的选择框就会变为绿色)
mingw32-base:必选,mingw的基础包,核心的c编译器
msys-base:MSYS 开发环境所需的包,在后续执行configure时需要使用
mingw32-gcc-g++:C++的编译器
选中后应用更改,并安装即可,如下图
2. perl,pcre,zlib,openssl 下载安装
安装 perl, Perl From ActiveState 下载,然后按照正常步骤安装即可(我选择的是5.26版本)
pcre: 下载地址 https://ftp.pcre.org/pub/pcre/ ,我选择的版本是pcre-8.36
zlib: 下载地址 http://zlib.net/zlib-1.2.11.tar.gz
openssl: 下载地址: https://www.openssl.org/source/old/1.0.1/,我选择的版本是openssl-1.0.1e
openssl,zlib,pcre下载的都是以tar.gz为后缀的压缩包
编译openssl
加压缩后,使用msys进入到openssl目录下,执行如下命令:
./config -t
./config threads shared no-capieng
make depend
make
会生成 libcrypto.a libssl.a libssl.dll.a libcrypto.dll.a 这四个文件和相应的dll文件,如果不事先编译openssl的话会在编译Nginx的时候提示如下错误:(下载的openssl里没有下述两个文件,需要先编译生成对应文件)。将上述生成的四个文件复制到openssl的lib目录下(没有则自行创建)
下载nginx 并编译
下载源码必须通过http://hg.nginx.org/nginx 进行下载,不可使用发布的源码包,否则无法支持windows下编译。可以选择在网页下载或通过hg下载。
在nginx下创建objs/lib目录,并将解压(编译)后的openssl,zlib,pcre文件夹拷贝到lib目录下,使用如下命令进行编译
./auto/configure --with-cc=gcc --builddir=objs --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=objs/lib/pcre-8.36 \
--with-zlib=objs/lib/zlib-1.2.11 --with-openssl=objs/lib/openssl-1.0.1e \
--with-select_module --with-http_ssl_module
使用gcc作为编译器,而不是vs的cl,因为我没有安装,使用cl的话在编译的报错日志里会有找不到command的错误信息
编译成功如下:
编译过程中遇到的问题:
1. make[1]: *** [objs/lib/openssl-1.0.1u/.openssl/include/openssl/ssl.h] Error 1
解决办法:
进入nginx根目录下的auto/lib/openssl 目录,
编辑 conf 文件。将下述内容:
CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
修改为:
CORE_INCS="$CORE_INCS $OPENSSL/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libcrypto.a"
保存文件后,需先执行 make clean 清除编译配置,然后重新创建objs/lib目录并拷贝依赖文件,然后重新编译
2.conflicting types for 'socklen_t’
头文件函数声明和函数定义参数不同, 一个是unsigned int,一个是int,
我将mingw里的ws2tcpip.h里的unsigned int socklen_t改成了int socklen ,就没有再报上述错误了
3.make[1]: *** No rule to make target objs/lib/openssl-1.0.1u/include/openssl/ssl.h', needed by
objs/src/core/nginx.o’. Stop.
这类错误基本都是属于找不到所依赖的文件所导致的,所以应该去:对应目录下确认所依赖的文件是否真实存在。
我原先使用的openssl-1.0.1u解压缩后确实没有对应的ssl.h文件,替换成openssl-1.0.1e就可以了
4. libssl.a : No such file or directory
编译下openssl,步骤在前面已经说明过了
编译成功后我使用Visual Studio Code打开对应的nginx目录,但是nginx.c文件会有如下编译错误:
无法成功运行
。。。。。。。。。。。。。
参考资料:
https://blog.csdn.net/weixin_39970103/article/details/102616904
https://blog.csdn.net/wxh0000mm/article/details/100666329