Nginx编译配置脚本篇- 编译器相关脚本

Posted 彼方丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx编译配置脚本篇- 编译器相关脚本相关的知识,希望对你有一定的参考价值。

1、相关文章

由于学习本文需要Nginx源码及搭建相关的编译环境,且本文与前面的文章有先后呼应关系,所以建议大家按以下文章顺序阅读

2、前言

auto/cc目录下的所有脚本都是用于配置不同平台的编译器的。众所周知Nginx具有出色的跨平台性能(LinuxDarwinSolarisWin32…),这些脚本在其中起到了巨大的作用。
脚本目录如下:

  • conf:为该目录下的主脚本,用于配置编译器的基本属性,并根据系统环境选用引用不同的编译器脚本
  • name:与编译器名称相关的处理逻辑
  • acc:HP ANSI C++编译器的配置脚本
  • bcc:Borland C++编译器的配置脚本
  • ccc:Compaq C编译器的配置脚本
  • clang:clang编译器的配置脚本
  • gcc:GNU C编译器的配置脚本
  • icc:Intel C++编译器的配置脚本
  • msvc:Microsoft Visual C++编译器的配置脚本
  • owc:Open Watcom C编译器的配置脚本
  • sunc:Sun C编译器的配置脚本

3、auto/cc/name脚本文件详解

  • 首先判断如果当前平台不是win32,则执行一次auto/feature,这次auto/feature不需要执行任何特殊函数,就是单纯试试当前环境是否支持$CC去编译代码(该参数默认是cc,可以自行在传入参数中指定用什么编译器,是在auto/options文件中设置的),不支持则退出。
    代码如下:
if [ "$NGX_PLATFORM" != win32 ]; then

    ngx_feature="C compiler"
    ngx_feature_name=
    ngx_feature_run=yes
    ngx_feature_incs=
    ngx_feature_path=
    ngx_feature_libs=
    ngx_feature_test=
    . auto/feature

    if [ $ngx_found = no ]; then
        echo
        echo $0: error: C compiler $CC is not found
        echo
        exit 1
    fi

fi
  • 接下来就是根据我们所选的编译器,去给NGX_CC_NAME赋予对应的值了,后续auto/cc/conf文件也是根据该值去调用当前编译器所对应的初始化脚本文件的
if [ "$CC" = cl ]; then
    NGX_CC_NAME=msvc
    echo " + using Microsoft Visual C++ compiler"

elif [ "$CC" = wcl386 ]; then
    NGX_CC_NAME=owc
    echo " + using Open Watcom C compiler"

elif [ "$CC" = bcc32 ]; then
    NGX_CC_NAME=bcc
    echo " + using Borland C++ compiler"

elif `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
    NGX_CC_NAME=icc
    echo " + using Intel C++ compiler"

elif `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
    NGX_CC_NAME=gcc
    echo " + using GNU C compiler"

elif `$CC -v 2>&1 | grep 'clang version' >/dev/null 2>&1`; then
    NGX_CC_NAME=clang
    echo " + using Clang C compiler"

elif `$CC -v 2>&1 | grep 'LLVM version' >/dev/null 2>&1`; then
    NGX_CC_NAME=clang
    echo " + using Clang C compiler"

elif `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
    NGX_CC_NAME=sunc
    echo " + using Sun C compiler"

elif `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then
    NGX_CC_NAME=ccc
    echo " + using Compaq C compiler"

elif `$CC -V 2>&1 | grep '^aCC: ' >/dev/null 2>&1`; then
    NGX_CC_NAME=acc
    echo " + using HP aC++ compiler"

else
    NGX_CC_NAME=unknown

fi

4、auto/cc/conf脚本文件详解

4.1、设置LINK变量

代码如下:

LINK="\\$(CC)"

MAIN_LINK=
MODULE_LINK="-shared"

4.2、设置编译选项变量

设置了各类编译选项,这里就不细说各个变量的作用了,有兴趣的读者可以自行百度搜索一下具体含义。
代码如下:

ngx_include_opt="-I "
ngx_compile_opt="-c"
ngx_pic_opt="-fPIC"
ngx_objout="-o "
ngx_binout="-o "

4.3、设置文件后缀变量

代码如下:

ngx_objext="o"
ngx_binext=
ngx_modext=".so"

4.4、设置某些平台相关变量

代码如下:

