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

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

回顾

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

nginx辅助脚本

本文讲述一下auto/types/typedef脚本,

auto/types/typedef脚本

Nginx的脚本名称以及变量名称都是非常的直截了当,我们完全可以见名知意,这是我们在写代码的时候要学习借鉴的地方。从这个脚本的名称中我们即可以看到,它的作用就是生成typedef声明的。

auto/types/sizeof脚本

参数

ngx_type:类型1
ngx_types:类型2

功能

判断ngx_typengx_types是否存在,根据判断条件生成相应的typedef语句。

示例

我们这次先看一下脚本使用的示例,从而全面了解一下这个脚本。
auto/unix脚本中,调用了auto/types/typedef脚本,如下:

ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef
脚本内容
echo $ngx_n "checking for $ngx_type ...$ngx_c"

cat << END >> $NGX_AUTOCONF_ERR

----------------------------------------
checking for $ngx_type

END

ngx_found=no

for ngx_try in $ngx_type $ngx_types
do

    cat << END > $NGX_AUTOTEST.c

#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
$NGX_INCLUDE_INTTYPES_H

int main() {
    $ngx_try i = 0;
    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
        if [ $ngx_try = $ngx_type ]; then
            echo " found"
            ngx_found=yes
        else
            echo ", $ngx_try used"
            ngx_found=$ngx_try
        fi
    fi

    rm -f $NGX_AUTOTEST

    if [ $ngx_found = no ]; then
        echo $ngx_n " $ngx_try not found$ngx_c"

        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

    else
        break
    fi
done

if [ $ngx_found = no ]; then
    echo
    echo "$0: error: can not define $ngx_type"

    exit 1
fi

if [ $ngx_found != yes ]; then
    echo "typedef $ngx_found  $ngx_type;"   >> $NGX_AUTO_CONFIG_H
fi
脚本分析

我们按照示例的调用例子进行脚本分析。

1). 首先是向控制台输出信息
我们在前面的文章中分析过ngx_c变量,这里不再赘述。

echo $ngx_n "checking for $ngx_type ...$ngx_c"   

我们在终端上可以看到如下内容:

checking for uint64_t ...

2).NGX_AUTOCONF_ERR中生成内容。

cat << END >> $NGX_AUTOCONF_ERR

----------------------------------------
checking for $ngx_type

END

END

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

checking for uint64_t

从前面的文章到现在,我们可以看出来,Nginx的每一步都有完善的日志,这对于监控程序的执行流程以及分析错误原因是非常有帮助的。

3). 生成测试程序

ngx_found=no

这里首先将ngx_found的内容赋值为no,这个变量在后面用来表示是否存在我们要检测的数据类型。

接着,auto/types/typedef脚本通过一个for循环遍历传进来的ngx_typengx_types,每次循环处理过程都是一样。我们分析一下这个for循环。
对于每次循环,都会根据当前遍历到的变量生成一份测试用的c源码,如下:

    cat << END > $NGX_AUTOTEST.c

#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
$NGX_INCLUDE_INTTYPES_H

int main() {
    $ngx_try i = 0;
    return 0;
}

END

实际对于我们示例的情况,第一次循环生成的代码如下:

#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <inttypes.h>

int main() {
    uint64_t i = 0;
    return 0;
}

这个源文件真的是很简单,main函数中只有一行实际的代码。这行代码的作用很简单:如果uint64_i这个类型存在的话,那么这个源文件肯定能编译成功,并且最终生成可以执行的目标文件。我们可以通过检测最终的目标文件是否可以被执行来间接的判断uint64_t类型是否存在。

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就是一个编译语句,具体内容如下:

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
        if [ $ngx_try = $ngx_type ]; then
        # $ngx_type是传给for循环的第一个循环参数。所以如果能够执行到这里,则说明第一个参数$ngx_type代表的类型存在
            echo " found"
            ngx_found=yes
        else
        # 如果执行到这里,那么说明$ngx_type代表的变量类型不存在,但是$ngx_types代表的变量类型存在, 这个时候 ngx_found就会被赋值为$ngx_types类型
            echo ", $ngx_try used"
            ngx_found=$ngx_try
        fi
fi

nginx判断如果第4步生成的目标文件是是可执行文件-x $NGX_AUTOTEST,那么执行该目标文件.
这段代码的详细分析我已经在代码里面进行了注释。

6).删除目标文件

rm -f $NGX_AUTOTEST

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

7).根据上面的执行结果进行错误输出

if [ $ngx_found = no ]; then
        echo $ngx_n " $ngx_try not found$ngx_c"

        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

    else
    # 如果当前的数据类型存在,那么就break,不再进行下面的for循环
        break
fi

如果当前遍历的变量类型并不存在,会进行日志输出。
首先,在控制台上面输出unit64_t not found(我们假设当前检测的uint64_t类型不存在)。
然后,把生成的检测数据类型的c源文件以及便一直令保存到NGX_AUTOCONF_ERR文件中,便于进行错误分析。

8). 循环结束后的处理
这里要分三种种情况,如下:

① ``ngx_typengx_types都不存在。那么执行下面的脚本:

if [ $ngx_found = no ]; then
    echo
    echo "$0: error: can not define $ngx_type"

    exit 1
fi

这部分脚本会向控制台输出一行错误信息,告诉nginx不能使用当前的变量类型,然后结束脚本。

ngx_type存在。如果是这种情况的话,ngx_found的值是yes,这样的话,auto/types/typedef脚本就直接结束了。

③ ngx_type类型不存在,但是ngx_types存在。这个时候ngx_found的值是ngx_types的值。所以会执行下面的脚本:

if [ $ngx_found != yes ]; then
    echo "typedef $ngx_found  $ngx_type;"   >> $
fi

也就是向NGX_AUTO_CONFIG_H头文件中生成一个typedef语句。如下:

typedef $ngx_types  $ngx_type;

也即是把ngx_type作为$ngx_types的别名,这样程序中就可以一直使用ngx_type这种类型。
对于本例来说,假设满足第种条件的话,就会生成一个如下的typedef语句:

typedef u_int64_t uint64_t;

到此为止,我们已经分析完了auto/types/typedef脚本。

总结

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容