This year I plan to study the nginx source code seriously. The purpose is to learn network programming. The source code I use is the first version nginx-0.1.0-RELEASE that is publicly released. The code address is: http://hg.nginx.org/nginx /rev/551102312e19
Just click zip or gz on the left in the browser to download. After decompression, there are 4 folders in the source code directory:
Copy the configure file in the auto directory to the source code directory and run .configure
The Makefile can be generated, and the output of the configure command looks like this on my ubuntu:
Configuration summary
+ PCRE library is not found
+ md5 library is not used
+ OpenSSL library is not used
+ using system zlib library./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using –without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using –with-pcre= option.`
The PCRE library was not found, so the HTTP rewrite module could not be installed correctly.
Execute command: sudo apt-get install libpcre3 libpcre3-dev
Then execute make clean, configure; display results:
Configuration summary
+ using system PCRE library
+ md5 library is not used
+ OpenSSL library is not used
+ using system zlib librarynginx path prefix: /usr/local/nginx
nginx binary file: /usr/local/nginx/sbin/nginx
nginx configuration file: /usr/local/nginx/conf/nginx.conf
nginx pid file: /usr/local/nginx/logs/nginx.pid
nginx error log file: /usr/local/nginx/logs/error.log
nginx http access log file: /usr/local/nginx/logs/access.log
md5 and openssl are not used, we will talk about this later. Then make, an error will appear, open the objs/Makefie file and view the current compilation options: CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused -Werror -g
Among them
-Werror Treat warnings as errors. Abort compilation if any warning occurs.
-Wpointer-arith Warn when performing arithmetic operations on function pointers or pointers of type void *. Also very useful. -Wall does not turn this on.
-pipe Use pipes instead of temporary files.
-Wno-unused Warn about unused variables
Remove all the following options and make again. There will also be an error: the display macro ngx_blocking_n is not declared in the file ngx_event_accept.c. Check objs/Makefile and find that this compilation error comes from the command: gcc -c -I src/core -I src/event -I src/event/modules - I src/os/unix -I objs src/event/ngx_event_accept.c -o ngx_event_accept.o
Finally, check the file src/os/unix/ngx_socket.h. The definition is as follows:
<code><span>#if (HAVE_FIONBIO)</span><span>int</span> ngx_nonblocking(ngx_socket_t s); <span>int</span> ngx_blocking(ngx_socket_t s); <span>#define ngx_nonblocking_n "ioctl(FIONBIO)"</span><span>#define ngx_blocking_n "ioctl(!FIONBIO)"</span><span>#else</span><span>#define ngx_nonblocking(s) fcntl(s, F_SETFL, O_NONBLOCK)</span><span>#define ngx_nonblocking_n "fcntl(O_NONBLOCK)"</span><span>#define ngx_blocking_n "ioctl(!FIONBIO)"</span><span>#endif</span></code>
does not include the second to last line of code, which I added newly. The test found that the if branch above is the else code under ubuntu. block, but the macro ngx_blocking_n is not defined in else, so just add it.
Continue making.
Found that IOV_MAX cannot be found in ngx_writev_chain.c, use the command grep IOV_MAX -r src/os/unix/*
I found that this macro is only defined under the freebsd system and is added directly to core/ngx_config.h.
Continue making.
It was found that there are no members msg_accrights and msg_accrightslen in struct msghdr. These are variable names that are only available in two lower versions of the operating system. Higher versions also have them but the names have changed. Check the code in the file src/os/unix/ngx_channel.c as follows:
<code><span>#if (HAVE_MSGHDR_MSG_CONTROL)</span> msg.msg_control = (caddr_t) &cmsg; msg.msg_controllen = <span>sizeof</span>(cmsg); <span>#else</span> msg.msg_accrights = (caddr_t) &fd; msg.msg_accrightslen = <span>sizeof</span>(<span>int</span>); <span>#endif</span></code>
The version issue has been considered here, and a macro has been defined to distinguish it. It must be that this macro is not defined, and the condition reaches the else branch, so an error is reported. Define the macro directly in the file:
<code><span>#define HAVE_MSGHDR_MSG_CONTROL 1</span></code>
Continue making.
This time all the target files have been generated, but an error occurred during linking. The reason is that some symbols cannot be found. The error content is as follows:
objs/src/core/ngx_times.o: In the function ‘ngx_time_update’:
/home/nginx-0.1.1/src/core/ngx_times.c:179: undefined reference to ‘ngx_timezone’
objs/src/event/ngx_event_accept.o: In function ‘ngx_event_accept’:
/home/nginx-0.1.1/src/event/ngx_event_accept.c:165: undefined reference to ‘ngx_blocking’
objs/src/event/ngx_event_connect.o: In function ‘ngx_event_connect_peer’:
/home/nginx-0.1.1/src/event/ngx_event_connect.c:301: undefined reference to ‘ngx_blocking’
objs/src/event/modules/ngx_rtsig_module.o: In function ‘ngx_rtsig_done’:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:173: undefined reference to ‘ngx_poll_module_ctx’
objs/src/event/modules/ngx_rtsig_module.o: In function ‘ngx_rtsig_init’:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:134: undefined reference to ‘ngx_poll_module_ctx’
collect2: error: ld returned 1 exit status
一次全部解决
1 在src/core/ngx_times.c文件里代码又走到了else分支里,然后在 src/os/unix/ngx_time.h中只有solaris才定义了ngx_timezone这个函数:
<code><span>#<span>define</span> ngx_timezone(isdst) (- (isdst ? altzone : timezone) / 60)</span></code>
放开宏定义会发现找不到altzone, 暂时不管这个,把它直接改成0:
<code><span>#<span>define</span> ngx_timezone(isdst) (- (isdst ? 0 : timezone) / 60)</span></code>
2 src/event/ngx_event_accept.c中未定义引用ngx_blocking,原因刚才已经找到了,在src/os/unix/ngx_socket.h中走了else分支,把if里的函数声明直接拷贝一份到else中,因为这是个函数,还有定义部分,在src/os/unix/ngx_socket.c中把这个函数从if宏定义中移出来。 注意,不要修改ngx_nonblocking函数。
3 src/event/modules/ngx_rtsig_module.c中未定义引用ngx_poll_module_ctx,查代码发现这是一个全局变量:
<code><span>extern</span> ngx_event_module_t ngx_poll_module_ctx;</code>
被定义在poll模块内,但编译的时候在objs/Makefile中没有编译这个模块,把它一起编译了,改3个地方,和epoll的编译一样,有epoll的地方直接复制epoll相关的内容,把里面的epoll改成poll就可以了。
最后make成功!
生成了nginx二进制文件。直接./nginx运行,报错:
[emerg] 11732#0: open() /usr/local/nginx/conf/nginx.conf failed (2: No such file or directory)
to be continued…
以上就介绍了nginx 源码(1)编译,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。