社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  NGINX

Nginx源码分析之--auto/types/sizeof脚本

郑尔多斯 • 6 年前 • 561 次点击  
阅读 21

Nginx源码分析之--auto/types/sizeof脚本

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

回顾

我们在上一篇文章中详细的分析了auto/defineauto/have,auto/nohave脚本源码,本文我们继续分析其他辅助脚本文件。我们首先回顾一下nginx中的大致辅助脚本图片,如下图:

nginx辅助脚本
nginx辅助脚本

auto/types脚本

auto/types目录下面有四个脚本,分别是sizeof,typedef,uintptr_t,value,这几个脚本都和c语言的数据类型有关。本文剩余的内容和下篇文章会主要分析一下这四个脚本。

auto/types/sizeof脚本

功能
参数

ngx_type:要检测的数据类型

脚本内容
 1echo


    
 $ngx_n "checking for $ngx_type size ...$ngx_c"
2
3cat << END >> $NGX_AUTOCONF_ERR
4
5----------------------------------------
6checking for $ngx_type size
7
8END
9
10ngx_size=
11
12cat << END > $NGX_AUTOTEST.c
13
14#include <sys/types.h>
15#include <sys/time.h>
16$NGX_INCLUDE_UNISTD_H
17#include <signal.h>
18#include <sys/resource.h>
19$NGX_INCLUDE_INTTYPES_H
20$NGX_INCLUDE_AUTO_CONFIG_H
21
22int main() {
23    printf("%d" , sizeof($ngx_type));
24    return 0;
25}
26
27END
28
29
30ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
31          -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"

32
33eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
34
35
36if [ -x $NGX_AUTOTEST ]; then
37    ngx_size=`$NGX_AUTOTEST`
38    echo $ngx_size bytes"
39fi
40
41
42rm -f $NGX_AUTOTEST
43
44
45case $ngx_size in
46    4)
47        if [ "$ngx_type"="long" ]; then
48            ngx_max_value=2147483647L
49        else
50            ngx_max_value=2147483647
51        fi
52
53        ngx_max_len='(sizeof("-2147483648") - 1)'
54    ;;
55
56    8)
57        if [ "$ngx_type"="long long" ]; then
58            ngx_max_value=9223372036854775807LL
59        else
60            ngx_max_value=9223372036854775807L
61        fi
62
63        ngx_max_len='(sizeof("-9223372036854775808") - 1)'
64    ;;
65
66    *)
67        echo
68        echo "$0: error: can not detect $ngx_type size"
69
70        echo "----------"    >> $NGX_AUTOCONF_ERR
71        cat $NGX_AUTOTEST.c  >> $NGX_AUTOCONF_ERR
72        echo "----------"    >> $NGX_AUTOCONF_ERR
73        echo $ngx_test       >> $NGX_AUTOCONF_ERR
74        echo "----------"    >> $NGX_AUTOCONF_ERR
75
76        exit 1
77esac
复制代码
示例

我们这次先看示例,然后用实际例子来分析这个脚本,这样更容易理解。
auto/unix脚本中有如下的内容:

1# C types
2
3ngx_type="int"; . auto/types/sizeof
4
5ngx_type="long"; . auto/types/sizeof
6
7ngx_type="long long"; . auto/types/sizeof
复制代码

上面的脚本分别是计算sizeof(int)sizeof(long)sizeof(long long)的脚本。
我们以sizeof(int)为例分析该脚本。

脚本分析

1). 首先是向控制台输出信息
sh echo $ngx_n "checking for $ngx_type size ...$ngx_c"
我们在终端上可以看到如下内容:
sh checking for int size ...

2).NGX_AUTOCONF_ERR中输出内容,表示开始类型检测,便于后面分析错误。

1cat << END >> $NGX_AUTOCONF_ERR
2
3----------------------------------------
4checking for $ngx_type size
5
6END
复制代码

所以,实际上向NGX_AUTOCONF_ERR中写入的内容是:

1checking for int size
复制代码

3). 生成测试程序

 1ngx_size=
