重点掌握以下知识点:
了解gcc编译器的下载和安装方法,包括嵌入式交叉编译平台搭建的方法
重点掌握gcc的基本编译流程和编译方法
重点掌握gcc编译的高级操作及选项
了解gcc编译器性能分析工具,包括gprof和gcov
gcc下载地址:ftp://ftp.gnu.org/gnu/gcc/
安装过程中遇到的问题:
#./configure --help 查看可用的参数
一般来说configure较重要的就是那个--prefix=/path了,--prefix后面接的路径表示这个软件将来要安装到那个目录去,如果你没有指定--prefix=/path这个参数,通常默认参数就是/usr/local。至于其他参数的意义可以参考./configure --help的结果。
参考《Linux常用工具入门到精通》编译器配置如下:
#./configure --prefix=/usr/local/gcc-3.4.0 --enable-shared --host=i386-redhat-Linux --mandir=/usr/share/man --enable-threads=posix
--disable-checking --with-system-zlib --enable-languages=c,c++,java
结果出现了如下错误:
checking build system type... Invalid configuration `i386-redhat-Linux': system `Linux' not recognized
configure: error: /bin/sh ../../gcc-3.4.0/gcc/../config.sub i386-redhat-Linux failed
make: *** [configure-gcc] 错误 1
很明显可以看出是--host=i386-redhat-Linux配置项有问题,但是该如何配置呢?
首先我用#uname -r查看了相关信息:Linux localhost.localdomain 2.6.18-53.el5 #1 SMP Wed Oct 10 16:34:02 EDT 2007 i686 athlon i386 GNU/Linux,但是还是不知道--host=???最终我的解决方法是直接用#.configure不加任何选项运行一下,会得到一个Makefile文件,打开该文件可以发现host=i686-redhat-linux-gnu,按照改行重新运行上面的配置命令,成功了。
如果用户在以前就安装了其他版本的GCC,为了两个版本同时使用,用户可以对新安装的版本做一个简单的链接:
#cd /usr/bin
#ln -s /usr/local/gcc-3.4.0/bin/gcc gcc3.4
这样用户就可以在一个Linux系统中使用两个版本的GCC了,只是输入gcc代表以前安装的GCC版本,输入gcc3.4代表GCC3.4.0版本。
交叉编译平台的搭建(以arm-linux-gcc-4.3.2为例):
(1)首先从网站上下载arm-linux-gcc-4.3.2.tgz压缩包,将此压缩包复制到/tmp下,然后进入该目录执行解压命令:
#cd /tmp
#tar -xvzf arm-linux-gcc-4.3.2.tgz -C /
(2)执行该命令,把arm-linux-gcc-4.3.2.tgz默认安装到/usr/local/arm/4.3.2目录,为保证每次开机arm-linux-gcc都能正常工作,在命令行输入:
#cd /root
#gedit /root/.bashrc
(3)编辑/root/.bashrc文件,在最后一行添加export PATH=$PATH:/usr/local/arm/4.3.2/bin,保存退出
(4)重新登录RedHat系统,在命令行输入arm-linux-gcc -v,验证是否已安装成功
GCC编译基础流程:
.c(c源程序) ---(-E)---> .i(预处理后的c程序)
.i(预处理后的c程序) ---(-S)---> .s(汇编代码)
.s(汇编代码) ---(-c)---> .o(目标文件)
.o(目标文件) ---(链接)---> elf(可执行文件)
例如:实例程序为hellogcc.c
分步进行:
#gcc -E hellogcc.c -o hellogcc.i 预处理
#gcc -S hellogcc.i -o hellogcc.s 编译
#gcc -c hellogcc.s -o hellogcc.o 汇编
#gcc hellogcc.o -o hellogcc 链接
一步到位:
#gcc -o hellogcc hellogcc.c
GCC常规选项:
-X language 指定输入文件的语言为language
-E 只对源文件进行预处理,不做编译、汇编及链接,GCC会忽略任何不需要预处理的输入文件
-S 只进行编译,不做汇编及链接,对于每个输入的非汇编语言文件,输出文件都是汇编语言文件
-c 只进行汇编,不做链接,汇编成源文件的目标文件,默认状态下生成.o文件,GCC忽略-c选项后面任何无法识别的输入文件
-o file 把输出的文件指定到file中,该选项可以输出汇编文件、目标文件以及可执行文件
-v 打印出编译器内部编译各个过程的命令行信息和编译器版本信息
GCC警告选项:
-fsyntax-only 检查程序中的语法错误,但是不产生输出信息
-w 禁止所有警告信息
-Wunused 如果某个局部变量除了声明就没有再使用,或者声明了静态函数但是没有定义,或者某条语句的运算结果显然没有使用,编译器就发出警告
-Wmain 如果把main函数声明或定义成奇怪的类型,编译器就发出警告
-Werror 视警告为错误,出现任何警告即放弃编译
-Wredundant-decls 如果在同一个可见域定义多次声明,编译器就发出警告,即使这些重复声明有效并且毫无差别
-Wall 允许gcc提供所有有用的报警信息
-pedantic-error 允许发出ANSI C标准所列出的全部信息
GCC调试选项:
-g 使用-g选项可以使GCC在编译时产生调试信息,GDB能够使用这些调试信息对程序进行排错,如果要使用GDB调试信息,那么-g选项必须要选中,否则GDB将不能调试出错语句
-pg 产生额外代码,用于输出profile信息,供分析程序gprof使用
-gdwarflevel n 生成调试信息,同时使用level指出需要多少信息,默认的level值是2,level 1输出最少量的信息,仅包括函数和外部变量的描述,没有局部变量和行号信息。level 3包含更多的信息,如程序中出现的所有宏定义,支持宏扩展
GCC优化选项:
-On 其中n是一个代表优化级别的整数,n的范围一般在0-3之间,n值越大,优化效果越好;-O0表示不进行任何优化;-O3表示尽可能的执行优化
-Os 对可执行文件的大小进行优化
GCC链接选项:
连接器的主要功能是链接多个目标文件和库文件,并最终生成特定平台的可执行文件。一般而言,标准函数库都放在/lib或者/usr/lib子目录里,默认情况下,GCC编译器只会寻找所有标准函数库目录里的文件,如果用户要链接自己编写的文件,就必须使用GCC的链接功能选项。
-llibrary 搜索library的库文件,连接器在标准搜索目录中寻找这个库文件,库文件的真正名字是liblibrary.a,连接器会把它当作文件名准确引用这个文件。但是即使不使用这个选项,gcc也把默认的一些库连接进去(若需要引用一个不是默认的库则必须使用该链接选项,否则会出现undefined reference to这样的链接错误)。搜索目录除了一些系统标准目录外,还包括用户以-L选项指定的路径
-nostartfiles 不连接系统标准启动文件,而标准库文件仍然正常使用
object-file-name 如果某些文件没有特别明确的后缀,GCC就认为它们生成的是目标文件或库文件
-nostdlib 不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器
-static 在动态链接时,阻止链接共享库
-shared 生成一个共享目标文件,它可以和其他目标文件连接产生可执行文件。只有部分系统支持该选项
-I 目录 表示在头文件搜索路径中添加用户自定义的搜索目录。由于Linux中头文件都默认放到/usr/include目录下,因此,当用户希望添加其他位置的头文件时,就可以通过 -I dir 选项指定。这个选项在编译多个不在同一个目录下的文件非常有用
-L 目录 表示在库文件的搜索路径中添加用户自定义的搜索目录名,例如一个程序在链接时需要使用在目录/home/wth下的库,用户只需要在 gcc 命令中加入 -L /home/wth/