Nginx源碼分析之--auto/types/sizeof腳本

微信公衆號:Nginx源碼分析
關注可瞭解更多的Nginx知識。任何問題或建議,請公衆號留言;
關注公衆號,有趣有內涵的文章第一時間送達!nginx

回顧

咱們在上一篇文章中詳細的分析了auto/defineauto/have,auto/nohave腳本源碼,本文咱們繼續分析其餘輔助腳本文件。咱們首先回顧一下nginx中的大體輔助腳本圖片,以下圖:
web

nginx輔助腳本
nginx輔助腳本

auto/types腳本

auto/types目錄下面有四個腳本,分別是sizeof,typedef,uintptr_t,value,這幾個腳本都和c語言的數據類型有關。本文剩餘的內容和下篇文章會主要分析一下這四個腳本。bash

auto/types/sizeof腳本

功能
參數

ngx_type:要檢測的數據類型微信

腳本內容
 1echo $ngx_n "checking for $ngx_type size ...$ngx_c"
2
3cat << END >> $NGX_AUTOCONF_ERR
4
5----------------------------------------
6checking for $ngx_type size
7
8END
9
10ngx_size=
11
12cat << END > $NGX_AUTOTEST.c
13
14#include <sys/types.h>
15#include <sys/time.h>
16$NGX_INCLUDE_UNISTD_H
17#include <signal.h>
18#include <sys/resource.h>
19$NGX_INCLUDE_INTTYPES_H
20$NGX_INCLUDE_AUTO_CONFIG_H
21
22int main() {
23    printf("%d", sizeof($ngx_type));
24    return 0;
25}
26
27END
28
29
30ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
31          -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"

32
33eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
34
35
36if [ -x $NGX_AUTOTEST ]; then
37    ngx_size=`$NGX_AUTOTEST`
38    echo $ngx_size bytes"
39fi
40
41
42rm -f $NGX_AUTOTEST
43
44
45case $ngx_size in
46    4)
47        if [ "$ngx_type"="long" ]; then
48            ngx_max_value=2147483647L
49        else
50            ngx_max_value=2147483647
51        fi
52
53        ngx_max_len='(sizeof("-2147483648") - 1)'
54    ;;
55
56    8)
57        if [ "$ngx_type"="long long" ]; then
58            ngx_max_value=9223372036854775807LL
59        else
60            ngx_max_value=9223372036854775807L
61        fi
62
63        ngx_max_len='(sizeof("-9223372036854775808") - 1)'
64    ;;
65
66    *)
67        echo
68        echo "$0: error: can not detect $ngx_type size"
69
70        echo "----------"    >> $NGX_AUTOCONF_ERR
71        cat $NGX_AUTOTEST.c  >> $NGX_AUTOCONF_ERR
72        echo "----------"    >> $NGX_AUTOCONF_ERR
73        echo $ngx_test       >> $NGX_AUTOCONF_ERR
74        echo "----------"    >> $NGX_AUTOCONF_ERR
75
76        exit 1
77esac
複製代碼
示例

咱們此次先看示例,而後用實際例子來分析這個腳本,這樣更容易理解。
auto/unix腳本中有以下的內容:app

1# C types
2
3ngx_type="int"; . auto/types/sizeof
4
5ngx_type="long"; . auto/types/sizeof
6
7ngx_type="long long"; . auto/types/sizeof
複製代碼

上面的腳本分別是計算sizeof(int)sizeof(long)sizeof(long long)的腳本。
咱們以sizeof(int)爲例分析該腳本。源碼分析

腳本分析

1). 首先是向控制檯輸出信息
sh echo $ngx_n "checking for $ngx_type size ...$ngx_c"
咱們在終端上能夠看到以下內容:
sh checking for int size ... 測試

2).NGX_AUTOCONF_ERR中輸出內容,表示開始類型檢測,便於後面分析錯誤。ui

1cat << END >> $NGX_AUTOCONF_ERR
2
3----------------------------------------
4checking for $ngx_type size
5
6END
複製代碼

因此,實際上向NGX_AUTOCONF_ERR中寫入的內容是:spa

1checking for int size
複製代碼

3). 生成測試程序操作系統

 1ngx_size=
