gcc
索引:
1.gcc特性
gcc能在生成调试信息的同时对代码进行优化。
gcc有30多个警告和3个一般警告级。
gcc对C和C++进行了大量扩展。
2.gcc编译过程
gcc首先运行预处理程序cpp来展开源文件中的宏并在其中插入#include文件所包含的内容;然后把预处理后的源代码编译成为目标代码;最后,连接程序ld创建可执行二进制文件。
使用-E选项进行预处理。如:
gcc -E hello.c -o hello.cpp
将预处理代码编译成目标代码,使用-x和-c选项。如:
gcc -x cpp-output -c hello.cpp -o hello.o
选项-x告诉gcc从指定的步骤开始编译。
链接目标文件,生成二进制代码:
gcc hello.o -o hello
3.gcc对文件扩展名的解释
扩展名 | 类型 |
---|---|
.c | C语言源代码 |
.C, .cc | C++语言源代码 |
.i | 预处理后的C源代码 |
.ii | 预处理后的C++源代码 |
.S, .s | 汇编语言代码 |
.o | 编译后的目标代码 |
.a, .so | 编译后的库代码 |
4.常用命令行选项
(1).选项列表
选项 | 说明 |
---|---|
-o File | 指定输出文件名 |
-c | 只编译不连接 |
-DFOO=BAR | 在命令行定义预处理宏FOO,其值为BAR |
-Idirname | 将dirname加入到头文件的搜索目录列表中 |
-Ldirname | 将dirname加入到库文件的搜索目录列表中 |
-static | 连接静态库,默认情况下gcc只连接动态库 |
-lFOO | 连接名为libFOO的函数库 |
-g | 在可执行程序中包含标准调试信息 |
-ggdb | 在可执行程序中包含只有GNU debugger(gdb)才能识别的大量调试信息 |
-O | 优化编译过的代码 |
-On | 指定代码优化的级别为n(0<=n<=3),如果未指定n,则默认级别为1 |
-ansi | 支持ANSI/ISO C的标准语法,取消gnu的语法扩展中与该标准有冲突部分(但这一选项并不能保证生成ANSI兼容的代码) |
-pedantic | 允许发出ANSI/IOS C标准所列出的所有警告 |
-pedantic-errors | 允许发出ANSI/IOS C标准所列出的所有错误 |
-traditional | 支持Kernighan $ Ritchie C语法(用旧式语法定义函数) |
-w | 关闭所有警告,建议不要使用此项 |
-Wall | 允许发出gcc能提供的所有有用的警告。也可以用-W{warning}来标记指定的警告 |
-werror | 把所有警告转换为错误,以在警告发生时中止编译过程 |
-MM | 输出一个make兼容的相关列表 |
-v | 显示在编译过程中的每一步中用到的命令 |
(2).gcc警告选项
-W{warning}作用是打开warning所指出的用户感兴趣的特殊警告信息。详细情况可参见帮助。
其中-Wuninitialized选项要求使用-O选项连用时才有效。
(3).优化选项
-O1级别:能执行的优化类型取决于目标处理器,但一定包括线程直接跳转(thread jump)和延迟退栈(deferred stack pops)这两种优化。
-O2级别包括所有-O1的优化和额外一些调整,其中包含对处理器指令调度的调整。
-O3包括所有-O2级优化,还包括循环展开和其他与处理器特性有关的优化。
可以使用-f{flag}选项执行特定的优化。详情参见帮助。
(4).调试选项
能够用1、2或3来限定-g选项来指定产生多少调试信息。默认的级别是2(-g2),此时产生的调试信息包括扩展的符号表、行号以及局部或外部变量的信息。3级调试信息包括所有2级信息和源代码中定义的所有宏。1级产生的信息只够创建回溯(backtrace)和堆栈转储(stack dump)之用。
-ggdb能接受的调试级别规范和-g一样。
-p选项在代码中加入prof程序能够读取的剖析符号信息,-pg在代码中加入gprof能够解释的符号信息。-a选项在代码中加入代码块(比如函数)累计使用的次数。
-save-temps选项可以保存在编译过程中生成的中间文件,其中包括目标文件和汇编代码文件。
-Q选项让gcc显示编译过程中碰到的每个函数,并提供编译器编译每个函数所花时间的剖析信息。
(5).特定体系结构的选项
gcc可以生成专门针对每种类型的cpu的代码,使用-m{value}选项。列表参见帮助。
5.GNU C扩展
使用long long类型提供64位的存储空间。
内联函数inline。
函数和变量属性attribute。
注释符//。
case区间。
构造函数名称__FUNCTION__。
6.建立静态库
生成目标代码:
gcc -c liberr.c -o liberr.o
使用ar命令生成静态库:
ar rcs liberr.a liberr.o
7.建立动态库
编译目标文件时使用gcc的-fPIC选项,产生与位置无关的代码并能被加载到任何地址:
gcc -fPIC -g -c liberr.c -o liberr.o
使用gcc的-shared和-soname选项;
使用gcc的-Wl选项把参数传递给连接器ld;
使用gcc的-l选项显示的连接C库,以保证可以得到所需的启动(startup)代码,从而避免程序在使用不同的,可能不兼容版本的C库的系统上不能启动执行。
gcc -g -shared -Wl,-soname,liberr.so -o liberr.so.1.0.0 \ liberr.o -lc
建立相应的符号连接:
ln -s liberr.so.1.0.0 liberr.so.1; ln -s liberr.so.1.0.0 liberr.so;