nginx中的configure脚本

1.简介

本文主要是为了解读configure脚本做了什么,我将对configure脚本分成多个块进行解析,主要是解读shell脚本代码,注意作者的系统是ubuntu19,可能提到的作者所写的部分代码在Windows下无法运行,另外如果有读者不懂shell编程,也可以阅读此文,我将会尽可能的将这些内容讲的更通俗,因此可能会稍微啰嗦一点。这里初步说明configure主要用于干嘛的,它主要和make工具一起使用,检查了各种系统参数,命令行参数和依赖库,然后根据这些参数生成定制的Makefile和一些C源文件,如果没有它就无法正确安装Nginx。

2.介绍

I.

LC_ALL=C
export LC_ALL

. auto/options 
. auto/init
. auto/sources

test -d $NGX_OBJS || mkdir -p $NGX_OBJS

echo > $NGX_AUTO_HEADERS_H
echo > $NGX_AUTOCONF_ERR

echo "#define NGX_CONFIGURE "$NGX_CONFIGURE"" > $NGX_AUTO_CONFIG_H
LC_ALL=C去除所有本地化的设置,让命令能正确执行。LC_ALL是一个宏,如果该值设置了,则该值会覆盖所有LC_*的设置值,但要注意的是LANG的值不受该宏影响。那么啥叫本地化设置呢?你可以在terminal中使用locale命令,就可以看到一系列的LC_*,根据
英文单词大概就知道它们是设置啥的。
至于下面的. auto/*,第一个options主要是解析参数,设置配置变量,例如我们随后提到的$NGX_OBJS(这是一个变量),在此脚本中设置为了objs,当然这个变量也受到了用户指定参数的影响。第二个init设置了少量的变量,
主要和创建的文件名有关,在此脚本中还直接创建了一个Makefile文件。
至于第三个sources也是初始化变量,这些变量主要和源代码的路径相关。后面的test主要是测试是否已经存在$NGX_OBJS这样一个目录,如果不存在那么重新创建新的目录,名为$NGX_OBJS
变量的值。后三行代码分别创建了ngx_auto_headers.h,ngx_autoconf.err,ngx_auto_config.h,它们均
创建在名为$NGX_OBJS变量值的目录中,并且向ngx_auto_config.h文件输出了一个#define NGX_CONFIGURE $NGX_CONFIGURE,注意也是该变量
的值,比如如果指定了$NGX_CONFIGURE="123",则该语句为#define NGX_CONFIGURE "123",此后部分不再如此详细,你只需要注意$a实际上是
取变量名为a中的值即可,a="123"即是将变量a赋值为"123",另外shell中没有常量的概念,一般利用全大写表明
一个常量。
II.
if [ $NGX_DEBUG = YES ]; then
    have=NGX_DEBUG . auto/have
fi


if test -z "$NGX_PLATFORM"; then
    echo "checking for OS"

    NGX_SYSTEM=`uname -s 2>/dev/null`
    NGX_RELEASE=`uname -r 2>/dev/null`
    NGX_MACHINE=`uname -m 2>/dev/null`

    echo " + $NGX_SYSTEM $NGX_RELEASE $NGX_MACHINE"

    NGX_PLATFORM="$NGX_SYSTEM:$NGX_RELEASE:$NGX_MACHINE";

    case "$NGX_SYSTEM" in
        MINGW32_* | MINGW64_* | MSYS_*)
            NGX_PLATFORM=win32
        ;;
    esac

else
    echo "building for $NGX_PLATFORM"
    NGX_SYSTEM=$NGX_PLATFORM
fi

. auto/cc/conf

if [ "$NGX_PLATFORM" != win32 ]; then
    . auto/headers
fi

. auto/os/conf

if [ "$NGX_PLATFORM" != win32 ]; then
    . auto/unix
fi

. auto/threads
. auto/modules
. auto/lib/conf

第二部分有点多建议直接打开configure脚本文件查看。if是shell中的判断语句,它以fi作为结尾。

第一个if很简单,即判断是否是指定了debug,如果指定了即执行auto/have脚本,为了看到具体结果,我们可以尝试自己加入一个test_configure文件,对每一个块进行执行,这里我们在该if语句前加入NGX_DEBUG=YES,可以看到的是我们将have设置为了NGX_DEBUG,在ngx_auto_config.h文件中追加了一段类似C语言的预编译语句#ifndef,该语句主要是检查是否定义了NGX_DEBUG宏,如果未定义即将其定义为1。

第二个if先测试$NGX_PLATFORM的长度是否为0,为0则设置NGX_SYSTEM,NGX_RELEASE,NGX_MACHINE,在我的系统上运行上述uname命令,这三个值分别为Linux,5.0.0-36-generic,x86_64,设置NGX_PLATFORM="Linux:5.0.0-36-generic-x86_64",此后会特别检查Windows版本,如果是Windows系统则将NGX_PLATFORM=win32,如果不为0则直接设置NGX_SYSTEM。

. auto/cc/conf执行conf脚本,这个不具体介绍,这里仅说明这个脚本主要用于设置编译器类型,例如我们所熟知的gcc,msvc等。

第三个if比较重要,如果当前系统不是Windows版本的,那么就执行headers脚本,而这个headers很有意义,它包含了那些符合unix标准下可用的一系列文件,例如unistd.h。

第四个if也很重要,如果当前系统不是Windows版本,则执行unix脚本,测试各类事件驱动的可用性,例如poll,epoll,对于符合unix标准下的不同系统,同样要有区别,有些系统并不支持epoll这样的函数,你可以按照我上面所说的加入一个自己的configure参数,测试下这两段代码,这这两个脚本向ngx_auto_config.h,ngx_auto_heads.h文件追加了一系列内容,此时我们就可以知道创建的这些文件意义所在了,其中autoconf.err文件记录在执行configure脚本时所发生的错误,ngx_auto_config.h中包含了我们特别制定的一些特性(或者是nginx默认的一些特性),ngx_auto_heads.h文件记录了我们可以使用的一系列文件。

threads脚本,如果指定了使用threads则我们会使用have脚本向ngx_auto_config.h文件中加入宏定义NGX_THREADS,其值为1,本文此后提及到利用have都是向ngx_auto_config.h文件中加入宏定义,如有特殊情况则会说明。

modules脚本,这个脚本是添加自定义模块的关键,该脚本将会创建一个新文件ngx_modules.c,这个文件声明了各种模块变量,以及它们的名字。

lib目录下的conf脚本,这个脚本主要是解决那些依赖库的宏定义,是否需要使用某些库,例如PCRE,这是一个正则表达式库。

III

if [ ".$NGX_CONF_PREFIX" != "." ]; then
    have=NGX_CONF_PREFIX value=""$NGX_CONF_PREFIX/"" . auto/define
fi

have=NGX_SBIN_PATH value=""$NGX_SBIN_PATH"" . auto/define
have=NGX_CONF_PATH value=""$NGX_CONF_PATH"" . auto/define
have=NGX_PID_PATH value=""$NGX_PID_PATH"" . auto/define
have=NGX_LOCK_PATH value=""$NGX_LOCK_PATH"" . auto/define
have=NGX_ERROR_LOG_PATH value=""$NGX_ERROR_LOG_PATH"" . auto/define

have=NGX_HTTP_LOG_PATH value=""$NGX_HTTP_LOG_PATH"" . auto/define
have=NGX_HTTP_CLIENT_TEMP_PATH value=""$NGX_HTTP_CLIENT_TEMP_PATH""
. auto/define
have=NGX_HTTP_PROXY_TEMP_PATH value=""$NGX_HTTP_PROXY_TEMP_PATH""
. auto/define
have=NGX_HTTP_FASTCGI_TEMP_PATH value=""$NGX_HTTP_FASTCGI_TEMP_PATH""
. auto/define
have=NGX_HTTP_UWSGI_TEMP_PATH value=""$NGX_HTTP_UWSGI_TEMP_PATH""
. auto/define
have=NGX_HTTP_SCGI_TEMP_PATH value=""$NGX_HTTP_SCGI_TEMP_PATH""
. auto/define

第三部分

这部分主要是配置各种路径,这一部分不再讲解每一段代码,而是直接介绍变量意义。

$NGX_PREFIX用于设置nginx配置文件所放的目录,一般而言都是usr/local/nginx。至于define脚本和have脚本非常类似,have脚本是根据变量have来设置宏的名字,其值为1,实际上相当于一个标志位,而define则是根据have设置宏的名字,其值为变量value的值。

IV

. auto/make
. auto/lib/make
. auto/install

# STUB
. auto/stubs

have=NGX_USER value=""$NGX_USER"" . auto/define
have=NGX_GROUP value=""$NGX_GROUP"" . auto/define

if [ ".$NGX_BUILD" != "." ]; then
    have=NGX_BUILD value=""$NGX_BUILD"" . auto/define
fi

. auto/summary

第四部分

make脚本创建了objs目录下的Makefile文件,src目录以及各种目录,注意此时src目录下并没有文件,而lib目录下的make脚本也是创建和外部库相关的目录以及文件。

install脚本向objs目录下的Makefile文件追加一些与安装编译nginx相关内容,此外会向当前目录下的Makefile追加如何安装,更新等。

后续的stub仅是一段占坑脚本。。而最后的summary会在控制台输出一系列相关安装信息。

3.总结

到此整个configure脚本就差不多了,本文并没有具体讲述configure中所调用的其他脚本,这些脚本要么是为了创建必要的文件,要么是为了设置一些特定的配置,最后生成了一个Makefile文件,这个文件用于构建nginx。最后执行完configure脚本,只需要使用make && make install 即可安装nginx,此时的make相当于make -f objs/Makefile,make install相当于make -f objs/Makefile install。

原文地址:https://www.cnblogs.com/zhuiyicc/p/11907760.html