概述
在nginx调试过程中,会发现三个文件不是在源码包中的,而是根据具体平台自动生成,这三个文件分别是 ngx_modules.c ,ngx_auto_headers.h,ngx_auto_config.h。那么这三个文件是怎么自动生成的?生成的流程是怎样的?又是在什么地方调用的呢?本篇针对这些问题做个分析。
1.总控脚本configure
nginx-1.22.1/configure
LC_ALL=C
export LC_ALL
. auto/options #该脚本生效全局变量,比如自动生成文件.h和.c名,模块是否安装控制开关
. auto/init #不修改脚本auto/init权限,仍然可以执行脚本,需要root权限才可以
. auto/sources #基本模块定义
...
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` #获取计算机CPU硬件架构
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
...
#调用操作系统配置脚本
. auto/os/conf
...
2.初始化脚本中需要用到的全局变量
nginx-1.22.1/auto/init
NGX_MAKEFILE=$NGX_OBJS/Makefile
NGX_MODULES_C=$NGX_OBJS/ngx_modules.c
NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h #自动生成运行环境相关宏定义,例如操作系统宏开关
NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h #操作系统属性相关宏开关,比如是否支持epoll,sendfile等系统函数调用
...
3.操作系统配置脚本
nginx-1.22.1/auto/os/conf
case "$NGX_PLATFORM" in
FreeBSD:*)
. auto/os/freebsd
;;
Linux:*)
. auto/os/linux #执行linux系统脚本
;;
SunOS:*)
. auto/os/solaris
;;
Darwin:*)
. auto/os/darwin
;;
win32)
. auto/os/win32
;;
...
*)
CORE_INCS="$UNIX_INCS"
CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
CORE_SRCS="$UNIX_SRCS"
;;
esac
4.自动生成头文件: ngx_auto_headers.h和ngx_auto_config.h
nginx-1.22.1/auto/os/linux
...
have=NGX_LINUX . auto/have_headers #自动生成linux系统的头文件ngx_auto_headers.h
...
. auto/feature #调用auto/have脚本和cat << END方法自动生成系统相关属性头文件ngx_auto_config.h
...
4.1 auto/have_headers脚本
nginx-1.22.1/auto/have_headers
#脚本从变量NGX_AUTO_HEADERS_H获取值自动生成头文件ngx_auto_headers.h
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
cat << END >> $NGX_AUTO_HEADERS_H
#ifndef $have
#define $have 1
#endif
END
#ngx_auto_headers.h文件样例
...
#ifndef NGX_LINUX
#define NGX_LINUX 1
#endif
...
4.2 auto/have脚本,往ngx_auto_config.h中写入信息
nginx-1.22.1/auto/have
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $have
#define $have 1
#endif
END
#ngx_auto_config.h文件样例
nginx-1.22.1/objs/ngx_auto_config.h
#define NGX_CONFIGURE " --prefix=/home/hesy/work/nginx-1.22.1/nginx/bin --with-http_ssl_module --with-stream --with-cc-opt='-O0 -g'"
#ifndef NGX_COMPILER
#define NGX_COMPILER "gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) "
#endif
...
#ifndef NGX_HAVE_EPOLL
#define NGX_HAVE_EPOLL 1
#endif
...
#ifndef NGX_HAVE_SENDFILE
#define NGX_HAVE_SENDFILE 1
#endif
...
5.自动生成文件: ngx_modules.c
auto/init脚本中定义文件路径:NGX_MODULES_C=$NGX_OBJS/ngx_modules.c
根据. auto/options 和 . auto/sources脚本来确定相关模块名,存在全局变量中
. auto/modules(调用auto/module)脚本根据模块全局变量名来动态生成.c文件
. auto/options:该脚本可用来定义控制模块是否编译,是否是预定义
如下两个脚本负责往ngx_modules.c中写入数据
nginx-1.22.1/auto/modules
nginx-1.22.1/auto/modules
6.程序引用
6.1 nginx-1.22.1/src/core/ngx_config.h中引用ngx_auto_headers.h和 <ngx_linux_config.h>, <ngx_linux_config.h>中又引用ngx_auto_config.h
nginx-1.22.1/src/core/ngx_config.h
#ifndef _NGX_CONFIG_H_INCLUDED_
#define _NGX_CONFIG_H_INCLUDED_
#include <ngx_auto_headers.h>
...
#elif (NGX_LINUX)
#include <ngx_linux_config.h>
...
#endif /* _NGX_CONFIG_H_INCLUDED_ */
6.2 nginx-1.22.1/src/os/unix/ngx_linux_config.h引用ngx_auto_config.h
nginx-1.22.1/src/os/unix/ngx_linux_config.h
#ifndef _NGX_LINUX_CONFIG_H_INCLUDED_
#define _NGX_LINUX_CONFIG_H_INCLUDED_
...
#include <ngx_auto_config.h>
...
#if (NGX_HAVE_EPOLL)
#include <sys/epoll.h>
#endif
#endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */
nginx以模块的方式组织代码,使得代码编写和扩展相当灵活。而为了实现跨平台,其通过shell脚本检测本地系统,自动生成代码,这一套处理解决问题的思想值得IT同仁们在工作中借鉴。
最后
以上就是等待鞋子为你收集整理的nginx系列第三篇:nginx平台相关源码自动生成流程的全部内容,希望文章能够帮你解决nginx系列第三篇:nginx平台相关源码自动生成流程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复