MinGW下编译nginx源码
为了研究nginx源码,笔者想编译调试一下nginx源码,由于nginx是使用configure脚本方式生成Makefile来编译的,MinGW中理论上也是可以的,但是直接在MinGW中编译nginx源码会出现找不到PCRE库以及zlib库的问题:
在Linux下如果安装了这两个库,在运行auto/configure
时,是完全没问题的,能够正确找到这两个库:
笔者经过研究,发现在查找PCRE
库以及zlib
库的脚本中都只对非win32
平台进行了检测,win32
平台没做检测。可以参见目前最新稳定版本nginx 1.26的源码,
PCRE配置以及
zlib配置。
只需要把条件判定去掉即可。
1. PCRE配置
2. zlib配置
3. OpenSSL配置
3. libxslt配置
75行处添加:
1if [ $ngx_found = no ]; then
2
3 # MinGW64
4
5 ngx_feature="libxslt in /mingw64"
6 ngx_feature_path="/mingw64/include/libxml2"
7 ngx_feature_libs="-L/opt/local/lib -lxml2 -lxslt"
8
9 . auto/feature
10fi
168行处添加:
1if [ $ngx_found = no ]; then
2
3 # MinGW64
4
5 ngx_feature="libexslt in /mingw64"
6 ngx_feature_path="/mingw64/include/libxml2"
7 ngx_feature_libs="-lexslt"
8
9 . auto/feature
10fi
再运行:
1 auto/configure --prefix= --with-cc=clang
如果要启用https
,需要添加参数:--with-http_ssl_module
,如果要调试添加参数:--with-debug
。
生成好Makefile
之后,就可以编译了:
1make -j8
可以使用VSCode进行调试,以下是笔者的launch.json
:
1{
2 // 使用 IntelliSense 了解相关属性。
3 // 悬停以查看现有属性的描述。
4 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 "version": "0.2.0",
6 "configurations": [
7 {
8 "type": "lldb",
9 "request": "launch",
10 "name": "(lldb) 启动",
11 "program": "${workspaceFolder}/objs/nginx.exe",
12 "args": [],
13 "cwd": "${workspaceFolder}",
14 "env": {
15 "PATH": "G:\\msys64\\mingw64\\bin"
16 }
17 },
18 {
19 "name": "(gdb) 启动",
20 "type": "cppdbg",
21 "request": "launch",
22 "program": "${workspaceFolder}/objs/nginx.exe",
23 "args": [],
24 "stopAtEntry": false,
25 "cwd": "${workspaceFolder}",
26 "environment": [],
27 "externalConsole": false,
28 "MIMode": "gdb",
29 "miDebuggerPath": "G:\\msys64\\mingw64\\bin\\gdb.exe",
30 "setupCommands": [
31 {
32 "description": "为 gdb 启用整齐打印",
33 "text": "-enable-pretty-printing",
34 "ignoreFailures": true
35 },
36 {
37 "description": "将反汇编风格设置为 Intel",
38 "text": "-gdb-set disassembly-flavor intel",
39 "ignoreFailures": true
40 }
41 ],
42 "windows": {
43 "environment": [
44 {
45 "name": "PATH",
46 "value": "G:\\msys64\\mingw64\\bin"
47 }
48 ]
49 }
50 }
51 ]
52}
需要注意的是,由于nginx
默认是使用的多进程模式,如果直接调试,将无法调试工作进程的情况,为此需要在调试时改为单进程的运行方式,修改
nginx.c:1143为:
1ngx_conf_init_value(ccf->daemon, 0)
2ngx_conf_init_value(ccf->master, 0);
重新编译后,即可使用GDB或者LLDB调试了:
目前虽然可以调试了,但是看代码,是没有intellisense的,也就不能正常代码跳转。所以最好是改为能够使用CMake
构建系统,这样就可以使用clangd
分析代码,进行代码跳转了。笔者根据源码中的脚本,写了一份可以在MinGW
以及ubuntu 22.04
中使用的CMakeLists.txt
。
CMakeLists.txt
:
1
2cmake_minimum_required(VERSION 3.20)
3
4project(nginx)
5
6set(ShareModules
7 --with-http_ssl_module
8 --with-http_v2_module
9 --with-http_realip_module
10 --with-http_addition_module
11 --with-http_xslt_module
12 --with-http_geoip_module
13 --with-http_dav_module
14 --with-http_stub_status_module
15 --with-http_image_filter_module
16 --with-mail
17 --with-mail_ssl_module
18 --with-stream
19 --with-stream_ssl_module
20)
21
22if(MINGW)
23execute_process(COMMAND sh auto/configure
24 --prefix=
25 --with-cc=clang
26 --with-debug
27 ${ShareModules}
28 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
29)
30else()
31execute_process(COMMAND auto/configure
32 --with-cc=clang
33 --with-debug
34 ${ShareModules}
35
36 --with-http_degradation_module
37 --with-threads
38 --with-file-aio
39 --with-http_v3_module
40 --with-google_perftools_module
41 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
42)
43endif()
44
45if(WIN32)
46if(MSVC)
47message(FATAL_ERROR "WIN32下不支持使用MSVC编译,仅支持MinGW或者Cygwin环境下使用gcc或者clang编译器编译")
48endif()
49endif()
50
51if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/objs/ngx_auto_config.h)
52message(STATUS "不存在ngx_auto_config.h,需要先执行`auto/configure`脚本")
53endif()
54
55if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/objs/ngx_auto_headers.h)
56message(STATUS "ngx_auto_headers.h,需要先执行`auto/configure`脚本")
57endif()
58
59if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/objs/ngx_modules.c)
60message(STATUS "不存在ngx_modules.c,需要先执行`auto/configure`脚本")
61endif()
62
63aux_source_directory(src/core SRC_LIST)
64aux_source_directory(src/event SRC_LIST)
65
66aux_source_directory(src/http SRC_LIST)
67aux_source_directory(src/http/v2 SRC_LIST)
68aux_source_directory(src/http/modules SRC_LIST)
69
70aux_source_directory(src/mail SRC_LIST)
71aux_source_directory(src/misc SRC_LIST)
72aux_source_directory(src/stream SRC_LIST)
73
74if(WIN32)
75aux_source_directory(src/os/win32 SRC_LIST)
76else()
77aux_source_directory(src/os/unix SRC_LIST)
78endif()
79
80list(APPEND SRC_LIST objs/ngx_modules.c)
81
82if(WIN32)
83list(APPEND SRC_LIST src/event/modules/ngx_win32_poll_module.c)
84list(APPEND SRC_LIST src/event/modules/ngx_iocp_module.c)
85list(APPEND SRC_LIST src/event/modules/ngx_win32_select_module.c)
86
87list(REMOVE_ITEM SRC_LIST src/core/ngx_bpf.c)
88
89# 不支持Windows
90list(REMOVE_ITEM SRC_LIST src/core/ngx_thread_pool.c)
91# 代码有错误
92list(REMOVE_ITEM SRC_LIST src/os/win32/ngx_service.c)
93# 代码有错误
94list(REMOVE_ITEM SRC_LIST src/event/ngx_event_connectex.c)
95
96#MinGW没sbrk函数
97list(REMOVE_ITEM SRC_LIST src/http/modules/ngx_http_degradation_module.c)
98
99elseif(LINUX)
100aux_source_directory(src/http/v3 SRC_LIST)
101aux_source_directory(src/event/quic SRC_LIST)
102list(APPEND SRC_LIST src/event/modules/ngx_epoll_module.c)
103
104list(REMOVE_ITEM SRC_LIST src/event/ngx_event_connectex.c)
105list(REMOVE_ITEM SRC_LIST src/event/ngx_event_acceptex.c)
106
107list(REMOVE_ITEM SRC_LIST src/os/unix/ngx_darwin_init.c)
108list(REMOVE_ITEM SRC_LIST src/os/unix/ngx_darwin_sendfile_chain.c)
109list(REMOVE_ITEM SRC_LIST src/os/unix/ngx_freebsd_init.c)
110list(REMOVE_ITEM SRC_LIST src/os/unix/ngx_freebsd_sendfile_chain.c)
111list(REMOVE_ITEM SRC_LIST src/os/unix/ngx_solaris_init.c)
112list(REMOVE_ITEM SRC_LIST src/os/unix/ngx_solaris_sendfilev_chain.c)
113list(REMOVE_ITEM SRC_LIST src/os/unix/ngx_file_aio_read.c)
114endif()
115
116add_executable(${PROJECT_NAME} ${SRC_LIST})
117
118include_directories(
119 src/core
120 src/event
121 src/event/modules
122 src/http
123 src/http/modules
124 src/http/v2
125 src/http/v3
126 src/event/quic
127 src/mail
128 src/stream
129 objs
130)
131
132if(WIN32)
133include_directories(src/os/win32)
134else()
135include_directories(src/os/unix)
136endif()
137
138find_package(LibXml2 REQUIRED)
139find_package(LibXslt REQUIRED)
140
141target_include_directories(${PROJECT_NAME} PUBLIC ${LIBXML2_INCLUDE_DIRS} ${LIBXSLT_INCLUDE_DIRS})
142if(WIN32)
143target_link_libraries(${PROJECT_NAME} PUBLIC advapi32 ws2_32)
144else()
145target_link_libraries(${PROJECT_NAME} PUBLIC crypt profiler)
146endif()
147target_link_libraries(${PROJECT_NAME} PUBLIC pcre crypto z pcre2-8 ssl gd GeoIP ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES})
MinGW
需要安装的一些库(不一定全,需要自行安装一些库):
1pacman -S mingw-w64-x86_64-geoip mingw-w64-x86_64-libgd
ubuntu
也需要安装的一些库(不一定全,需要自行安装一些库):
1sudo apt install libxslt1-dev libxml2-dev libgeoip-dev libgd-dev libgoogle-perftools-dev
当然,也可以使用辅助工具bear
或者compiledb
来生成compile_commands.json
:
bear
ubuntu
下使用sudo apt install bear
安装bear
工具。
在bear
3.0之前使用
1bear make
在3.0之后使用
1bear --make
就可以生成compile_commands.json
compiledb
compiledb
是一个使用python
开发的工具,所以需要使用
1pip install compiledb
来安装。 直接使用:
1compiledb make
就可以生成compile_commands.json
bear
目前在MinGW中还没有安装包,貌似也暂时不支持MinGW,所以需要在Linux下使用。而compiledb
是只要有python环境即可。
如果对你有帮助,欢迎点赞收藏!
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2025/2025-03-17-MinGW下编译nginx源码/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。