微信公众号:Nginx源码分析
关注可了解更多的Nginx
知识。任何问题或建议,请公众号留言;
关注公众号,有趣有内涵的文章第一时间送达!
回顾
我们在上一篇文章中详细的分析了auto/define
,auto/have
,auto/nohave
脚本源码,本文我们继续分析其他辅助脚本文件。我们首先回顾一下nginx
中的大致辅助脚本图片,如下图:
auto/types脚本
在auto/types
目录下面有四个脚本,分别是sizeof
,typedef
,uintptr_t
,value
,这几个脚本都和c
语言的数据类型有关。本文剩余的内容和下篇文章会主要分析一下这四个脚本。
auto/types/sizeof脚本
功能
参数
ngx_type
:要检测的数据类型
脚本内容
echo $ngx_n "checking for $ngx_type size ...$ngx_c"
cat << END >> $NGX_AUTOCONF_ERR
----------------------------------------
checking for $ngx_type size
END
ngx_size=
cat << END > $NGX_AUTOTEST.c
#include <sys/types.h>
#include <sys/time.h>
$NGX_INCLUDE_UNISTD_H
#include <signal.h>
#include <sys/resource.h>
$NGX_INCLUDE_INTTYPES_H
$NGX_INCLUDE_AUTO_CONFIG_H
int main() {
printf("%d", sizeof($ngx_type));
return 0;
}
END
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then
ngx_size=`$NGX_AUTOTEST`
echo " $ngx_size bytes"
fi
rm -f $NGX_AUTOTEST
case $ngx_size in
4)
if [ "$ngx_type"="long" ]; then
ngx_max_value=2147483647L
else
ngx_max_value=2147483647
fi
ngx_max_len='(sizeof("-2147483648") - 1)'
;;
8)
if [ "$ngx_type"="long long" ]; then
ngx_max_value=9223372036854775807LL
else
ngx_max_value=9223372036854775807L
fi
ngx_max_len='(sizeof("-9223372036854775808") - 1)'
;;
*)
echo
echo "$0: error: can not detect $ngx_type size"
echo "----------" >> $NGX_AUTOCONF_ERR
cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
echo "----------" >> $NGX_AUTOCONF_ERR
echo $ngx_test >> $NGX_AUTOCONF_ERR
echo "----------" >> $NGX_AUTOCONF_ERR
exit 1
esac
示例
我们这次先看示例,然后用实际例子来分析这个脚本,这样更容易理解。
在auto/unix
脚本中有如下的内容:
# C types
ngx_type="int"; . auto/types/sizeof
ngx_type="long"; . auto/types/sizeof
ngx_type="long long"; . auto/types/sizeof
上面的脚本分别是计算sizeof(int)
,sizeof(long)
,sizeof(long long)
的脚本。
我们以sizeof(int)
为例分析该脚本。
脚本分析
1).
首先是向控制台输出信息
echo $ngx_n "checking for $ngx_type size ...$ngx_c"
我们在终端上可以看到如下内容:
checking for int size ...
2).
向NGX_AUTOCONF_ERR
中输出内容,表示开始类型检测,便于后面分析错误。
cat << END >> $NGX_AUTOCONF_ERR
----------------------------------------
checking for $ngx_type size
END
所以,实际上向NGX_AUTOCONF_ERR
中写入的内容是:
checking for int size
3). 生成测试程序
ngx_size=
cat << END > $NGX_AUTOTEST.c
#include <sys/types.h>
#include <sys/time.h>
$NGX_INCLUDE_UNISTD_H
#include <signal.h>
#include <sys/resource.h>
$NGX_INCLUDE_INTTYPES_H
$NGX_INCLUDE_AUTO_CONFIG_H
int main() {
printf("%d", sizeof($ngx_type));
return 0;
}
这里首先将ngx_size
的内容赋值为空,这个变量在后面用来表示int
类型的长度。
接着生成如下的测试源文件。
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <sys/resource.h>
#include <inttypes.h>
int main() {
printf("%d", sizeof(int));
return 0;
}
这个源文件真的是很简单,就是在终端打印一下sizeof(int)
的值。
4).
编译上面生成的源文件
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
上面的ngx_test
就是一个编译语句,具体内容如下:
ngx_test=gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -o objs/autotest objs/autotest.c
紧接着的eval
语句会执行ngx_test
的内容,也就是执行编译语句,生成可以执行文件objs/autotest
。
5).
执行可执行程序
if [ -x $NGX_AUTOTEST ]; then
ngx_size=`$NGX_AUTOTEST`
echo " $ngx_size bytes"
fi
nginx
判断如果第4
步生成的目标文件是是可执行文件-x $NGX_AUTOTEST
,那么执行该目标文件,并将结果保存到ngx_size
变量中。
6).
删除目标文件
rm -f $NGX_AUTOTEST
Nginx
会在运行完可执行文件之后就将该文件删除,所以实际上我们在Nginx
的目录中是不能看到这些文件的,它们都是临时文件。
7).
设置该类型的最大值和最大长度
case $ngx_size in
4)
if [ "$ngx_type"="long" ]; then
ngx_max_value=2147483647L
else
ngx_max_value=2147483647
fi
ngx_max_len='(sizeof("-2147483648") - 1)'
;;
8)
if [ "$ngx_type"="long long" ]; then
ngx_max_value=9223372036854775807LL
else
ngx_max_value=9223372036854775807L
fi
ngx_max_len='(sizeof("-9223372036854775808") - 1)'
;;
*)
echo
echo "$0: error: can not detect $ngx_type size"
echo "----------" >> $NGX_AUTOCONF_ERR
cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
echo "----------" >> $NGX_AUTOCONF_ERR
echo $ngx_test >> $NGX_AUTOCONF_ERR
echo "----------" >> $NGX_AUTOCONF_ERR
exit 1
esac
其中ngx_size
就是第5)
步中得到的长度,根据该值来计算最大值ngx_max_value
和最大长度ngx_max_len
,这两个值在后面执行auto/types/value
的时候会用到。如下:
ngx_type="off_t"; . auto/types/sizeof
ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
至于auto/types/value
脚本,我们后面的文章会分析。
总结
本文详细的分析了auto/types/sizeof
脚本的功能:测试一个c
语言数据类型在特定操作系统上的长度,根据长度进行不同的操作。
其实我们通过这几篇文章可以发现一个东东,Nginx
的许多脚本都是自动生成的,说实话,我以前看的源码比较少,也没有关注过这种大型工程的配置文件,真的是一种非常巧妙的方法,我们可以多多借鉴。
后面的文章我们会接着分析nginx
的其他辅助脚本,敬请期待。顺便关注我的个公众号(Nginx源码分析
)。