MinGW下编译nginx源码
为了研究nginx源码,笔者想编译调试一下nginx源码,由于nginx是使用configure脚本方式生成Makefile来编译的,MinGW中理论上也是可以的,但是直接在MinGW中编译nginx源码会出现找不到PCRE库以及zlib库的问题:
实际上MinGW中是有安装这两个库的:
在Linux下如果安装了这两个库,在运行auto/configure
时,是完全没问题的,能够正确找到这两个库:
笔者经过研究,发现在查找PCRE
库以及zlib
库的脚本中都只对非win32
平台进行了检测,win32
平台没做检测。可以参见目前最新稳定版本nginx 1.26的源码,PCRE配置以及zlib配置。
只需要把条件判定去掉即可:
再运行:
auto/configure --prefix= --with-cc=clang
如果要启用https
,需要添加参数:--with-http_ssl_module
,在MinGW中编译同样需要注释掉判断条件
如果要调试添加参数:--with-debug
。
生成好Makefile
之后,就可以编译了:
make -j8
可以使用VSCode进行调试,以下是笔者的launch.json
:
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "(lldb) 启动",
"program": "${workspaceFolder}/objs/nginx.exe",
"args": [],
"cwd": "${workspaceFolder}",
"env": {
"PATH": "G:\\msys64\\mingw64\\bin"
}
},
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/objs/nginx.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "G:\\msys64\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为 Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"windows": {
"environment": [
{
"name": "PATH",
"value": "G:\\msys64\\mingw64\\bin"
}
]
}
}
]
}
需要注意的是,由于nginx
默认是使用的多进程模式,如果直接调试,将无法调试工作进程的情况,为此需要在调试时改为单进程的运行方式,修改nginx.c:1143为:
ngx_conf_init_value(ccf->daemon, 0)
ngx_conf_init_value(ccf->master, 0);
重新编译后,即可使用GDB或者LLDB调试了:
目前虽然可以调试了,但是看代码,是没有intellisense的,也就不能正常代码跳转。所以最好是改为能够使用CMake
构建系统,这样就可以使用clangd
分析代码,进行代码跳转了。笔者根据源码中的脚本,写了一份可以在MinGW
中使用的CMakeLists.txt
,不过还是需要先在MinGW
中执行auto/configure
脚本。
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.20)
project(nginx)
if(WIN32)
if(MSVC)
message(FATAL_ERROR "WIN32下不支持使用MSVC编译,仅支持MinGW或者Cygwin环境下使用gcc或者clang编译器编译")
endif()
endif()
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/objs/ngx_auto_config.h)
message(STATUS "不存在ngx_auto_config.h,需要先执行`auto/configure`脚本")
endif()
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/objs/ngx_auto_headers.h)
message(STATUS "ngx_auto_headers.h,需要先执行`auto/configure`脚本")
endif()
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/objs/ngx_modules.c)
message(STATUS "不存在ngx_modules.c,需要先执行`auto/configure`脚本")
endif()
aux_source_directory(src/core SRC_LIST)
aux_source_directory(src/event SRC_LIST)
if(WIN32)
aux_source_directory(src/os/win32 SRC_LIST)
else()
aux_source_directory(src/os/unix SRC_LIST)
endif()
aux_source_directory(src/http SRC_LIST)
aux_source_directory(src/http/modules SRC_LIST)
list(REMOVE_ITEM SRC_LIST src/core/ngx_bpf.c)
list(APPEND SRC_LIST objs/ngx_modules.c)
if(WIN32)
list(APPEND SRC_LIST src/event/modules/ngx_win32_poll_module.c)
list(APPEND SRC_LIST src/event/modules/ngx_iocp_module.c)
list(APPEND SRC_LIST src/event/modules/ngx_win32_select_module.c)
list(REMOVE_ITEM SRC_LIST src/core/ngx_thread_pool.c)
list(REMOVE_ITEM SRC_LIST src/os/win32/ngx_service.c)
list(REMOVE_ITEM SRC_LIST src/event/ngx_event_connectex.c)
list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_degradation_module.c)
list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_dav_module.c)
list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_realip_module.c)
list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_geoip_module.c)
list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_xslt_filter_module.c)
list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_stub_status_module.c)
list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_grpc_module.c)
endif()
add_executable(${PROJECT_NAME} ${SRC_LIST})
include_directories(src/core
src/event
src/event/modules
src/http
src/http/modules
src/mail
objs
)
if(WIN32)
include_directories(src/os/win32)
else()
include_directories(src/os/unix)
endif()
target_link_libraries(${PROJECT_NAME} PUBLIC advapi32 pcre crypto libz ws2_32 pcre2-8 ssl gd)
如果对你有帮助,欢迎点赞收藏!