Nginx源码分析之--auto/lib脚本

1,226 阅读14分钟

微信公众号:Nginx源码分析
关注可了解更多的Nginx知识。任何问题或建议,请公众号留言;
关注公众号,有趣有内涵的文章第一时间送达!

内容简介

本文分析auto/lib相关脚本的功能。
从脚本名称我们也能够知道,这部分是和第三方库相关的。比如pcre库,openssl, perl等。
我们首先看一下这个目录中的各个脚本的作用。如下图:

auto/lib目录
auto/lib目录

auto/lib/conf脚本

这个脚本就在configure中被调用。负责auto/lib下的所有第三方库的配置工作。

脚本内容
 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的处理。

 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_PCREPCRE的值,这两个变量的值都是是在auto/option中进行设置的。

默认情况下,这两个变量的值如下:

1USE_PCRE=NO
2PCRE=NONE

通过执行configure脚本时传递--with-pcre=*) PCRE="$value"参数可以设置这两个变量的值。其中USE_PCRE表示是否使用pcre库。PCRE表示pcre库所在的目录。

1--without-pcre)      USE_PCRE=DISABLED          ;;
2--with-pcre)         USE_PCRE=YES               ;;
3--with-pcre=*)       PCRE="$value"              ;;

如果我们没有设置pcre,但是使用了http_rewrite功能,那么在执行./cofigure脚本的时候就会报错,如下:

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的时候经常遇到的错误,就是上面所说的原因造成的。

注意:我们在./configure的时候可能并没有指定--with-pcre,但是默认情况下还是会编译pcre的。因为默认情况下HTTP_REWRITE = YES,在执行auto/modules脚本(后面分析)的时候,会根据HTTP_REWRITE来设置USE_PCRE的值。

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源码分析,更多精彩内容第一时间送达
Nginx源码分析
Nginx源码分析