ngx_long_start=
ngx_long_end=
  • bcc中,ngx_long_start=’@&&|ngx_long_end=’|’
  • conf中,ngx_long_start=ngx_long_end=
  • msvc中,ngx_long_start=’@<<ngx_long_end=’<<’
  • owc中,ngx_long_start=’ ‘ngx_long_end=’ ’

4.5、设置某些符号变量

代码如下:

ngx_regex_dirsep="\\/"
ngx_dirsep='/'

ngx_regex_cont=' \\\\\\
	'
ngx_cont=' \\
	'
ngx_tab=' \\
		'
ngx_spacer=

ngx_long_regex_cont=$ngx_regex_cont
ngx_long_cont=$ngx_cont

各变量作用见下表:

变量作用
ngx_regex_dirsep正则表达式中的目录分隔符
ngx_dirsep目录分隔符
ngx_regex_cont正则续接符
ngx_cont续接符
ngx_tabTAB符号
ngx_spacer空内容符号
ngx_long_regex_cont正则续接符
ngx_long_cont续接符

4.6、调用auto/cc/name脚本

调用auto/cc/name脚本来获取NGX_CC_NAME变量,代码如下:

. auto/cc/name

4.7、根据NGX_CC_NAME选择对应的编译器的配置脚本

代码如下:

if test -n "$CFLAGS"; then

    CC_TEST_FLAGS="$CFLAGS $NGX_CC_OPT"

    case $NGX_CC_NAME in

        ccc)
            # Compaq C V6.5-207

            ngx_include_opt="-I"
        ;;

        sunc)

            MAIN_LINK=
            MODULE_LINK="-G"

            case "$NGX_MACHINE" in

                i86pc)
                    NGX_AUX=" src/os/unix/ngx_sunpro_x86.il"
                ;;

                sun4u | sun4v)
                    NGX_AUX=" src/os/unix/ngx_sunpro_sparc64.il"
                ;;

            esac

            case $CPU in

                amd64)
                    NGX_AUX=" src/os/unix/ngx_sunpro_amd64.il"
                ;;

            esac
        ;;

    esac

else

    case $NGX_CC_NAME in
        gcc)
            # gcc 2.7.2.3, 2.8.1, 2.95.4, egcs-1.1.2
            #     3.0.4, 3.1.1, 3.2.3, 3.3.2, 3.3.3, 3.3.4, 3.4.0, 3.4.2
            #     4.0.0, 4.0.1, 4.1.0

            . auto/cc/gcc
        ;;

        clang)
            # Clang C compiler

            . auto/cc/clang
        ;;

        icc)
            # Intel C++ compiler 7.1, 8.0, 8.1

            . auto/cc/icc
        ;;

        sunc)
            # Sun C 5.7 Patch 117837-04 2005/05/11

            . auto/cc/sunc
        ;;

        ccc)
            # Compaq C V6.5-207

            . auto/cc/ccc
        ;;

        acc)
            # aCC: HP ANSI C++ B3910B A.03.55.02

            . auto/cc/acc
        ;;

        msvc*)
            # MSVC++ 6.0 SP2, MSVC++ Toolkit 2003

            . auto/cc/msvc
        ;;

        owc)
            # Open Watcom C 1.0, 1.2

            . auto/cc/owc
        ;;

        bcc)
            # Borland C++ 5.5

            . auto/cc/bcc
        ;;

    esac

    CC_TEST_FLAGS="$CC_TEST_FLAGS $NGX_CC_OPT"

fi

CFLAGS="$CFLAGS $NGX_CC_OPT"
NGX_TEST_LD_OPT="$NGX_LD_OPT"

4.8、检查环境是否支持链接选项

使用auto/feature来检查$NGX_LD_OPT选项是否错误(前提是必须要有$NGX_LD_OPT不为空),auto/feature前面已经介绍很多了,这里就不赘述了。
代码如下:

if [ "$NGX_PLATFORM" != win32 ]; then

    if test -n "$NGX_LD_OPT"; then
        ngx_feature=--with-ld-opt=\\"$NGX_LD_OPT\\"
        ngx_feature_name=
        ngx_feature_run=no
        ngx_feature_incs=
        ngx_feature_path=
        ngx_feature_libs=
        ngx_feature_test=
        . auto/feature

        if [ $ngx_found = no ]; then
            echo $0: error: the invalid value in --with-ld-opt=\\"$NGX_LD_OPT\\"
            echo
            exit 1
        fi
    fi

4.9、检查环境是否支持-Wl -E选项

