在nginx源代码auto/cc目录下有很多编译器配置相关的脚本。除了conf脚本
及name脚本
之外,其他的都直接与编译器相关。Nginx的出色跨平台性(Linux、Darwin、Solaris、Win32 等)就有这些脚本的贡献,这些脚本主要有:
- acc: HP ANSI C++编译器的相关配置
- bcc: Borland C++编译器的相关配置
- ccc: Compaq C编译器的相关配置
- clang: clang编译器的相关配置,其是一个
较新
的C、C++、Objective-C、Objective-C++语言的轻量级编译器
- gcc: GNU C编译器的相关配置
- icc: Intel C++编译器的相关配置
- msvc: Microsoft Visual C++编译器的相关配置
- owc: Open Watcom C编译器的相关配置
- sunc: Sun C编译器的相关配置
这些配置脚本都是与编译器的特性直接相关。这里我们以我们最常用的gcc编译器为例来进行讲解。
1. auto/cc/gcc脚本
在进行具体的脚本分析之前,我们这里贴出其源代码:
脚本主要是用于配置CFLAGS
编译选项。
2. 获取gcc版本号
上述代码获取gcc版本号,然后将版本信息通过宏定义的形式写入到ngx_auto_config.h头文件中.
3. 设置编译器的-pipe
特性
pipe特性是指在编译的各阶段(stage)使用pipe来通信,而不是采用临时文件的方式来通信。在有一些系统上,汇编器并不能够从pipe读取数据,因此不能正常工作。GNU汇编器一般都具有pipe特性。
运行auto/feature脚本,在编译选项中加入-pipe
选项,以判断是否支持此特性。
4. 平台是否支持casa汇编指令
在sun4u、sun4v、sparc、sparc64平台上支持casa汇编指令,因此在编译选项中添加-mcpu=v9的选项。
5. 编译器优化选项的设置
6. fomit-frame-pointer选项
在函数中禁止保留帧指针(frame pointer)到寄存器中。则就避免了生成frame pointer的保存、建立、恢复的代码,加快了程序的运行。但是在有些系统上启用此功能后会使得编译出来的程序不能进行调试。
从gcc4.6版本开始,默认会启用此功能,而如果需要保留帧指针(frame pointer),则可以使用--enable-frame-pointer
选项。
一般情况下,在非调试程序中,都会给编译器添加--fomit-frame-pointer
选项。
7. 针对CPU的优化
如上根据不同的CPU类型进行优化,然后将相应的优化选项添加到gcc的编译选项中。
CC_AUX_FLAGS
作为辅助参数,并不会反映到最后生成的Makefile文件中,其只在脚本解析过程中被用到。而CFLAGS会作为编译选项反映到最后生成的Makefile文件中。
这里在auto/options脚本当中,CPU默认被初始化为NO,我们后续也没有通过--with-cpu-opt
选项来对CPU进行专门的设置。
8. nginx依赖库的编译选项
nginx会依赖于pcre、md5、zlib等,nginx在编译过程中可以直接编译这些依赖库的源代码,这里为其设置编译选项。
9. 编译器警告的设置
下面对gcc编译器警告相关的一些参数进行说明:
- -w: 关闭编译时的警告。也就是编译后不显示任何warning,因为有时在编译后编译器会显示一些例如数据转换之类的警告,这些警告我们平时可以忽略。
- -Wall: 显示所有警告
- -W: 类似于-Wall,但只显示编译器认为出现错误的警告
- -Werror: 将所有警告都认为是发生了错误。
-Wpointer-arith
: 对函数指针或者void *类型的指针进行算术操作时给出警告。-Wall 并不会打开此项。
char a[] = {'a','b','c','d'};
void *pa = a;
void *p = pa + 1; //此处产生警告
-Wno-unused-parameter
`: 表示对未被使用的函数参数不产生警告。
10. 打开调试选项
11. 预处理选项
如果没有设置预处理器,则将$CC -E
作为预处理器。