利用configure脚本将定制的模块加入到Nginx中

在1.6节提到的configure执行流程中,其中有两行脚本负责将第三方模块加入到Nginx中,如下所示。

. auto/modules

. auto/make

下面完整地解释一下configure脚本是如何与3.3.1节中提到的config文件配合起来把定制的第三方模块加入到Nginx中的。

在执行configure --add-module=PATH命令时,PATH就是第三方模块所在的路径。在configure中,通过auto/options脚本设置了NGX_ADDONS变量:
--add-module=*)                  NGX_ADDONS="$NGX_ADDONS $value" ;;

在configure命令执行到auto/modules脚本时,将在生成的ngx_modules.c文件中加入定制的第三方模块。
if test -n "$NGX_ADDONS"; then

    echo configuring additional modules

    for ngx_addon_dir in $NGX_ADDONS
    do
        echo "adding module in $ngx_addon_dir"

        if test -f $ngx_addon_dir/config; then
            #在这里执行自定义的config脚本
            . $ngx_addon_dir/config

            echo " + $ngx_addon_name was configured"

        else
            echo "$0: error: no $ngx_addon_dir/config was found"
            exit 1
        fi
    done
fi

可以看到,$NGX_ADDONS可以包含多个目录,对于每个目录,如果其中存在config文件就会执行,也就是说,在config中重新定义的变量都会生效。之后,auto/modules脚本开始创建ngx_modules.c文件,这个文件的关键点就是定义了ngx_module_t *ngx_modules[]数组,这个数组存储了Nginx中的所有模块。Nginx在初始化、处理请求时,都会循环访问ngx_modules数组,确定该用哪一个模块来处理。下面来看一下auto/modules是如何生成数组的,代码如下所示:
modules="$CORE_MODULES $EVENT_MODULES"

if [ $USE_OPENSSL = YES ]; then
    modules="$modules $OPENSSL_MODULE"
    CORE_DEPS="$CORE_DEPS $OPENSSL_DEPS"
    CORE_SRCS="$CORE_SRCS $OPENSSL_SRCS"
fi

if [ $HTTP = YES ]; then
    modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \
             $HTTP_HEADERS_FILTER_MODULE \
             $HTTP_AUX_FILTER_MODULES \
             $HTTP_COPY_FILTER_MODULE \
             $HTTP_RANGE_BODY_FILTER_MODULE \
             $HTTP_NOT_MODIFIED_FILTER_MODULE"

    NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(HTTP_DEPS)"
fi

首先,auto/modules会按顺序生成modules变量。注意,这里的$HTTP_MODULES等已经在config文件中重定义了。这时,modules变量是包含所有模块的。然后,开始生成ngx_modules.c文件:
cat << END                                    > $NGX_MODULES_C

#include <ngx_config.h>
#include <ngx_core.h>

$NGX_PRAGMA

END

for mod in $modules
do
    echo "extern ngx_module_t  $mod;"         >> $NGX_MODULES_C
done

echo                                          >> $NGX_MODULES_C
echo 'ngx_module_t *ngx_modules[] = {'        >> $NGX_MODULES_C

for mod in $modules
do
    #向ngx_modules数组里添加Nginx模块
    echo "    &$mod,"                         >> $NGX_MODULES_C
done

cat << END                                    >> $NGX_MODULES_C
    NULL
};

END

这样就已经确定了Nginx在运行时会调用自定义的模块,而auto/make脚本负责把相关模块编译进Nginx。

在Makefile中生成编译第三方模块的源代码如下:
if test -n "$NGX_ADDON_SRCS"; then

    ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"

    for ngx_src in $NGX_ADDON_SRCS
    do
        ngx_obj="addon/`basename \`dirname $ngx_src\``"

        ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
            | sed -e "s/\//$ngx_regex_dirsep/g"`

        ngx_obj=`echo $ngx_obj \
            | sed -e
              "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
                  -e
              "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
                  -e
              "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
                  -e
              "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`

        ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`

        cat << END                                            >> $NGX_MAKEFILE

$ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src
 $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END
     done

fi

下面这段代码用于将各个模块的目标文件设置到ngx_obj变量中,紧接着会生成Makefile里的链接代码,并将所有的目标文件、库文件链接成二进制程序。
for ngx_src in $NGX_ADDON_SRCS
do
    ngx_obj="addon/`basename \`dirname $ngx_src\``"

    test -d $NGX_OBJS/$ngx_obj || mkdir -p $NGX_OBJS/$ngx_obj

    ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
        | sed -e "s/\//$ngx_regex_dirsep/g"`

    ngx_all_srcs="$ngx_all_srcs $ngx_obj"
done

cat << END                                                    >> $NGX_MAKEFILE

$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: 
 $ngx_deps$ngx_spacer \$(LINK)
 ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link
 $ngx_rcc
${ngx_long_end}
END

综上可知,第三方模块就是这样嵌入到Nginx程序中的。

猜你喜欢

转载自blog.csdn.net/ai2000ai/article/details/80402721