2
3cat << END > $NGX_AUTOTEST.c
4
5#include <sys/types.h>
6#include <sys/time.h>
7$NGX_INCLUDE_UNISTD_H
8#include <signal.h>
9#include <sys/resource.h>
10$NGX_INCLUDE_INTTYPES_H
11$NGX_INCLUDE_AUTO_CONFIG_H
12
13int main() {
14    printf("%d", sizeof($ngx_type));
15    return 0;
16}
複製代碼

這裏首先將ngx_size的內容賦值爲空,這個變量在後面用來表示int類型的長度。
接着生成以下的測試源文件。

 1#include <sys/types.h>
2#include <sys/time.h>
3#include <unistd.h>
4#include <signal.h>
5#include <sys/resource.h>
6#include <inttypes.h>
7
8
9int main() {
10    printf("%d"sizeof(int));
11    return 0;
12}
複製代碼

這個源文件真的是很簡單,就是在終端打印一下sizeof(int)的值。

4). 編譯上面生成的源文件

1ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
2          -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"

3
4eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
複製代碼

上面的ngx_test就是一個編譯語句,具體內容以下:

1ngx_test=gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64           -o objs/autotest objs/autotest.c
複製代碼

緊接着的eval語句會執行ngx_test的內容,也就是執行編譯語句,生成能夠執行文件objs/autotest

5). 執行可執行程序

1if [ -x $NGX_AUTOTEST ]; then
2    ngx_size=`$NGX_AUTOTEST`
3    echo $ngx_size bytes"
4fi
複製代碼

nginx判斷若是第4步生成的目標文件是是可執行文件-x $NGX_AUTOTEST,那麼執行該目標文件,並將結果保存到ngx_size變量中。

6).刪除目標文件

1rm -f $NGX_AUTOTEST
複製代碼

Nginx會在運行完可執行文件以後就將該文件刪除,因此實際上咱們在Nginx的目錄中是不能看到這些文件的,它們都是臨時文件。

7).設置該類型的最大值和最大長度

 1case $ngx_size in
2    4)
3        if [ "$ngx_type"="long" ]; then
4            ngx_max_value=2147483647L
5        else
6            ngx_max_value=2147483647
7        fi
8
9        ngx_max_len='(sizeof("-2147483648") - 1)'
10    ;;
11
12    8)
13        if [ "$ngx_type"="long long" ]; then
14            ngx_max_value=9223372036854775807LL
15        else
16            ngx_max_value=9223372036854775807L
17        fi
18
19        ngx_max_len='(sizeof("-9223372036854775808") - 1)'
20    ;;
21
22    *)
23        echo
24        echo "$0: error: can not detect $ngx_type size"
25
26        echo "----------"    >> $NGX_AUTOCONF_ERR
27        cat $NGX_AUTOTEST.c  >> $NGX_AUTOCONF_ERR
28        echo "----------"    >> $NGX_AUTOCONF_ERR
29        echo $ngx_test       >> $NGX_AUTOCONF_ERR
30        echo "----------"    >> $NGX_AUTOCONF_ERR
31
32        exit 1
33esac
複製代碼

其中ngx_size就是第5)步中獲得的長度,根據該值來計算最大值ngx_max_value和最大長度ngx_max_len,這兩個值在後面執行auto/types/value的時候會用到。以下:

1ngx_type="off_t"; . auto/types/sizeof
2ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
3ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
複製代碼

至於auto/types/value腳本,咱們後面的文章會分析。

總結

本文詳細的分析了auto/types/sizeof腳本的功能:測試一個c語言數據類型在特定操做系統上的長度,根據長度進行不一樣的操做。
其實咱們經過這幾篇文章能夠發現一個東東,Nginx的許多腳本都是自動生成的,說實話,我之前看的源碼比較少,也沒有關注過這種大型工程的配置文件,真的是一種很是巧妙的方法,咱們能夠多多借鑑。
後面的文章咱們會接着分析nginx的其餘輔助腳本,敬請期待。順便關注個人個公衆號(Nginx源碼分析)。



喜歡本文的朋友們,歡迎長按下圖關注訂閱號Nginx源碼分析,更多精彩內容第一時間送達
Nginx源碼分析
Nginx源碼分析
相關文章
相關標籤/搜索