nginx 源碼(1)編譯

來源:互聯網
上載者:User
今年準備認真一下nginx源碼,目的是學習網路編程,我用的源碼公開發布的第一個版本 nginx-0.1.0-RELEASE,代碼地址:
http://hg.nginx.org/nginx/rev/551102312e19
在瀏覽器裡直接點左邊的zip或gz就可以下載了。解壓後源碼目錄下有4個檔案夾:

  • auto
  • conf
  • docs
  • src

把auto目錄下的configure檔案拷貝到源碼目錄,運行
.configure
就可以產生Makefile,同時configure命令的輸出,在我的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.`

未找到PCRE庫,因此無法正確安裝HTTP rewrite模組。
執行命令:
sudo apt-get install libpcre3 libpcre3-dev
後再執行make clean,configure;顯示結果:

Configuration summary
+ using system PCRE library
+ md5 library is not used
+ OpenSSL library is not used
+ using system zlib library

nginx 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和openssl未使用,這個以後再說。然後make,會出現錯誤,開啟objs/Makefie檔案,查看當前的編譯選項:
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused -Werror -g
其中
-Werror 把警告當作錯誤。出現任何警告就放棄編譯。
-Wpointer-arith 對函數指標或者void *類型的指標進行算術操作時給出警告。也很有用。 -Wall 並不會開啟此項。
-pipe 使用管道代替臨時檔案。
-Wno-unused 未使用的變數給出警告
把後面幾個選項都去掉,重新make。還會出錯:顯示宏ngx_blocking_n在檔案ngx_event_accept.c中未聲明,查看objs/Makefile發現這個編譯錯誤來自命令:
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
最終查看檔案src/os/unix/ngx_socket.h,其中的定義如下:

#if (HAVE_FIONBIO)int ngx_nonblocking(ngx_socket_t s);int ngx_blocking(ngx_socket_t s);#define ngx_nonblocking_n   "ioctl(FIONBIO)"#define ngx_blocking_n      "ioctl(!FIONBIO)"#else#define ngx_nonblocking(s)  fcntl(s, F_SETFL, O_NONBLOCK)#define ngx_nonblocking_n   "fcntl(O_NONBLOCK)"#define ngx_blocking_n      "ioctl(!FIONBIO)"#endif

不含倒數第2行代碼,那是我新加的,測試發現上面的if分支在ubuntu下是走的else代碼塊,但else中沒有定義宏ngx_blocking_n,所以加上就好了。

繼續make。
發現在ngx_writev_chain.c中找不到IOV_MAX, 使用命令
grep IOV_MAX -r src/os/unix/*
發現這個宏只在freebsd系統下才有定義,直接加到core/ngx_config.h中。

繼續make。
發現struct msghdr中沒有成員msg_accrights和msg_accrightslen,這是兩個低版本的作業系統才有的變數名,高版本也有但是名字變了,查看檔案src/os/unix/ngx_channel.c中代碼如下:

#if (HAVE_MSGHDR_MSG_CONTROL)    msg.msg_control = (caddr_t) &cmsg;    msg.msg_controllen = sizeof(cmsg);#else    msg.msg_accrights = (caddr_t) &fd;    msg.msg_accrightslen = sizeof(int);#endif

此處已經考慮了版本問題,定義了一個宏來區分,肯定是這個宏未定義,條件走到了else分支所以報錯,直接在檔案內定義宏:

#define HAVE_MSGHDR_MSG_CONTROL 1

繼續make。
這次所有的目標檔案已經產生,但連結的時候出錯了,原因還是一些符號找不到,出錯內容如下:

objs/src/core/ngx_times.o:在函數‘ngx_time_update’中:
/home/nginx-0.1.1/src/core/ngx_times.c:179:對‘ngx_timezone’未定義的引用
objs/src/event/ngx_event_accept.o:在函數‘ngx_event_accept’中:
/home/nginx-0.1.1/src/event/ngx_event_accept.c:165:對‘ngx_blocking’未定義的引用
objs/src/event/ngx_event_connect.o:在函數‘ngx_event_connect_peer’中:
/home/nginx-0.1.1/src/event/ngx_event_connect.c:301:對‘ngx_blocking’未定義的引用
objs/src/event/modules/ngx_rtsig_module.o:在函數‘ngx_rtsig_done’中:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:173:對‘ngx_poll_module_ctx’未定義的引用
objs/src/event/modules/ngx_rtsig_module.o:在函數‘ngx_rtsig_init’中:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:134:對‘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這個函數:

#define ngx_timezone(isdst) (- (isdst ? altzone : timezone) / 60)

放開宏定義會發現找不到altzone, 暫時不管這個,把它直接改成0:

#define ngx_timezone(isdst) (- (isdst ? 0 : timezone) / 60)

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,查代碼發現這是一個全域變數:

extern ngx_event_module_t  ngx_poll_module_ctx;

被定義在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教程有興趣的朋友有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.