2
3cat << END > $NGX_AUTOTEST.c
4
5#include <sys/types.h>
6#include <sys/time.h>
7$NGX_INCLUDE_UNISTD_H
8#include <signal.h>
9#include <sys/resource.h>
10$NGX_INCLUDE_INTTYPES_H
11$NGX_INCLUDE_AUTO_CONFIG_H
12
13int main() {
14    printf("%d", sizeof($ngx_type));
15    return 0;
16}
复制代码

这里首先将ngx_size的内容赋值为空,这个变量在后面用来表示int类型的长度。
接着生成如下的测试源文件。

 1#include <sys/types.h>
2#include <sys/time.h>
3 #include <unistd.h>
4#include <signal.h>
5#include <sys/resource.h>
6#include <inttypes.h>
7
8
9int main() {
10    printf("%d"sizeof(int));
11    return 0;
12}
复制代码

这个源文件真的是很简单,就是在终端打印一下sizeof(int)的值。

4). 编译上面生成的源文件

1ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
2          -o $NGX_AUTOTEST $NGX_AUTOTEST .c $NGX_LD_OPT $ngx_feature_libs"

3
4eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
复制代码

上面的ngx_test就是一个编译语句,具体内容如下:

1ngx_test=gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64           -o objs/autotest objs/autotest.c
复制代码

紧接着的eval语句会执行ngx_test的内容,也就是执行编译语句,生成可以执行文件objs/autotest

5). 执行可执行程序

1if [ -x $NGX_AUTOTEST ]; then
2    ngx_size=`$NGX_AUTOTEST`
3    echo $ngx_size bytes"
4fi
复制代码

nginx判断如果第4步生成的目标文件是是可执行文件-x $NGX_AUTOTEST,那么执行该目标文件,并将结果保存到ngx_size变量中。

6).删除目标文件

1rm -f $NGX_AUTOTEST
复制代码

Nginx会在运行完可执行文件之后就将该文件删除,所以实际上我们在Nginx的目录中是不能看到这些文件的,它们都是临时文件。

7).设置该类型的最大值和最大长度

 1case $ngx_size in
2    4)
3        if [ "$ngx_type"="long" ]; then
4            ngx_max_value=2147483647L
5        else
6            ngx_max_value=2147483647
7        fi
8
9        ngx_max_len='(sizeof("-2147483648") - 1)'
10    ;;
11
12    8)
13        if [ "$ngx_type"="long long" ]; then
14            ngx_max_value=9223372036854775807LL
15        else
16            ngx_max_value=9223372036854775807L
17        fi
18
19        ngx_max_len='(sizeof("-9223372036854775808") - 1)'
20    ;;
21
22    *)
23        echo
24        echo "$0: error: can not detect $ngx_type size"
25
26        echo "----------"    >> $NGX_AUTOCONF_ERR
27        cat $NGX_AUTOTEST.c  >> $NGX_AUTOCONF_ERR
28        echo "----------"    >> $NGX_AUTOCONF_ERR
29        echo $ngx_test       >> $NGX_AUTOCONF_ERR
30        echo "----------"    >> $NGX_AUTOCONF_ERR
31
32        exit 1
33esac
复制代码

其中ngx_size就是第5)步中得到的长度,根据该值来计算最大值ngx_max_value和最大长度ngx_max_len,这两个值在后面执行auto/types/value的时候会用到。如下:

1ngx_type="off_t"; . auto/types/sizeof
2ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
3ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
复制代码

至于auto/types/value脚本,我们后面的文章会分析。

总结

本文详细的分析了auto/types/sizeof脚本的功能:测试一个c语言数据类型在特定操作系统上的长度,根据长度进行不同的操作。
其实我们通过这几篇文章可以发现一个东东,Nginx的许多脚本都是自动生成的,说实话,我以前看的源码比较少,也没有关注过这种大型工程的配置文件,真的是一种非常巧妙的方法,我们可以多多借鉴。
后面的文章我们会接着分析nginx的其他辅助脚本,敬请期待。顺便关注我的个公众号(Nginx源码分析)。



喜欢本文的朋友们,欢迎长按下图关注订阅号Nginx源码分析,更多精彩内容第一时间送达
Nginx源码分析
Nginx源码分析
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/36076
 
561 次点击