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

Posted 彼方丶

tags:

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

1、相关文章

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

2、前言

本文将介绍与系统环境设置的相关脚本,这些脚本是放在auto/os/目录下的。

3、auto/os/conf脚本文件详解

3.1、输出当前操作系统名称(NGX_SYSTEM)

NGX_SYSTEM的值就是当前操作系统名称,是在configure文件里面设置的,这里先不分析这个,到最后分析configure文件时会说明的。
代码如下:

echo "checking for $NGX_SYSTEM specific features"

3.2、根据NGX_PLATFORM执行对应的脚本文件

NGX_PLATFORM的值就是系统信息,可以在auto/options文件里面设置(执行configure文件时传入参数加上–crossbuild=value),如果我们没有主动设置的话,NGX_SYSTEM的值就会在configure文件里面设置,这里先不分析这个,到最后分析configure文件时会说明的。
代码如下:

case "$NGX_PLATFORM" in

    FreeBSD:*)
        . auto/os/freebsd
    ;;

    Linux:*)
        . auto/os/linux
    ;;

    SunOS:*)
        . auto/os/solaris
    ;;

    Darwin:*)
        . auto/os/darwin
    ;;

    win32)
        . auto/os/win32
    ;;

    DragonFly:*)
        have=NGX_FREEBSD . auto/have_headers
        CORE_INCS="$UNIX_INCS"
        CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
        CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS"

        echo " + sendfile() found"
        have=NGX_HAVE_SENDFILE . auto/have
        CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"

        ngx_spacer='
'
    ;;

    NetBSD:*)
        CORE_INCS="$UNIX_INCS"
        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
        CORE_SRCS="$UNIX_SRCS"

        NGX_RPATH=YES
    ;;

    HP-UX:*)
        # HP/UX
        have=NGX_HPUX . auto/have_headers
        CORE_INCS="$UNIX_INCS"
        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
        CORE_SRCS="$UNIX_SRCS"
        CC_AUX_FLAGS="$CC_AUX_FLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
        CC_AUX_FLAGS="$CC_AUX_FLAGS -D_HPUX_ALT_XOPEN_SOCKET_API"
    ;;

    OSF1:*)
        # Tru64 UNIX
        have=NGX_TRU64 . auto/have_headers
        have=NGX_HAVE_STRERROR_R . auto/nohave
        CORE_INCS="$UNIX_INCS"
        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
        CORE_SRCS="$UNIX_SRCS"
    ;;

    GNU:*)
        # GNU Hurd
        have=NGX_GNU_HURD . auto/have_headers
        CORE_INCS="$UNIX_INCS"
        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
        CORE_SRCS="$UNIX_SRCS"
        CC_AUX_FLAGS="$CC_AUX_FLAGS -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
    ;;

    *)
        CORE_INCS="$UNIX_INCS"
        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
        CORE_SRCS="$UNIX_SRCS"
    ;;

esac

从代码中可以看出这里会根据系统的不同选择执行不同的脚本文件,后续会以最典型的Linux为例去讲解,其他脚本文件的执行原理也大致是相同的,读者可以自行查阅学习。

3.3、根据处理器的类型设置缓存行大小

首先根据处理器的不同往文件里面写入不同的宏定义和设置NGX_MACH_CACHE_LINE的大小,其次是先检查NGX_CPU_CACHE_LINE的值是否为空(该值是在设置编译器信息那里被设置的,详情看这篇文章 Nginx编译配置脚本篇(5)- 编译器相关脚本),为空的话就将NGX_MACH_CACHE_LINE的值赋给NGX_CPU_CACHE_LINE,最后使用auto/define脚本将宏定义信息写入$NGX_AUTO_CONFIG_H文件中,示例如下:

#ifndef NGX_CPU_CACHE_LINE
#define NGX_CPU_CACHE_LINE  64
#endif

代码如下:

case "$NGX_MACHINE" in

    i386 | i686 | i86pc)
        have=NGX_HAVE_NONALIGNED . auto/have
        NGX_MACH_CACHE_LINE=32
    ;;

    amd64 | x86_64)
        have=NGX_HAVE_NONALIGNED . auto/have
        NGX_MACH_CACHE_LINE=64
    ;;

    sun4u | sun4v | sparc | sparc64)
        have=NGX_ALIGNMENT value=16 . auto/define
        # TODO
        NGX_MACH_CACHE_LINE=64
    ;;

    ia64 )
        have=NGX_ALIGNMENT value=16 . auto/define
        # TODO
        NGX_MACH_CACHE_LINE=64
    ;;

    aarch64 )
        have=NGX_ALIGNMENT value=16 . auto/define
        NGX_MACH_CACHE_LINE=64
    ;;

    *)
        have=NGX_ALIGNMENT value=16 . auto/define
        NGX_MACH_CACHE_LINE=32
    ;;

