分类: C/C++
2013-06-25 15:17:04
GCC编译器能将C、C++语言源程序、汇编程序编译、连接成可执行文件,在linux系统中,可执行文件没有后缀,系统从文件的属性来区分可执行文件和不可执行文件。
使用GCC编译程序时,编译过程可以分为四个阶段:
*预处理(pre-processing)
*编译(compiling)
*汇编(assembling)
*连接(lingking)
GCC通过后缀来区别输入文件的类别:
*.c -------: C语言源代码文件
*.a-------: 是由目标文件构成的库文件
*.C,.cc或.cxx-----: 是C++元代码文件
*.h------: 头文件
*.i------: 是已经与处理过的C源代码文件
*.ii-----: 是已经处理过的C++源代码文件
*.o-----: 是编译后的目标文件
*.s-----: 是汇编语言源代码文件
*.S----: 是经过预编译的汇编语言文件源代码
基本用法
gcc最基本的用法是::
gcc [options] filename
options : 编译器所需要的编辑选项
filename: 要编译的文件名
一 常用编译命令选项
-c 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
例子用法: gcc -c hello.c 他将生成.o的obj文件
-S 只激活预处理和编译,就是指把文件编译成为汇编代码。
例子用法 gcc -S hello.c 他将生成.s的汇编代码,你可以用文本编辑器察看
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面.
例子用法: gcc -E hello.c > pianoapan.txt gcc -E hello.c | more
假设源程序文件名为test.c
1. 无选项编译链接
用法:#gcc test.c
作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。编译成功后可以看到生成了一个a.out的文件。在命令行输入./a.out 执行程序。./表示在当前目录,a.out为可执行程序文件名。
2. 选项 -o
用法:#gcc test.c -o test
作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。输入./test执行程序。
3. 选项 -E
用法:#gcc -E test.c -o test.i
作用:将test.c预处理输出test.i文件。预处理后停止编译. .i通常为已经预处理过的C原始程序
4. 选项 -S
用法:#gcc -S test.i
作用:将预处理输出文件test.i汇编成test.s文件。
5. 选项 -c
用法:#gcc -c test.s
作用:将汇编输出文件test.s编译输出test.o文件。
6. 无选项链接
用法:#gcc test.o -o test
作用:将编译输出文件test.o链接成最终可执行文件test。输入./test执行程序。
7. 选项-O
用法:#gcc -O1 test.c -o test
作用:使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。输入./test执行程序。
8.编译使用C++ std库的程序
用法:#gcc test.cpp -o test -lstdc++
作用:将test.cpp编译链接成test可执行文件。-lstdc++指定链接std c++库。
二 多源文件的编译方法
如果有多个源文件,基本上有两种编译方法:
[假设有两个源文件为test.c和testfun.c]
1. 多个文件一起编译
用法:#gcc testfun.c test.c -o test
作用:将testfun.c和test.c分别编译后链接成test可执行文件。
2. 分别编译各个源文件,之后对编译后输出的目标文件链接。
用法:
#gcc -c testfun.c //将testfun.c编译成testfun.o
#gcc -c test.c //将test.c编译成test.o
#gcc -o testfun.o test.o -o test //将testfun.o和test.o链接成test
以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。
三 gcc参数的警告提示功能
1:-pedantic 使用了ANSI/ISO C语言扩展语法的地方将产生相应的警告信息
2:-Wall 产生尽可能多的警告信息,建议始终带上
3:-Werror 将所有的警告当成错误进行处理
四 库依赖
函数库实际上就是一些头文件和库文件的集合.
-I选项向gcc的头文件搜索路径中添加新的目录
-L选项向gcc的库文件搜索路径中添加新的目录
-l指定链接的库文件名,如 -ldavid 表示指示gcc去连接库文件libdavid.so
-static强制使用静态链接库
-share 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
动态库文件(.so)和静态库文件(.a)的区别在于程序执行时所需的代码是运行时动态加载的,还是编译时静态加载的.gcc优先使用动态库
其他:
-g 只是编译器,在编译的时候,产生调试信息。
-C 在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序,用这个很方便的
-M 生成文件关联的信息。包含目标文件所依赖的所有源代码你可以用gcc -M hello.c 来测试一下,很简单。
-pipe:管道,它可以用来同时连接两个程序,其中一个程序的输出将直接作为另一个程序的输入,这样就可以避免使用临时文件,提高编译速度,但编译时消耗更多的内存.
-Dmacro 定义指定的宏,使它能够通过源码中的#ifdef进行检验
-g3 获得有关调试程序的详细信息
-v 启动所有报警
-w 禁止所有报警
五 常见错误类型
1:syntex error,语法错误
2:can't find include file,头文件错误
3:ld:lm:No such file or directory,找不到所需的函数库
4:Undefined symbol未定义符号:源代码文件未被包含或编译。