代码如下:

    ngx_feature="-Wl,-E switch"
    ngx_feature_name=
    ngx_feature_run=no
    ngx_feature_incs=
    ngx_feature_path=
    ngx_feature_libs=-Wl,-E
    ngx_feature_test=
    . auto/feature

    if [ $ngx_found = yes ]; then
        MAIN_LINK="-Wl,-E"
    fi

4.10、检查环境是否支持gcc的原子操作

代码如下:

    if [ "$NGX_CC_NAME" = "sunc" ]; then
        echo "checking for gcc builtin atomic operations ... disabled"
    else
        ngx_feature="gcc builtin atomic operations"
        ngx_feature_name=NGX_HAVE_GCC_ATOMIC
        ngx_feature_run=yes
        ngx_feature_incs=
        ngx_feature_path=
        ngx_feature_libs=
        ngx_feature_test="long  n = 0;
                          if (!__sync_bool_compare_and_swap(&n, 0, 1))
                              return 1;
                          if (__sync_fetch_and_add(&n, 1) != 1)
                              return 1;
                          if (n != 2)
                              return 1;
                          __sync_synchronize();"
        . auto/feature
    fi

4.11、检查环境是否支持C99的可变参宏

代码如下:

    if [ "$NGX_CC_NAME" = "ccc" ]; then
        echo "checking for C99 variadic macros ... disabled"
    else
        ngx_feature="C99 variadic macros"
        ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS"
        ngx_feature_run=yes
        ngx_feature_incs="#include <stdio.h>
#define var(dummy, ...)  sprintf(__VA_ARGS__)"
        ngx_feature_path=
        ngx_feature_libs=
        ngx_feature_test="char  buf[30]; buf[0] = '0';
                          var(0, buf, \\"%d\\", 1);
                          if (buf[0] != '1') return 1"
        . auto/feature
    fi

4.12、检查环境是否支持gcc的可变参宏

代码如下:

    ngx_feature="gcc variadic macros"
    ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS"
    ngx_feature_run=yes
    ngx_feature_incs="#include <stdio.h>
#define var(dummy, args...)  sprintf(args)"
    ngx_feature_path=
    ngx_feature_libs=
    ngx_feature_test="char  buf[30]; buf[0] = '0';
                      var(0, buf, \\"%d\\", 1);
                      if (buf[0] != '1') return 1"
    . auto/feature

4.13、检查环境是否支持gcc的64位的byteswap

代码如下:

    ngx_feature="gcc builtin 64 bit byteswap"
    ngx_feature_name="NGX_HAVE_GCC_BSWAP64"
    ngx_feature_run=no
    ngx_feature_incs=
    ngx_feature_path=
    ngx_feature_libs=
    ngx_feature_test="if (__builtin_bswap64(0)) return 1"
    . auto/feature

fi

5、auto/cc/gcc脚本文件详解

由于与平台相关的编译器的配置脚本比较多,这里就以最典型的auto/cc/gcc文件为例,讲解一下对gcc编译器的配置,其它脚本也是类似的,读者可以自行查阅。

5.1、输出当前编译器信息

将当前的gcc版本信息输出到控制台,然后调用auto/define将版本信息也输出到$NGX_AUTO_CONFIG_H文件中。
代码如下:

NGX_GCC_VER=`$CC -v 2>&1 | grep 'gcc version' 2>&1 \\
                         | sed -e 's/^.* version \\(.*\\)/\\1/'`

echo " + gcc version: $NGX_GCC_VER"

have=NGX_COMPILER value="\\"gcc $NGX_GCC_VER\\"" . auto/define

5.2、检查当前是否支持-pipe选项

检查当前是否支持-pipe选项,如果支持,则将PIPE的值设为-pipe
代码如下:

CC_TEST_FLAGS="-pipe"

ngx_feature="gcc -pipe switch"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test=
. auto/feature

CC_TEST_FLAGS=

if [ $ngx_found = yes ]; then
    PIPE="-pipe"
fi

5.3、根据NGX_MACHINE的值设置CFLAGS

代码如下:

case "$NGX_MACHINE" in

    sun4u | sun4v | sparc | sparc64 )
        # "-mcpu=v9" enables the "casa" assembler instruction
        CFLAGS="$CFLAGS -mcpu=v9"
    ;;

esac

5.4、设置gcc优化等级变量NGX_GCC_OPT

代码如下:

NGX_GCC_OPT="-O"

5.5、根据CPU类型设置部分变量

代码如下:

