Nginx编译配置脚本篇- 编译器相关脚本
Posted 彼方丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx编译配置脚本篇- 编译器相关脚本相关的知识,希望对你有一定的参考价值。
nginx编译配置脚本篇(5)- 编译器相关脚本
1、相关文章
由于学习本文需要Nginx
源码及搭建相关的编译环境,且本文与前面的文章有先后呼应关系,所以建议大家按以下文章顺序阅读
- CentOS 7使用源码编译安装Nginx,以及配置使用autoindex模块
- Nginx配置编译脚本篇(1)- 解析配置选项脚本auto/options
- Nginx编译配置脚本篇(2)- Makefile初始化脚本auto/init
- Nginx编译配置脚本篇(3)- 源码相关变量脚本auto/sources
- Nginx编译配置脚本篇(4)- 工具型脚本系列
2、前言
auto/cc
目录下的所有脚本都是用于配置不同平台的编译器的。众所周知Nginx
具有出色的跨平台性能(Linux
、Darwin
、Solaris
、Win32
…),这些脚本在其中起到了巨大的作用。
脚本目录如下:
- 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_tab | TAB符号 |
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编译配置脚本篇- 源码相关变量脚本auto/sources
Nginx配置编译脚本篇- 解析配置选项脚本auto/options