Nginx编译配置脚本篇- 工具型脚本系列
Posted 彼方丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx编译配置脚本篇- 工具型脚本系列相关的知识,希望对你有一定的参考价值。
nginx编译配置脚本篇(4)- 工具型脚本系列
1、相关文章
由于学习本文需要Nginx
源码及搭建相关的编译环境,且本文与前面的文章有先后呼应关系,所以建议大家按以下文章顺序阅读
- CentOS 7使用源码编译安装Nginx,以及配置使用autoindex模块
- Nginx配置编译脚本篇(1)- 解析配置选项脚本auto/options
- Nginx编译配置脚本篇(2)- Makefile初始化脚本auto/init
- Nginx编译配置脚本篇(3)- 源码相关变量脚本auto/sources
2、前言
本文将介绍Nginx
里面的一些工具型脚本,里面有些是内容比较简短,有些是内容比较相似的,故放在一起讲了。需要注意的是,本文并不完全按照configure
文件的调用顺序来讲解各个脚本。
(configure
文件将在最后一篇关于Nginx
脚本配置文件的文章中讲解)
3、目录
3.1、auto/have脚本文件
- 主要功能:向自动配置头文件中添加标示有指定参数的宏定义
- 处理变量:
$have
- 作用对象:
$NGX_AUTO_CONFIG_H
所表示的自动配置头文件(前文介绍过了,该值默认为objs/ngx_auto_config.h
) - 源代码如下:
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $have
#define $have 1
#endif
END
- 若
have
变量的值为NGX_DEBUG
,则运行该脚本后,objs/ngx_auto_config.h
中将追加如下内容:
#ifndef NGX_DEBUG
#define NGX_DEBUG 1
#endif
3.2、auto/nohave脚本文件
- 主要功能:向自动配置头文件中添加标示没有指定参数的宏定义
- 处理变量:
$have
- 作用对象:
$NGX_AUTO_CONFIG_H
所表示的自动配置头文件(前文介绍过了,该值默认为objs/ngx_auto_config.h
) - 源代码如下:
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $have
#define $have 0
#endif
END
- 若
have
变量的值为NGX_DEBUG
,则运行该脚本后,objs/ngx_auto_config.h
中将追加如下内容:
#ifndef NGX_DEBUG
#define NGX_DEBUG 0
#endif
3.3、auto/define脚本文件
- 主要功能:向自动配置头文件中添加标示指定参数的值
- 处理变量:
$have
和$value
- 作用对象:
$NGX_AUTO_CONFIG_H
所表示的自动配置头文件(前文介绍过了,该值默认为objs/ngx_auto_config.h
) - 源代码如下:
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $have
#define $have $value
#endif
END
- 若
have
变量的值为NGX_CPU_CACHE_LINE
,value
变量的值为64
,则运行该脚本后,objs/ngx_auto_config.h
中将追加如下内容:
#ifndef NGX_CPU_CACHE_LINE
#define NGX_CPU_CACHE_LINE 64
#endif
3.4、auto/have_headers脚本文件
- 主要功能:向自动头头文件中添加标示有指定参数的宏定义
- 处理变量:
$have
- 作用对象:
$NGX_AUTO_HEADERS_H
所表示的自动头文件(前文介绍过了,该值默认为objs/ngx_auto_headers.h
) - 源代码如下:
cat << END >> $NGX_AUTO_HEADERS_H
#ifndef $have
#define $have 1
#endif
END
- 若
have
变量的值为NGX_HAVE_UNISTD_H
,则运行该脚本后,objs/ngx_auto_headers.h
中将追加如下内容:
#ifndef NGX_HAVE_UNISTD_H
#define NGX_HAVE_UNISTD_H 1
#endif
3.5、auto/feature脚本文件
该文件的主要功能是测试系统环境是否支持某些操作的,如果测试了某一操作不支持,则会将错误信息输出到$NGX_AUTOCONF_ERR
文件中
$NGX_AUTOCONF_ERR
默认值是autoconf.err
,该变量是在auto/init
文件中被初始化的
接下来详细分析该文件:
3.5.1、输出检查提示信息
在《Nginx编译配置脚本篇(2)- Makefile初始化脚本auto/init》一文中我们介绍了关于ngx_n
和ngx_c
两个变量,在auto/feature
中的第一句有效代码是:
echo $ngx_n "checking for $ngx_feature ...$ngx_c"
这一行代码的意思就是输出checking for $ngx_feature
和换行符到$NGX_AUTOCONF_ERR
文件中,以此来提示我们当前检查的操作是$ngx_feature
。当然ngx_n
和ngx_c
是有可能都为空的,这时就没有换行了。
3.5.2、初始化ngx_found变量
代码如下:
ngx_found=no
3.5.3、初始化ngx_have_feature变量
代码如下:
if test -n "$ngx_feature_name"; then
ngx_have_feature=`echo $ngx_feature_name \\
| tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
fi
test -n
的意思是测试参数的长度是否为0。那么如果ngx_feature_name
的值为空,则不会执行if
语句,if
语句的内容是将ngx_have_feature
的值设置为ngx_feature_name
的值的大写版本(代码中使用tr
命令将小写全部改为大写)。
3.5.4、初始化ngx_feature_inc_path变量
代码如下:
if test -n "$ngx_feature_path"; then
for ngx_temp in $ngx_feature_path; do
ngx_feature_inc_path="$ngx_feature_inc_path -I $ngx_temp"
done
fi
test -n
的意思是测试参数的长度是否为0。假设ngx_feature_path
的值为/path/111 /path/222 /path/333
,则经过for
循环后ngx_feature_inc_path
的值将被置为-I /path/111 -I /path/222 -I /path/333
。
(-I path
是gcc
编译中指定头文件路径的语法)
3.5.5、生成自动测试程序
代码如下:
cat << END > $NGX_AUTOTEST.c
#include <sys/types.h>
$NGX_INCLUDE_UNISTD_H
$ngx_feature_incs
int main(void) {
$ngx_feature_test;
return 0;
}
END
NGX_AUTOTEST
的值是在auto/init
脚本中被初始化的,默认为objs/autotest
,在此处最终加上后缀名变为objs/autotest.c
。NGX_INCLUDE_UNISTD_H
暂时没有什么用,不用理会ngx_feature_incs
表示需要包含的头文件信息ngx_feature_test
表示测试函数,如果编译能成功表示当前系统环境支持改函数,反之不支持
3.5.6、编译自动测试程序
代码如下:
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \\
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs"
ngx_feature_inc_path=
eval "/bin/sh -c \\"$ngx_test\\" >> $NGX_AUTOCONF_ERR 2>&1"
CC
的值是在atuo/options
中设置的,值默认为cc
CC_TEST_FLAGS
的值是在atuo/cc/
目录中根据环境不同进行不同的设置的,在Linux
该值默认为-pipe
-pipe
是gcc
的一个编译选项,用于加快编译速度用的。gcc
在将源代码变成可执行文件的过程中,需要经过许多中间步骤,包括预处理、编译、汇编和连接,这些过程实际上是由不同的程序负责完成的。大多数情况下gcc
可以自动调用相应程序进行处理,替程序员完成一整套编译工作。但是这样做有一个很明显的缺点,就是gcc
在处理每一个源文件时,最终都需要生成好几个临时文件才能完成相应的工作,从而无形中导致处理速度变慢。例如,gcc
在处理一个源文件时,可能需要一个临时文件来保存预处理的输出,一个临时文件来保存编译器的输出,一个临时文件来保存汇编器的输出,而读写这些临时文件显然需要耗费一定的时间。当软件项目变得非常庞大的时候,花费在这上面的代价可能会变得很大。解决的办法是,使用Linux
提供的一种更加高效的通信方式——管道。它可以用来同时连接两个程序,其中一个程序的输出将直接作为另一个程序的输入,这样就可以避免使用临时文件,但编译时需要消耗更多的内存。
CC_AUX_FLAGS
的值是在atuo/os/
目录中根据环境不同进行不同的设置的ngx_feature_inc_path
在3.5.4小节
介绍过了,这里就不赘述了NGX_AUTOTEST
在3.5.5小节
介绍过了,这里就不赘述了NGX_TEST_LD_OPT
是链接选项了,一般为空ngx_feature_libs
是需要链接的动态库,有些需要有些不需要,比如测试epoll
就不需要链接动态库了,测试pthread
则需要链接动态库了- 展开示例:
ngx_test="cc -pipe -D_GNU_SOURCE -o objs/autotest objs/autotest.c -ldl"
- 使用
ngx_feature_inc_path=
将ngx_feature_inc_path
的值置为空,以免影响后续调用 - 最后运行编译程序生成可执行文件,并将标准错误信息输出到
$NGX_AUTOCONF_ERR
文件中
3.5.7、根据ngx_feature_run进行相应的处理
Shell
编程中-x
表示检查文件是否存在且是一个可执行文件。如果$NGX_AUTOTEST
文件符合条件则执行then的操作。
if [ -x $NGX_AUTOTEST ]; then
case "$ngx_feature_run" in
- 如果
ngx_feature_run
的值为yes
,则将执行$NGX_AUTOTEST
文件,将标准错误信息输出到$NGX_AUTOCONF_ERR
文件中。
可以看到如果执行成功,会输出found
,并将ngx_found
的值置为yes
。如果此时ngx_feature_name
的值不为空,则将have
的值设置为ngx_have_feature
的值,并引用auto/have
脚本向objs/ngx_auto_config.h
写入宏定义,以此来表示某个功能被开启。
如果程序执行错误,则执行else
,输出错误信息。
代码如下:
yes)
# /bin/sh is used to intercept "Killed" or "Abort trap" messages
if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
echo " found"
ngx_found=yes
if test -n "$ngx_feature_name"; then
have=$ngx_have_feature . auto/have
fi
else
echo " found but is not working"
fi
;;
- 如果
ngx_feature_run
的值为value
,则也是执行$NGX_AUTOTEST
文件,将标准错误信息输出到$NGX_AUTOCONF_ERR
文件中。
可以看到如果执行成功,会输出found
,并将ngx_found
的值置为yes
,最后向$NGX_AUTO_CONFIG_H
文件中写入宏定义。
写入文件示例如下:
#ifndef NGX_HTTP_SCGI_TEMP_PATH
#define NGX_HTTP_SCGI_TEMP_PATH "scgi_temp"
#endif
如果程序执行错误,则执行else
,输出错误信息。
value)
# /bin/sh is used to intercept "Killed" or "Abort trap" messages
if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
echo " found"
ngx_found=yes
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_feature_name
#define $ngx_feature_name `$NGX_AUTOTEST`
#endif
END
else
echo " found but is not working"
fi
;;
- 如果
ngx_feature_run
的值为bug
,情况与前面类似,不过这个是当程序执行成功才会写入信息到文件中去的,与前面的逻辑相反,其他的操作都是一样的了,代码如下:
bug)
# /bin/sh is used to intercept "Killed" or "Abort trap" messages
if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
echo " not found"
else
echo " found"
ngx_found=yes
if test -n "$ngx_feature_name"; then
have=$ngx_have_feature . auto/have
fi
fi
;;
- 如果是其他情况,则只要
ngx_feature_name
不为空的话就将ngx_have_feature
相关的宏写入$NGX_AUTO_CONFIG_H
文件中。
(这种情况一般是某些函数接口在所有系统上都有实现,且暴露出来的接口是一致的,则不需要去特意检查当前环境是否支持该函数接口了)
*)
echo " found"
ngx_found=yes
if test -n "$ngx_feature_name"; then
have=$ngx_have_feature . auto/have
fi
;;
esac
- 如果
$NGX_AUTOTEST
文件不存在或者不可执行,则执行下面的else里面的内容,输出错误信息到$NGX_AUTOCONF_ERR
文件中。
else
echo " not found"
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
fi
3.5.8、删除与本次测试生成的文件
代码如下:
rm -rf $NGX_AUTOTEST*
3.6、其它与auto/feature具有类似功能的脚本文件
3.6.1、auto/types/sizeof脚本文件
该文件与auto/feature
文件类似,也是通过生成测试文件来进行操作的,不同的是auto/types/sizeof
是测试当前系统是32位还是64位的。该文件在auto/unix
文件中被调用。
3.6.2、auto/types/typedef脚本文件
该文件的作用是检查某个类型名是否被占用,没被占用的话就使用它来作为其它某个类型的别名(使用typedef
),然后输出到$NGX_AUTO_CONFIG_H
文件中。该文件在auto/unix
文件中被调用。
3.6.3、auto/types/uintptr_t脚本文件
该文件的作用是检查系统是否已经定义了uintptr_t
类型,有定义的话就不做任何动作,没定义的话就自己定义一个改类型,然后输出到$NGX_AUTO_CONFIG_H
文件中。该文件在auto/unix
文件中被调用。
3.6.4、auto/types/value脚本文件
该文件在auto/unix
文件中被调用的,比较简单,就不具体分析了。
代码如下:
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_param
#define $ngx_param $ngx_value
#endif
END
4、总结
本文主要介绍了一系列工具脚本的内容,它们有如下特点:
auto/have
、auto/nohave
、auto/define
、auto/have_headers
、auto/types/value
这五个脚本的作用都是往头文件里面写入宏,它们会被其它脚本多次复用,属于通用类型的脚本。auto/feature
、auto/types/sizeof
、auto/types/typedef
、auto/types/uintptr_t
这四个脚本属于功能性测试脚本,用于测试当前系统环境是否支持某一操作,不支持的话就会有对应的动作,它们也会被其它脚本复用。
以上是关于Nginx编译配置脚本篇- 工具型脚本系列的主要内容,如果未能解决你的问题,请参考以下文章
Nginx配置编译脚本篇- 解析配置选项脚本auto/options
Nginx编译配置脚本篇- 动态库配置脚本auto/lib/conf