基于nginx-1.14.0脚本分析
该脚本检测不同平台的特性。它的实现原理是,写一段C程序,然后编译连接,生成可执行程序,再运行可执行程序,根据此过程来检查相关特性。。
脚本中使用变量
- 变量ngx_found:
使ngx_found用来返回检测的结果,检测失败为no,检测成功为yes,默认为失败。 - 变量ngx_feature_name:
传递给脚本需要写入的定义的名称,脚本中会把ngx_feature_name全部转化为大写字母,然后当作定义写入ngx_auto_config.h头文件中。 - 变量ngx_feature:
传递给脚本的特性名称,便于日志输出查看。例如刚开始编译时,会检测gcc compiler。 - 变量ngx_feature_path:
传递给脚本的,头文件的目录,脚本中会在此变量的每个路径前面添加-I,生成的ngx_feature_inc_path变量,以备在编译的时候使用。 - 变量ngx_feature_incs:
传递给脚本的,在代码中要include的头文件。 - 变量ngx_feature_libs:
传递给脚本的,编译源文件时需要依赖的库文件。 - 变量ngx_feature_test:
传递给脚本的,测试当前特性时要执行的代码,也可以为空,表示不执行任何代码。
变量ngx_feature_run:
传递给脚本的,编译成功后,对二进制文件需要执行什么操作,它的值可以是:yes,value,bug,以及其它的值。
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
echo $ngx_n "checking for $ngx_feature ...$ngx_c"
cat << END >> $NGX_AUTOCONF_ERR
----------------------------------------
checking for $ngx_feature
END
#
# ngx_found默认值设置为no
#
ngx_found=no
#
# 把ngx_feature_name的对应的小写字母转化成大写字母
#
if test -n "$ngx_feature_name"; then
ngx_have_feature=`echo $ngx_feature_name \
| tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
fi
#
# 在包含路径前面添加-I参数
#
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
#
# 向objs/autotest.c文件中写入代码
# 代码有中需要包含的头文件,和需要测试的代码
# NGX_AUTOTEST的默认值为objs/autotest
#
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
#
# 生成编译语句
# 例如最简易格式:cc -o objs/autotest objs/autotest.c
#
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=
#
# 编译objs/autotest.c文件,在目录objs生成autotest文件
# "-c"选项使shell解释器从一个字符串中而不是从一个文件中读取并执行shell命令。
#
eval "/bin/sh -c \"$ngx_test\" >> $NGX_AUTOCONF_ERR 2>&1"
#
# 如果生成的文件存在并且可执行
#
if [ -x $NGX_AUTOTEST ]; then
case "$ngx_feature_run" in
yes)
# 检查程序是否能运行。 程序返回0表示程序正常,会打印found字样
# 如程序正常执行,添加ngx_feature_name的宏定义,宏的值为1
# /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
;;
value)
#
# /bin/sh is used to intercept "Killed" or "Abort trap" messages
# 如果程序能够正常运行,将程序标准输出的结果作为宏的值,把ngx_feature_name值写入到文件ngx_auto_config.h中。
#
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
;;
bug)
# 与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 " not found"
else
echo " found"
ngx_found=yes
if test -n "$ngx_feature_name"; then
have=$ngx_have_feature . auto/have
fi
fi
;;
*)
echo " found"
ngx_found=yes
if test -n "$ngx_feature_name"; then
have=$ngx_have_feature . auto/have
fi
;;
esac
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
#
# 删除相关临时文件
#
rm -rf $NGX_AUTOTEST*