case $CPU in
    pentium)
        # optimize for Pentium and Athlon
        CPU_OPT="-march=pentium"
        NGX_CPU_CACHE_LINE=32
    ;;

    pentiumpro | pentium3)
        # optimize for Pentium Pro, Pentium II and Pentium III
        CPU_OPT="-march=pentiumpro"
        NGX_CPU_CACHE_LINE=32
    ;;

    pentium4)
        # optimize for Pentium 4, gcc 3.x
        CPU_OPT="-march=pentium4"
        NGX_CPU_CACHE_LINE=128
    ;;

    athlon)
        # optimize for Athlon, gcc 3.x
        CPU_OPT="-march=athlon"
        NGX_CPU_CACHE_LINE=64
    ;;

    opteron)
        # optimize for Opteron, gcc 3.x
        CPU_OPT="-march=opteron"
        NGX_CPU_CACHE_LINE=64
    ;;

    sparc32)
        # build 32-bit UltraSparc binary
        CPU_OPT="-m32"
        CORE_LINK="$CORE_LINK -m32"
        NGX_CPU_CACHE_LINE=64
    ;;

    sparc64)
        # build 64-bit UltraSparc binary
        CPU_OPT="-m64"
        CORE_LINK="$CORE_LINK -m64"
        NGX_CPU_CACHE_LINE=64
    ;;

    ppc64)
        # build 64-bit PowerPC binary
        CPU_OPT="-m64"
        CPU_OPT="$CPU_OPT -falign-functions=32 -falign-labels=32"
        CPU_OPT="$CPU_OPT -falign-loops=32 -falign-jumps=32"
        CORE_LINK="$CORE_LINK -m64"
        NGX_CPU_CACHE_LINE=128
    ;;

esac

CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT"

case "$NGX_GCC_VER" in
    2.7*)
        # batch build
        CPU_OPT=
    ;;
esac


CFLAGS="$CFLAGS $PIPE $CPU_OPT"

5.6、设置pcre和zlib的编译选项

代码如下:

if [ ".$PCRE_OPT" = "." ]; then
    PCRE_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT"
else
    PCRE_OPT="$PCRE_OPT $PIPE"
fi

if [ ".$ZLIB_OPT" = "." ]; then
    ZLIB_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT"
else
    ZLIB_OPT="$ZLIB_OPT $PIPE"
fi

5.7、设置编译警告选项

代码如下:

# warnings

# -W requires at least -O
CFLAGS="$CFLAGS ${NGX_GCC_OPT:--O} -W"

CFLAGS="$CFLAGS -Wall -Wpointer-arith"
#CFLAGS="$CFLAGS -Wconversion"
#CFLAGS="$CFLAGS -Winline"
#CFLAGS="$CFLAGS -Wmissing-prototypes"

case "$NGX_GCC_VER" in
    2.*)
        # we have a lot of the unused function arguments
        CFLAGS="$CFLAGS -Wno-unused"
    ;;

    *)
        # we have a lot of the unused function arguments
        CFLAGS="$CFLAGS -Wno-unused-parameter"
        # 4.2.1 shows the warning in wrong places
        #CFLAGS="$CFLAGS -Wunreachable-code"

        # deprecated system OpenSSL library on OS X
        if [ "$NGX_SYSTEM" = "Darwin" ]; then
            CFLAGS="$CFLAGS -Wno-deprecated-declarations"
        fi
    ;;
esac


# stop on warning
CFLAGS="$CFLAGS -Werror"

# debug
CFLAGS="$CFLAGS -g"

# DragonFly's gcc3 generates DWARF
#CFLAGS="$CFLAGS -g -gstabs"

if [ ".$CPP" = "." ]; then
    CPP="$CC -E"
fi

6、总结

本文主要介绍了与编译器配置相关的脚本,这些脚本是Nginx能够跨平台使用的功臣,其中的内容非常重要,希望读者能够好好研读一番这些文件。

以上是关于Nginx编译配置脚本篇- 编译器相关脚本的主要内容,如果未能解决你的问题,请参考以下文章

Nginx编译配置脚本篇- 系统环境相关脚本

Nginx编译配置脚本篇- 源码相关变量脚本auto/sources

Nginx编译配置脚本最终篇 - configure脚本

Nginx配置编译脚本篇- 解析配置选项脚本auto/options

Nginx编译配置脚本篇- 动态库配置脚本auto/lib/conf

Nginx编译配置脚本篇- Makefile初始化脚本auto/init