由于学习本文需要Nginx
源码及搭建相关的编译环境,且本文与前面的文章有先后呼应关系,所以建议大家按以下文章顺序阅读
本文将介绍与Makefile
相关的几个脚本文件,之前文章中讲到的那些没被使用的变量也会在这里被悉数使用,因为configure
基本是在最末尾调用这些脚本的,所有之前没用到的有效信息理所当然得在这里使用。
从auto/init
脚本中可以知道NGX_MAKEFILE
的值为objs/Makefile
。
代码如下:
echo "creating $NGX_MAKEFILE"
从auto/options
脚本中可以知道NGX_OBJS
的默认值为objs
,这段代码就是要在objs/
目录里创建存放编译产生的目标文件的目录
代码如下:
mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \
$NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \
$NGX_OBJS/src/http $NGX_OBJS/src/http/v2 $NGX_OBJS/src/http/modules \
$NGX_OBJS/src/http/modules/perl \
$NGX_OBJS/src/mail \
$NGX_OBJS/src/stream \
$NGX_OBJS/src/misc
从这篇文章 Nginx编译配置脚本篇(5)- 编译器相关脚本 中可以知道ngx_regex_dirsep
是正则表达式中的目录分隔符,gcc
编译器下该值为/
,则ngx_objs_dir
展开之后为objs/
,ngx_use_pch
的值不用理会,对于大部分编译器来说这个值没用。
代码如下:
ngx_objs_dir=$NGX_OBJS$ngx_regex_dirsep
ngx_use_pch=`echo $NGX_USE_PCH | sed -e "s/\//$ngx_regex_dirsep/g"`
代码如下:
cat << END > $NGX_MAKEFILE
CC = $CC
CFLAGS = $CFLAGS
CPP = $CPP
LINK = $LINK
END
这里创建了objs/Makefile
文件,并往里面写入了与编译参数相关的信息,以gcc
为例,最终生成到objs/Makefile
文件里的内容如下:
CC = cc
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g
CPP = cc -E
LINK = $(CC)
这段不是重要内容,忽略
代码如下:
if test -n "$NGX_PERL_CFLAGS"; then
echo NGX_PERL_CFLAGS = $NGX_PERL_CFLAGS >> $NGX_MAKEFILE
echo NGX_PM_CFLAGS = $NGX_PM_CFLAGS >> $NGX_MAKEFILE
echo NGX_PM_LDFLAGS = $NGX_PM_LDFLAGS >> $NGX_MAKEFILE
fi
ALL_INCS
的作用是指定Nginx
通用头文件所在目录,代码里面使用到了CORE_INCS
、NGX_OBJS
、HTTP_INCS
、MAIL_INCS
、STREAM_INCS
,这些都是之前auto/modules
和auto/lib/conf
里生成的变量,在这里终于将它们写入到objs/Makefile
文件中了。ngx_include_opt
的值为-I
,在这篇文章 Nginx编译配置脚本篇(5)- 编译器相关脚本 中有讲到,这是gcc
一个指定头文件路径的参数ngx_regex_cont
在编译器相关脚本那篇文章中有讲述,值为 空格++换行符+TABngx_incs
变量的那个echo
会将CORE_INCS
等变量的内容输出出来,输出的形式为一系列以空格为分隔的字符串sed
正则语句的意思是匹配输出语句中除了第一个之外的全部字符串,然后在他们前面加上$ngx_regex_cont$ngx_include_opt
,第一段正则语句 *\([^ ][^ ]*\)
会匹配到除了第一个字符串以外的内容,在sed
正则中,括号表示一个整体,所以在后面的$ngx_regex_cont$ngx_include_opt\1
里的\1
指的就是前面括号匹配到的内容。这个可以讲起来比较晦涩难懂,读者可以自行去自行建个脚本去实验一下,或者去百度查一下正则相关的内容ngx_regex_dirsep
是正则语句中的目录分隔符(在这篇文章 Nginx编译配置脚本篇(5)- 编译器相关脚本 中有介绍),我们知道不同系统的目录分隔符是有可能不同的,比如Windows
下的目录分隔符是\
,而Linux
下的是/
。sed
正则语句的意思就是将目录分隔符替换为当前平台支持的分隔符,因为我们之前的脚本设置的分隔符都是Linux
风格的,这样在Windows
系统编译就肯定不行了,ngx_regex_dirsep
变量就是为了应对这些情况的,比如ngx_regex_dirsep
在Windows
下的值为\\
,Linux
下的值就为\/
(多一个反斜杠是因为用于sed
正则里,需要转义)代码如下:
ngx_incs=`echo $CORE_INCS $NGX_OBJS $HTTP_INCS $MAIL_INCS $STREAM_INCS\
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
cat << END >> $NGX_MAKEFILE
ALL_INCS = $ngx_include_opt$ngx_incs
END
展开ALL_INCS = $ngx_include_opt$ngx_incs
后的内容如下,可以看到和前面分析的是一致的
ALL_INCS = -I src/core \
-I src/event \
-I src/event/modules \
-I src/os/unix \
-I objs \
-I src/http \
-I src/http/modules
CORE_DEPS
的作用是指定Nginx
核心代码头文件路径,代码里面使用到了CORE_DEPS
、NGX_AUTO_CONFIG_H
、NGX_PCH
,这些都是在之前讲过的那些脚本文件里面被赋值的,在这里终于将它们写入到objs/Makefile
文件中了CORE_INCS
的作用是指定Nginx
核心代码头文件所在目录,代码里面使用到了CORE_INCS
、NGX_OBJS
,这些都是在之前讲过的那些脚本文件里面被赋值的,在这里终于将它们写入到objs/Makefile
文件中了代码如下:
ngx_all_srcs="$CORE_SRCS"
ngx_deps=`echo $CORE_DEPS $NGX_AUTO_CONFIG_H $NGX_PCH \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
ngx_incs=`echo $CORE_INCS $NGX_OBJS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
cat << END >> $NGX_MAKEFILE
CORE_DEPS = $ngx_deps
CORE_INCS = $ngx_include_opt$ngx_incs
END
展开后的内容如下:
CORE_DEPS = src/core/nginx.h \
src/core/ngx_config.h \
src/core/ngx_core.h \
...
objs/ngx_auto_config.h
CORE_INCS = -I src/core \
-I src/event \
-I src/event/modules \
-I src/os/unix \
-I objs
接下来的一大段内容是将各个模块的头文件路径和头文件所在目录输出到objs/Makefile文件中(前提是该模块已经被启用),比如http
、mail
、stream
等模块,代码和前面的基本一致,这里就只贴出http
的代码,其余的读者可以自行去阅读源代码
代码如下:
if [ $HTTP = YES ]; then
ngx_all_srcs="$ngx_all_srcs $HTTP_SRCS"
ngx_deps=`echo $HTTP_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
ngx_incs=`echo $HTTP_INCS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
cat << END >> $NGX_MAKEFILE
HTTP_DEPS = $ngx_deps
HTTP_INCS = $ngx_include_opt$ngx_incs
END
fi
输出到objs/Makefile
的内容如下:
HTTP_DEPS = src/http/ngx_http.h \
src/http/ngx_http_request.h \
src/http/ngx_http_config.h \
src/http/ngx_http_core_module.h \
src/http/ngx_http_cache.h \
src/http/ngx_http_variables.h \
src/http/ngx_http_script.h \
src/http/ngx_http_upstream.h \
src/http/ngx_http_upstream_round_robin.h \
src/http/modules/ngx_http_ssi_filter_module.h
HTTP_INCS = -I src/http \
-I src/http/modules
这里需要先了解一下另一个变量ngx_all_srcs
,这个变量主要存放了的是源文件路径,是在之前设置的,读者可以自行去auto/make
脚本里面看一下ngx_all_srcs
的值都有什么,最后再使用ngx_all_srcs
之前,用下面的代码将目录分隔符替换为当前平台支持的分隔符,这个语句前面已经讲过了,这里就不赘述了
ngx_all_srcs=`echo $ngx_all_srcs | sed -e "s/\//$ngx_regex_dirsep/g"`
生成ngx_all_objs
的代码如下:
ngx_all_objs=`echo $ngx_all_srcs \
| sed -e "s#\([^ ]*\.\)cpp#$NGX_OBJS\/\1$ngx_objext#g" \
-e "s#\([^ ]*\.\)cc#$NGX_OBJS\/\1$ngx_objext#g" \
-e "s#\([^ ]*\.\)c#$NGX_OBJS\/\1$ngx_objext#g" \
-e "s#\([^ ]*\.\)S#$NGX_OBJS\/\1$ngx_objext#g"`
里面的正则和之前看到的那些不同,用#
来做字符串的分隔符,也是可以的,/
、@
、#
三个都可以,这里使用#
是为了防止和目录分隔符产生冲突。上面的正则的意思就是将文件名的后缀改为ngx_objext
的值(这个值是在设置编译器的脚本那里设置的,默认是o
),然后在文件路径开头加上objs/
,所以这里替换前后的内容举例如下:
替换前
ngx_all_srcs = src/core/nginx.c src/core/ngx_log.c src/core/ngx_palloc.c ...
替换后
ngx_all_objs = objs/src/core/nginx.o objs/src/core/ngx_log.o objs/src/core/ngx_palloc.o ...
这些变量的生成方式和前面讲的那些差不多,读者可以自行看一下,这里就不赘述了
代码如下:
ngx_modules_c=`echo $NGX_MODULES_C | sed -e "s/\//$ngx_regex_dirsep/g"`
ngx_modules_obj=`echo $ngx_modules_c | sed -e "s/\(.*\.\)c/\1$ngx_objext/"`
if test -n "$NGX_RES"; then
ngx_res=$NGX_RES
else
ngx_res="$NGX_RC $NGX_ICONS"
ngx_rcc=`echo $NGX_RCC | sed -e "s/\//$ngx_regex_dirsep/g"`
fi
ngx_deps=`echo $ngx_all_objs $ngx_modules_obj $ngx_res $LINK_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
ngx_objs=`echo $ngx_all_objs $ngx_modules_obj \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
ngx_libs=
if test -n "$NGX_LD_OPT$CORE_LIBS"; then
ngx_libs=`echo $NGX_LD_OPT $CORE_LIBS \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`
fi
ngx_link=${CORE_LINK:+`echo $CORE_LINK \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
ngx_main_link=${MAIN_LINK:+`echo $MAIN_LINK \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
代码如下:
cat << END >> $NGX_MAKEFILE
build: binary modules manpage
binary: $NGX_OBJS${ngx_dirsep}nginx$ngx_binext
$NGX_OBJS${ngx_dirsep}nginx$ngx_binext: $ngx_deps$ngx_spacer
\$(LINK) $ngx_long_start$ngx_binout$NGX_OBJS${ngx_dirsep}nginx$ngx_binext$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link
$ngx_rcc
$ngx_long_end
modules:
END
从代码中可以看到,这里生成了build
、binary
和$NGX_OBJS${ngx_dirsep}nginx$ngx_binext
三个目标,前两个比较简单就不讲了,$NGX_OBJS${ngx_dirsep}nginx$ngx_binext
这个目标比较重要,他是生成最终文件可执行文件的目标,他依赖于ngx_deps
这个变量(该变量存储了前面生成的所有目标文件),然后使用$LINK
(值是cc
)来链接生成最终的目标文件,其中动态链接了一些库,以及加了一些额外的编译参数,最终生成在objs/Makefile
中的代码如下:
build: binary modules manpage
binary: objs/nginx
objs/nginx: objs/src/core/nginx.o \
objs/src/core/ngx_log.o \
objs/src/core/ngx_palloc.o \
...
objs/ngx_modules.o
$(LINK) -o objs/nginx \
objs/src/core/nginx.o \
objs/src/core/ngx_log.o \
objs/src/core/ngx_palloc.o \
...
objs/ngx_modules.o \
-ldl -lpthread -lcrypt -lpcre -lz \
-Wl,-E
上以小节介绍了生成最终可执行文件的语句,该语句依赖于其他很多的子目标,这些子目标也是需要单独编译生成的。接下来的一大段代码就是与这些子目标相关的,由于内容过多这里就不全部贴出来了,有兴趣的读者可以自行去源代码中阅读相关的内容
示例代码如下:
for ngx_src in $CORE_SRCS
do
ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
ngx_obj=`echo $ngx_src \
| sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
-e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
-e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
-e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
cat << END >> $NGX_MAKEFILE
$ngx_obj: \$(CORE_DEPS)$ngx_cont$ngx_src
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
END
done
由于里面有个for
循环,所以他会遍历CORE_SRCS
的内容,生成每一个源文件转换为目标文件的编译语句,代码展开如下:
objs/ngx_modules.o: $(CORE_DEPS) \
objs/ngx_modules.c
$(CC) -c $(CFLAGS) $(CORE_INCS) \
-o objs/ngx_modules.o \
objs/ngx_modules.c
objs/src/core/nginx.o: $(CORE_DEPS) \
src/core/nginx.c
$(CC) -c $(CFLAGS) $(CORE_INCS) \
-o objs/src/core/nginx.o \
src/core/nginx.c
objs/src/core/ngx_log.o: $(CORE_DEPS) \
src/core/ngx_log.c
$(CC) -c $(CFLAGS) $(CORE_INCS) \
-o objs/src/core/ngx_log.o \
src/core/ngx_log.c
...
objs/src/core/ngx_regex.o: $(CORE_DEPS) \
src/core/ngx_regex.c
$(CC) -c $(CFLAGS) $(CORE_INCS) \
-o objs/src/core/ngx_regex.o \
src/core/ngx_regex.c
本节讲解了auto/make
脚本的内容,从上面的分析中我们可以知道最终生成的objs/Makefile
文件里的绝大部分内容都来自于auto/make
脚本,建议读者自行阅读该脚本时,先执行配置文件生成最终的objs/Makefile
文件,然后对比着去看auto/make
脚本的内容,这样理解起来会很快,因为没有Shell
编程基础看起来会比较费劲。
auto/lib/make
内容如下:
if [ $PCRE != NONE -a $PCRE != NO -a $PCRE != YES ]; then
. auto/lib/pcre/make
fi
if [ $OPENSSL != NONE -a $OPENSSL != NO -a $OPENSSL != YES ]; then
. auto/lib/openssl/make
fi
if [ $ZLIB != NONE -a $ZLIB != NO -a $ZLIB != YES ]; then
. auto/lib/zlib/make
fi
if [ $NGX_LIBATOMIC != NO -a $NGX_LIBATOMIC != YES ]; then
. auto/lib/libatomic/make
fi
if [ $USE_PERL != NO ]; then
. auto/lib/perl/make
fi
可以看到该脚本并不直接起作用,而是调用子目录的脚本去实现对应的功能的,子目录的那些脚本就是将对应第三方库的链接信息写入objs/Makefile
文件中,这里就不展开讲了,这些不是很重要的内容,有兴趣的读者可以自行去看一下这些脚本。
代码如下:
if [ $USE_PERL != NO ]; then
cat << END >> $NGX_MAKEFILE
install_perl_modules:
cd $NGX_OBJS/src/http/modules/perl && \$(MAKE) install
END
NGX_INSTALL_PERL_MODULES=install_perl_modules
fi
NGX_PREFIX
的值是在auto/options
里面根据我们的传入参数设置的,如果我们没有主动设置的话,则会在configure
中设置为默认值/usr/local/nginx
。下面的代码就是根据各个路径参数的值去设置对应的信息,如果路径参数是以./
开头的(相对路径),则不对其进行修改,否则在其前面加上NGX_PREFIX
的值
case ".$NGX_SBIN_PATH" in
./*)
;;
*)
NGX_SBIN_PATH=$NGX_PREFIX/$NGX_SBIN_PATH
;;
esac
case ".$NGX_MODULES_PATH" in
./*)
;;
*)
NGX_MODULES_PATH=$NGX_PREFIX/$NGX_MODULES_PATH
;;
esac
NGX_MODULES_PATH=`dirname $NGX_MODULES_PATH/.`
case ".$NGX_CONF_PATH" in
./*)
;;
*)
NGX_CONF_PATH=$NGX_PREFIX/$NGX_CONF_PATH
;;
esac
NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
case ".$NGX_PID_PATH" in
./*)
;;
*)
NGX_PID_PATH=$NGX_PREFIX/$NGX_PID_PATH
;;
esac
case ".$NGX_ERROR_LOG_PATH" in
./* | .)
;;
*)
NGX_ERROR_LOG_PATH=$NGX_PREFIX/$NGX_ERROR_LOG_PATH
;;
esac
case ".$NGX_HTTP_LOG_PATH" in
./*)
;;
*)
NGX_HTTP_LOG_PATH=$NGX_PREFIX/$NGX_HTTP_LOG_PATH
;;
esac
代码如下:
if test -f man/nginx.8 ; then
NGX_MAN=man/nginx.8
else
NGX_MAN=docs/man/nginx.8
fi
if test -d html ; then
NGX_HTML=html
else
NGX_HTML=docs/html
fi
这部分内容不重要,了解就行,主要是为了生成man
手册的相关内容
代码如下:
cat << END >> $NGX_MAKEFILE
manpage: $NGX_OBJS/nginx.8
$NGX_OBJS/nginx.8: $NGX_MAN $NGX_AUTO_CONFIG_H
sed -e "s|%%PREFIX%%|$NGX_PREFIX|" \\
-e "s|%%PID_PATH%%|$NGX_PID_PATH|" \\
-e "s|%%CONF_PATH%%|$NGX_CONF_PATH|" \\
-e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\
< $NGX_MAN > \$@
展开如下:
manpage: objs/nginx.8
objs/nginx.8: man/nginx.8 objs/ngx_auto_config.h
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
-e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
-e "s|%%CONF_PATH%%|/usr/local/nginx/conf/nginx.conf|" \
-e "s|%%ERROR_LOG_PATH%%|/usr/local/nginx/logs/error.log|" \
< man/nginx.8 > $@
这部分内容就比较重要了,我们知道,当我们使用make
命令编译完Nginx
之后,需要使用make install
命令安装Nginx
到指定的目录,这里就是生成这部分内容的代码了。内容比较简单,就是判断各个目录是否已经存在,不存在就生成对应的目录,然后将Nginx
的可执行文件、配置文件等等复制到指定的安装目录中。
代码如下:
install: build $NGX_INSTALL_PERL_MODULES
test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX'
test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \\
|| mkdir -p '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`'
test ! -f '\$(DESTDIR)$NGX_SBIN_PATH' \\
|| mv '\$(DESTDIR)$NGX_SBIN_PATH' \\
'\$(DESTDIR)$NGX_SBIN_PATH.old'
cp $NGX_OBJS/nginx '\$(DESTDIR)$NGX_SBIN_PATH'
test -d '\$(DESTDIR)$NGX_CONF_PREFIX' \\
|| mkdir -p '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/koi-win '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/koi-utf '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/win-utf '\$(DESTDIR)$NGX_CONF_PREFIX'
test -f '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types' \\
|| cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types.default'
test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params' \\
|| cp conf/fastcgi_params '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/fastcgi_params \\
'\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params.default'
test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf' \\
|| cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf.default'
test -f '\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params' \\
|| cp conf/uwsgi_params '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/uwsgi_params \\
'\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params.default'
test -f '\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params' \\
|| cp conf/scgi_params '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/scgi_params \\
'\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params.default'
test -f '\$(DESTDIR)$NGX_CONF_PATH' \\
|| cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PATH'
cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX/nginx.conf.default'
test -d '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' \\
|| mkdir -p '\$(DESTDIR)`dirname "$NGX_PID_PATH"`'
test -d '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' \\
|| mkdir -p '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`'
test -d '\$(DESTDIR)$NGX_PREFIX/html' \\
|| cp -R $NGX_HTML '\$(DESTDIR)$NGX_PREFIX'
END
if test -n "$NGX_ERROR_LOG_PATH"; then
cat << END >> $NGX_MAKEFILE
test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' \\
|| mkdir -p '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`'
END
fi
if test -n "$DYNAMIC_MODULES"; then
cat << END >> $NGX_MAKEFILE
test -d '\$(DESTDIR)$NGX_MODULES_PATH' \\
|| mkdir -p '\$(DESTDIR)$NGX_MODULES_PATH'
END
fi
for ngx_module in $DYNAMIC_MODULES
do
ngx_module=$ngx_module$ngx_modext
cat << END >> $NGX_MAKEFILE
test ! -f '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \\
|| mv '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \\
'\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module.old'
cp $NGX_OBJS/$ngx_module '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module'
END
done
从之前的内容我们可以知道,我们一直操作的是objs/Makefile
文件,但是我们最终编译时,是在源代码目录下进行编译的,所以肯定存在一个主Makefile
来调用子目录的Makefile
文件的。这也就是auto/install
文件最后所做的工作了,也就是生成主Makefile
文件,然后往里面写入相关的可以调用objs/Makefile
的目标
代码如下:
cat << END >> Makefile
build:
\$(MAKE) -f $NGX_MAKEFILE
install:
\$(MAKE) -f $NGX_MAKEFILE install
modules:
\$(MAKE) -f $NGX_MAKEFILE modules
upgrade:
$NGX_SBIN_PATH -t
kill -USR2 \`cat $NGX_PID_PATH\`
sleep 1
test -f $NGX_PID_PATH.oldbin
kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
END
生成的主Makefile
文件的内容如下:
default: build
clean:
rm -rf Makefile objs
build:
$(MAKE) -f objs/Makefile
install:
$(MAKE) -f objs/Makefile install
modules:
$(MAKE) -f objs/Makefile modules
upgrade:
/usr/local/nginx/sbin/nginx -t
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
sleep 1
test -f /usr/local/nginx/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
本文是零散介绍Nginx
配置脚本的最后一篇了,那些相对重要的脚本在这十篇文章中都介绍过了。通过这十篇文章的学习,我们大致了解了Nginx
各种类型的配置脚本所发挥的作用,当然这些脚本需要有一个文件来统一使用它们,也就是源代码根目录的configure
文件,我将在下一篇文章中讲解configure
文件,看看里面是如何使用这些脚本来完成一个完整的、可跨平台的配置编译信息的过程的。