esac

if test -z "$NGX_CPU_CACHE_LINE"; then
    NGX_CPU_CACHE_LINE=$NGX_MACH_CACHE_LINE
fi

have=NGX_CPU_CACHE_LINE value=$NGX_CPU_CACHE_LINE . auto/define

4、auto/os/linux脚本文件详解

4.1、写入当前系统类型到头文件

使用auto/have_headers将宏定义写入$NGX_AUTO_HEADERS_H文件。
代码如下:

have=NGX_LINUX . auto/have_headers

4.2、设置与Makefile相关变量

代码如下:

CORE_INCS="$UNIX_INCS"
CORE_DEPS="$UNIX_DEPS $LINUX_DEPS"
CORE_SRCS="$UNIX_SRCS $LINUX_SRCS"

4.3、设置分行符(ngx_spacer)

在之前这篇文章 Nginx编译配置脚本篇(5)- 编译器相关脚本 中曾经提到过ngx_spacer这个
变量,当时这个变量还没赋值,就先认定他是个空内容符号了,其实从这里初始化之后可以看出,这其实是一个分行符,用于将两个变量隔开一行,使文件结构更好看。
代码如下:

ngx_spacer='
'

4.4、设置Linux内核版本相关信息

代码如下:

version=$((`uname -r \\
    | sed -n -e 's/^\\([0-9][0-9]*\\)\\.\\([0-9][0-9]*\\)\\.\\([0-9][0-9]*\\).*/ \\
                                                 \\1*256*256+\\2*256+\\3/p' \\
             -e 's/^\\([0-9][0-9]*\\)\\.\\([0-9][0-9]*\\).*/\\1*256*256+\\2*256/p'`))

version=${version:-0}


# posix_fadvise64() had been implemented in 2.5.60

if [ $version -lt 132412 ]; then
    have=NGX_HAVE_POSIX_FADVISE . auto/nohave
fi

4.5、设置epoll相关信息

  • 使用auto/feature检查当前是否支持epoll,支持的话将NGX_HAVE_EPOLL宏和NGX_HAVE_CLEAR_EVENT宏写入$NGX_AUTO_CONFIG_H文件,然后在$CORE_SRCS后添加$EPOLL_SRCSsrc/event/modules/ngx_epoll_module.c),在$EVENT_MODULES后添加$EPOLL_MODULEngx_epoll_module)。
  • 如果当前支持epoll的话,检查是否支持EPOLLRDHUP参数,支持的话将NGX_HAVE_EPOLLRDHUP宏入$NGX_AUTO_CONFIG_H文件
  • 如果当前支持epoll的话,检查是否支持EPOLLEXCLUSIVE参数,支持的话将NGX_HAVE_EPOLLEXCLUSIVE宏入$NGX_AUTO_CONFIG_H文件

代码如下:

ngx_feature="epoll"
ngx_feature_name="NGX_HAVE_EPOLL"
ngx_feature_run=yes
ngx_feature_incs="#include <sys/epoll.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="int efd = 0;
                  struct epoll_event ee;
                  ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
                  ee.data.ptr = NULL;
                  (void) ee;
                  efd = epoll_create(100);
                  if (efd == -1) return 1;"
. auto/feature

if [ $ngx_found = yes ]; then
    have=NGX_HAVE_CLEAR_EVENT . auto/have
    CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
    EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
    EVENT_FOUND=YES


    # EPOLLRDHUP appeared in Linux 2.6.17, glibc 2.8

    ngx_feature="EPOLLRDHUP"
    ngx_feature_name="NGX_HAVE_EPOLLRDHUP"
    ngx_feature_run=no
    ngx_feature_incs="#include <sys/epoll.h>"
    ngx_feature_path=
    ngx_feature_libs=
    ngx_feature_test="int efd = 0, fd = 0;
                      struct epoll_event ee;
                      ee.events = EPOLLIN|EPOLLRDHUP|EPOLLET;
                      ee.data.ptr = NULL;
                      epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
    . auto/feature


    # EPOLLEXCLUSIVE appeared in Linux 4.5, glibc 2.24

    ngx_feature="EPOLLEXCLUSIVE"
    ngx_feature_name="NGX_HAVE_EPOLLEXCLUSIVE"
    ngx_feature_run=no
    ngx_feature_incs="#include <sys/epoll.h>"
    ngx_feature_path=
    ngx_feature_libs=
    ngx_feature_test="int efd = 0, fd = 0;
                      struct epoll_event ee;
                      ee.events = EPOLLIN|EPOLLEXCLUSIVE;
                      ee.data.ptr = NULL;
                      epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
    . auto/feature
fi

4.6、设置openat函数相关信息

检查当前环境下的openat是否支持O_PATH参数,支持的话将NGX_HAVE_O_PATH宏入$NGX_AUTO_CONFIG_H文件
代码如下:

ngx_feature="O_PATH"
ngx_feature_name="NGX_HAVE_O_PATH"
ngx_feature_run=no
ngx_feature_incs="#include <sys/types.h>
                  #include <sys/stat.h>
                  #include <fcntl.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="int fd; struct stat sb;
                  fd = openat(AT_FDCWD, \\".\\", O_PATH|O_DIRECTORY|O_NOFOLLOW);
                  if (fstatat(fd, \\"\\", &sb, AT_EMPTY_PATH) != 0) return 1"
. auto/feature

4.7、设置sendfile函数相关信息

检查当前环境是否支持sendfile函数,支持的话写入相关的宏。
代码如下:

# sendfile()

CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE"
ngx_feature="sendfile()"
ngx_feature_name="NGX_HAVE_SENDFILE"
ngx_feature_run=yes
ngx_feature_incs="#include <sys/sendfile.h>
                  #include <errno.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="int s = 0, fd = 1;
                  ssize_t n; off_t off = 0;
                  n = sendfile(s, fd, &off, 1);
                  if (n == -1 && errno == ENOSYS) return 1"
. auto/feature

if [ $ngx_found = yes ]; then
    CORE_SRCS="$CORE_SRCS $LINUX_SENDFILE_SRCS"
fi


# sendfile64()

CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
ngx_feature="sendfile64()"
ngx_feature_name="NGX_HAVE_SENDFILE64"
ngx_feature_run=yes
ngx_feature_incs="#include <sys/sendfile.h>
                  #include <errno.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="int s = 0, fd = 1;
                  ssize_t n; off_t off = 0;
                  n = sendfile(s, fd, &off, 1);
                  if (n == -1 && errno == ENOSYS) return 1"
. auto/feature

4.8、设置prctl函数相关信息

检查当前环境是否支持prctl函数,支持的话写入相关的宏。
代码如下:

ngx_include="sys/prctl.h"; . auto/include

# prctl(PR_SET_DUMPABLE)

ngx_feature="prctl(PR_SET_DUMPABLE)"
ngx_feature_name="NGX_HAVE_PR_SET_DUMPABLE"
ngx_feature_run=yes
ngx_feature_incs="#include <sys/prctl.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) return 1"
. auto/feature


# prctl(PR_SET_KEEPCAPS)

ngx_feature="prctl(PR_SET_KEEPCAPS)"
ngx_feature_name="NGX_HAVE_PR_SET_KEEPCAPS"
ngx_feature_run=yes
ngx_feature_incs="#include <sys/prctl.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) return 1"
. auto/feature

4.9、设置capability相关信息

检查当前环境是否支持capability.h头文件的一系列操作,支持的话写入相关的宏。
代码如下:

ngx_feature="capabilities"
ngx_feature_name="NGX_HAVE_CAPABILITIES"
ngx_feature_run=no
ngx_feature_incs="#include <linux/capability.h>
                  #include <sys/syscall.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="struct __user_cap_data_struct    data;
                  struct __user_cap_header_struct  header;

                  header.version = _LINUX_CAPABILITY_VERSION_1;
                  data.effective = CAP_TO_MASK(CAP_NET_RAW);
                  data.permitted = 0;

                  (void) header;
                  (void) data;
                  (void) SYS_capset"
. auto/feature

4.10、设置crypt_r函数相关信息

检查当前环境是否支持crypt_r函数,支持的话写入相关的宏。
代码如下:

ngx_feature="crypt_r()"
ngx_feature_name="NGX_HAVE_GNU_CRYPT_R"
ngx_feature_run=no
ngx_feature_incs="#include <crypt.h>"
ngx_feature_path=
ngx_feature_libs=-lcrypt
ngx_feature_test="struct crypt_data  cd;
                  crypt_r(\\"key\\", \\"salt\\", &cd);"
. auto/feature

4.11、检查是否支持sys/vfs.h头文件

使用auto/include脚本来检查当前环境是否支持sys/vfs.h头文件,auto/include的内容与auto/feature的内容非常相似,而且还简单了一些,所以这里也就不重复讲解了,读者可以自行查看该文件的内容。
代码如下:

ngx_include="sys/vfs.h";     . auto/include

4.12、设置CC_AUX_FLAGS变量

代码如下:

CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"

5、总结

本文介绍了与系统环境相关的脚本文件,先是介绍了auto/os/conf文件,该文件调用了根据当前系统环境选择执行对应的脚本文件,并设置了缓存行的大小。然后以auto/os/linux文件为例,介绍了该文件所做的工作,包括验证环境是否支持epoll、是否支持crypt_r函数等等。其他特化的与系统环境相关的脚本的内容也是大致相同的。

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

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

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

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

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

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

Nginx编译配置脚本篇(10)- Makefile相关脚本