微信公衆號:Nginx源碼分析
關注可瞭解更多的Nginx
知識。任何問題或建議,請公衆號留言;
關注公衆號,有趣有內涵的文章第一時間送達!nginx
本文分析auto/lib
相關腳本的功能。
從腳本名稱咱們也可以知道,這部分是和第三方庫相關的。好比pcre
庫,openssl
, perl
等。
咱們首先看一下這個目錄中的各個腳本的做用。以下圖:
web
這個腳本就在configure
中被調用。負責auto/lib
下的全部第三方庫的配置工做。bash
1if [ $USE_PCRE = YES -o $PCRE != NONE ]; then
2 . auto/lib/pcre/conf
3
4else
5 if [ $USE_PCRE = DISABLED -a $HTTP = YES -a $HTTP_REWRITE = YES ]; then
6
7cat << END
8
9$0: error: the HTTP rewrite module requires the PCRE library.
10You can either disable the module by using --without-http_rewrite_module
11option or you have to enable the PCRE support.
12
13END
14 exit 1
15 fi
16fi
17
18
19if [ $USE_OPENSSL = YES ]; then
20 . auto/lib/openssl/conf
21fi
22
23if [ $USE_ZLIB = YES ]; then
24 . auto/lib/zlib/conf
25fi
26
27if [ $USE_LIBXSLT != NO ]; then
28 . auto/lib/libxslt/conf
29fi
30
31if [ $USE_LIBGD != NO ]; then
32 . auto/lib/libgd/conf
33fi
34
35if [ $USE_PERL != NO ]; then
36 . auto/lib/perl/conf
37fi
38
39if [ $USE_GEOIP != NO ]; then
40 . auto/lib/geoip/conf
41fi
42
43if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
44 . auto/lib/google-perftools/conf
45fi
46
47if [ $NGX_LIBATOMIC != NO ]; then
48 . auto/lib/libatomic/conf
49fi
複製代碼
咱們觀察一下這個腳本,會發現全部的功能處理方法都是相似的。先判斷是否使用了某個功能,若是使用了,就調用對應的auto/lib
腳本。微信
咱們以pcre
爲例分析auto/lib/conf
的做用。
在auto/lib/conf
的最上面就是對pcre
的處理。app
1if [ $USE_PCRE = YES -o $PCRE != NONE ]; then
2 . auto/lib/pcre/conf
3
4else
5 if [ $USE_PCRE = DISABLED -a $HTTP = YES -a $HTTP_REWRITE = YES ]; then
6
7cat << END
8
9$0: error: the HTTP rewrite module requires the PCRE library.
10You can either disable the module by using --without-http_rewrite_module
11option or you have to enable the PCRE support.
12
13END
14 exit 1
15 fi
16fi
複製代碼
這部分腳本首先會判斷USE_PCRE
和PCRE
的值,這兩個變量的值都是是在auto/option
中進行設置的。源碼分析
默認狀況下,這兩個變量的值以下:測試
1USE_PCRE=NO
2PCRE=NONE
複製代碼
經過執行configure
腳本時傳遞--with-pcre=*) PCRE="$value"
參數能夠設置這兩個變量的值。其中USE_PCRE
表示是否使用pcre
庫。PCRE
表示pcre
庫所在的目錄。ui
1--without-pcre) USE_PCRE=DISABLED ;;
2--with-pcre) USE_PCRE=YES ;;
3--with-pcre=*) PCRE="$value" ;;
複製代碼
若是咱們沒有設置pcre
,可是使用了http_rewrite
功能,那麼在執行./cofigure
腳本的時候就會報錯,以下:google
1./configure: error: the HTTP rewrite module requires the PCRE library.
2You can either disable the module by using --without-http_rewrite_module
3option or you have to enable the PCRE support.
複製代碼
這是咱們在編譯nginx
的時候常常遇到的錯誤,就是上面所說的緣由形成的。atom
注意:咱們在
./configure
的時候可能並無指定--with-pcre
,可是默認狀況下仍是會編譯pcre
的。由於默認狀況下HTTP_REWRITE = YES
,在執行auto/modules
腳本(後面分析)的時候,會根據HTTP_REWRITE
來設置USE_PCRE
的值。
下面咱們看一下auto/lib/pcre/conf
腳本主要乾了什麼工做。
先看一下腳本內容:
1if [ $PCRE != NONE ]; then
2 CORE_INCS="$CORE_INCS $PCRE"
3
4 case "$NGX_CC_NAME" in
5
6 msvc | owc | bcc)
7 have=NGX_PCRE . auto/have
8 have=PCRE_STATIC . auto/have
9 CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
10 LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
11 CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
12 ;;
13
14 icc)
15 have=NGX_PCRE . auto/have
16 CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
17
18 LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
19
20 echo $ngx_n "checking for PCRE library ...$ngx_c"
21
22 if [ -f $PCRE/pcre.h ]; then
23 ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
24 | sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
25
26 else if [ -f $PCRE/configure.in ]; then
27 ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
28 | sed -e 's/^.*=\(.*\)$/\1/'`
29
30 else
31 ngx_pcre_ver=`grep pcre_major, $PCRE/configure.ac \
32 | sed -e 's/^.*pcre_major,.*\[\(.*\)\].*$/\1/'`
33 fi
34 fi
35
36 echo " $ngx_pcre_ver major version found"
37
38 # to allow -ipo optimization we link with the *.o but not library
39
40 case "$ngx_pcre_ver" in
41 4|5)
42 CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
43 ;;
44
45 6)
46 CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
47 CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
48 CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
49 CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
50 CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
51 CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
52 CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
53 ;;
54
55 *)
56 CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
57 CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
58 CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
59 CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
60 CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
61 CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
62 CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
63 CORE_LIBS="$CORE_LIBS $PCRE/pcre_newline.o"
64 ;;
65
66 esac
67 ;;
68
69 *)
70 have=NGX_PCRE . auto/have
71
72 if [ "$NGX_PLATFORM" = win32 ]; then
73 have=PCRE_STATIC . auto/have
74 fi
75
76 CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
77 LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
78 CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
79 ;;
80
81 esac
82
83
84 if [ $PCRE_JIT = YES ]; then
85 have=NGX_HAVE_PCRE_JIT . auto/have
86 PCRE_CONF_OPT="$PCRE_CONF_OPT --enable-jit"
87 fi
88
89else
90
91 if [ "$NGX_PLATFORM" != win32 ]; then
92
93 PCRE=NO
94
95 ngx_feature="PCRE library"
96 ngx_feature_name="NGX_PCRE"
97 ngx_feature_run=no
98 ngx_feature_incs="#include <pcre.h>"
99 ngx_feature_path=
100 ngx_feature_libs="-lpcre"
101 ngx_feature_test="pcre *re;
102 re = pcre_compile(NULL, 0, NULL, 0, NULL);
103 if (re == NULL) return 1"
104 . auto/feature
105
106 if [ $ngx_found = no ]; then
107
108 # FreeBSD port
109
110 ngx_feature="PCRE library in /usr/local/"
111 ngx_feature_path="/usr/local/include"
112
113 if [ $NGX_RPATH = YES ]; then
114 ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lpcre"
115 else
116 ngx_feature_libs="-L/usr/local/lib -lpcre"
117 fi
118
119 . auto/feature
120 fi
121
122 if [ $ngx_found = no ]; then
123
124 # RedHat RPM, Solaris package
125
126 ngx_feature="PCRE library in /usr/include/pcre/"
127 ngx_feature_path="/usr/include/pcre"
128 ngx_feature_libs="-lpcre"
129
130 . auto/feature
131 fi
132
133 if [ $ngx_found = no ]; then
134
135 # NetBSD port
136
137 ngx_feature="PCRE library in /usr/pkg/"
138 ngx_feature_path="/usr/pkg/include"
139
140 if [ $NGX_RPATH = YES ]; then
141 ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
142 else
143 ngx_feature_libs="-L/usr/pkg/lib -lpcre"
144 fi
145
146 . auto/feature
147 fi
148
149 if [ $ngx_found = no ]; then
150
151 # MacPorts
152
153 ngx_feature="PCRE library in /opt/local/"
154 ngx_feature_path="/opt/local/include"
155
156 if [ $NGX_RPATH = YES ]; then
157 ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
158 else
159 ngx_feature_libs="-L/opt/local/lib -lpcre"
160 fi
161
162 . auto/feature
163 fi
164
165 if [ $ngx_found = yes ]; then
166 CORE_INCS="$CORE_INCS $ngx_feature_path"
167 CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
168 PCRE=YES
169 fi
170
171 if [ $PCRE = YES ]; then
172 ngx_feature="PCRE JIT support"
173 ngx_feature_name="NGX_HAVE_PCRE_JIT"
174 ngx_feature_test="int jit = 0;
175 pcre_free_study(NULL);
176 pcre_config(PCRE_CONFIG_JIT, &jit);
177 if (jit != 1) return 1;"
178 . auto/feature
179
180 if [ $ngx_found = yes ]; then
181 PCRE_JIT=YES
182 fi
183 fi
184 fi
185
186 if [ $PCRE != YES ]; then
187cat << END
188
189$0: error: the HTTP rewrite module requires the PCRE library.
190You can either disable the module by using --without-http_rewrite_module
191option, or install the PCRE library into the system, or build the PCRE library
192statically from the source with nginx by using --with-pcre=<path> option.
193
194END
195 exit 1
196 fi
197
198fi
複製代碼
從腳本的總體內容上來看,auto/lib/pcre/conf
是一個if-else
結構,分別處理PCRE
變量爲空和非空的狀況。
若是在configre
的時候經過--with-pcre
選項指定了pcre
的庫文件路徑,那麼執行if
部分,不然執行else
部分,兩者的處理邏輯基本相同。下面咱們詳細分析這兩種狀況。
1).
指定pcre
路徑
1if [ $PCRE != NONE ]; then
2 CORE_INCS="$CORE_INCS $PCRE"
3
4 case "$NGX_CC_NAME" in
5
6 *)
7 have=NGX_PCRE . auto/have
8
9 if [ "$NGX_PLATFORM" = win32 ]; then
10 have=PCRE_STATIC . auto/have
11 fi
12
13 CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
14 LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
15 CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
16 ;;
17
18 esac
19
20
21 if [ $PCRE_JIT = YES ]; then
22 have=NGX_HAVE_PCRE_JIT . auto/have
23 PCRE_CONF_OPT="$PCRE_CONF_OPT --enable-jit"
24 fi
25else # 沒有設置 PCRE 變量
複製代碼
這部分總體就是一個case
語句,根據NGX_CC_NAME
的值執行不一樣的處理邏輯。這個變量咱們在以前的分析auto/cc
的時候說過,它表示的是當前使用的編譯器。我使用的是gcc
,因此執行的是default
部分。因此我把那些執行不到的case
分支刪了,只保留了default
部分。
這部分代碼就是設置一些編譯時候要用到的變量,根據configre
時設置的pcre
源文件以及庫文件的路徑,設置到編譯選項中,等到最後生成Makefile
的時候使用。
注意:這裏並無判斷
pcre
是否存在,由於沒有必要,既然你在執行configure
的時候已經手動指定了pcre
的路徑,那麼nginx
就認爲它是存在的,若是不存在,那麼在最後編譯的時候會報錯。這點和下面咱們要分析的else
部分不一樣。
而後又經過PCRE_CONF_OPT
參數設置pcre
即時編譯相關功能,在編譯pcre
的時候會使用。
2).
未指定pcre
路徑
1else
2
3 if [ "$NGX_PLATFORM" != win32 ]; then
4
5 PCRE=NO
6
7 ngx_feature="PCRE library"
8 ngx_feature_name="NGX_PCRE"
9 ngx_feature_run=no
10 ngx_feature_incs="#include <pcre.h>"
11 ngx_feature_path=
12 ngx_feature_libs="-lpcre"
13 ngx_feature_test="pcre *re;
14 re = pcre_compile(NULL, 0, NULL, 0, NULL);
15 if (re == NULL) return 1"
16 . auto/feature
17
18 if [ $ngx_found = no ]; then
19
20 # FreeBSD port
21
22 ngx_feature="PCRE library in /usr/local/"
23 ngx_feature_path="/usr/local/include"
24
25 if [ $NGX_RPATH = YES ]; then
26 ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lpcre"
27 else
28 ngx_feature_libs="-L/usr/local/lib -lpcre"
29 fi
30
31 . auto/feature
32 fi
33
34 if [ $ngx_found = no ]; then
35
36 # RedHat RPM, Solaris package
37
38 ngx_feature="PCRE library in /usr/include/pcre/"
39 ngx_feature_path="/usr/include/pcre"
40 ngx_feature_libs="-lpcre"
41
42 . auto/feature
43 fi
44
45 if [ $ngx_found = no ]; then
46
47 # NetBSD port
48
49 ngx_feature="PCRE library in /usr/pkg/"
50 ngx_feature_path="/usr/pkg/include"
51
52 if [ $NGX_RPATH = YES ]; then
53 ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
54 else
55 ngx_feature_libs="-L/usr/pkg/lib -lpcre"
56 fi
57
58 . auto/feature
59 fi
60
61 if [ $ngx_found = no ]; then
62
63 # MacPorts
64
65 ngx_feature="PCRE library in /opt/local/"
66 ngx_feature_path="/opt/local/include"
67
68 if [ $NGX_RPATH = YES ]; then
69 ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
70 else
71 ngx_feature_libs="-L/opt/local/lib -lpcre"
72 fi
73
74 . auto/feature
75 fi
76
77 if [ $ngx_found = yes ]; then
78 CORE_INCS="$CORE_INCS $ngx_feature_path"
79 CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
80 PCRE=YES
81 fi
82
83 if [ $PCRE = YES ]; then
84 ngx_feature="PCRE JIT support"
85 ngx_feature_name="NGX_HAVE_PCRE_JIT"
86 ngx_feature_test="int jit = 0;
87 pcre_free_study(NULL);
88 pcre_config(PCRE_CONFIG_JIT, &jit);
89 if (jit != 1) return 1;"
90 . auto/feature
91
92 if [ $ngx_found = yes ]; then
93 PCRE_JIT=YES
94 fi
95 fi
96 fi
97
98 if [ $PCRE != YES ]; then
99cat << END
100
101$0: error: the HTTP rewrite module requires the PCRE library.
102You can either disable the module by using --without-http_rewrite_module
103option, or install the PCRE library into the system, or build the PCRE library
104statically from the source with nginx by using --with-pcre=<path> option.
105
106END
107 exit 1
108 fi
109
110fi
複製代碼
這一部分是在沒有設置pcre
的時候執行。nginx
會經過auto/feature
腳本測試當前操做系統是否支持pcre
功能。
這一部分腳本雖然比較多,可是功能特別單一。
首先默認pcre
安裝在了標準路徑
中。這裏的標準路徑
指的是編譯器默認查找頭文件以及庫文件的路徑。
若是沒有找到,那麼依次從/usr/include/pcre
, /usr/pkg/include
, /opt/local/include
路徑中查找,若是在任何一個路徑中找到pcre
都算成功。
找到PCRE
以後,會進一步的測試PCRE_JIT
功能。
若是通過上面的步驟以後,仍是沒有找到pcre
,那麼就會輸出錯誤提示,以下:
1./configure: error: the HTTP rewrite module requires the PCRE library.
2You can either disable the module by using --without-http_rewrite_module
3option, or install the PCRE library into the system, or build the PCRE library
4statically from the source with nginx by using --with-pcre=<path> option.
複製代碼
咱們在本文中詳細的分析了auto/lib/
目錄下的腳本。
這一部分的腳本主要是爲了nginx
使用到的第三方庫進行便已測試。我只對pcre
庫的內容進行了分析。其餘的你們能夠自行分析。
後面的文章咱們會接着分析nginx
的源碼,敬請期待。順便關注個人個公衆號(Nginx源碼分析
)。
Nginx源碼分析
,更多精彩內容第一時間送達