GCC发展至今已经成为Linux中重要的编译语言之一,可以看出GCC的地位还是很重要的。而且GCC对于操纵系统平台以及硬件系统平台的支持就像无所不在的感觉,所以在本文中将会对GCC中的命令项比如预处理代码、汇编代码以及链接代码进行介绍。
GCC简单介绍
Gcc是GNU推出的多平台编译器,原名为GNU C Compiler,原来只是做C语言编译器,后来发展支持处理C++,继而可处理Fortran、java、Pascal等语言,Gcc支持在多种硬体平台上编译可执行程序,目前,Gcc是Unix类操作系统的标准编译器。而GCC也不再单是GNU C Compiler的意思,而是GNU Compiler Collection也即是GNU编译器家族的意思了。
简单编译
对于上面的程序,可以一步到位的编译命令如下:
gcc test.c -o test
编译程序的时候看起来是只通过编译就可以完成但是GCC的执行过程包括预编译(Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)四个阶段。
预处理
gcc -E test.c -o test.i 或 gcc -E test.c
这时可以直接把test.i文件中存放着test.c经预处理之后的代码输出的命令项。gcc -E test.c是直接在命令行窗口中输出预处理后的代码,你只要打开test.i就知道了。
要知道的是:gcc的-E是可以让编译器在预处理后停止并输出预处理结果的。
编译为汇编代码(Compilation)
可以直接对预处理之后生成的test.i文件进行编译,生成汇编代码:
gcc -S test.i -o test.s
要注意的是:gcc中的-S选项,表示在程序编译的期间,生成汇编代码之后停止,并用-o输出汇编代码文件。
汇编(Assembly)
gcc -c test.s -o test.o
对于汇编代码文件test.s,gas汇编器复杂将其编译为目标文件
连接(Linking)
gcc连接器是由gas提供的,gcc连接器的作用是把程序的目标文件和所有所需的附加的目标文件(包括静态连接库和动态连接库)进行连接,然后最后生成可执行的文件。
gcc test.o -o test
对于汇编生成的test.o,把它和C标准输入库进行连接,就会生成最终成型test。
多个文件的编译
一般来说,一个程序是由多个源文件组成的,所以也就相应的形成了多个编译单元。而使用GCC就可以很好的管理这些编译单元。
例如:有一个由test1.c和test2.c两个源文件组成的程序,我们可以使用以下的这条命令对它们进行编译,使它们最终生成可以执行的程序test。
gcc test1.c test2.c -o test
但是有时候要同时处理的文件不止一个,而GCC依旧会按照原本的过程执行(预处理、编译、链接)。
gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test
检错
gcc -pedantic illcode.c -o illcode
简单来说,-pedantic编译选项只能用来帮助Linux程序员离目标越来越近,因为它不能保证编译程序与ANSI/ISO C标准的完全兼容。从另一个角度来看,-pedantic选项能够帮助程序员发现部分不符合 ANSI/ISO C标准的代码。
gcc -Wall illcode.c -o illcode
除了pedantic,GCC中其他编译选项也能产生有用的警告信息。例如上面的命令行,-Wall是这些-W开头的选择中最有价值的,因为使用它可以使GCC产生尽可能的警告信息。
虽然说GCC的警告错误信息并不能说明是真正的错误,但是对于一个专业的Linux程序员来说,使自己的代码整齐标准是一个良好的习惯。所以把警告信息当做真正的程序对待是一种良好的编程行为。
编译成可以执行的文件
gcc –c –I /usr/dev/MySQL/include test.c –o test.o
当我们要进行编译test.c为目标文件的时候就要使用上面的代码
链接
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
最后我们再使用这个代码把所有的目标文件链接为可执行文件
要注意的是:在Linux库下的文件分为两大类:动态链接库(通常以.so结尾)和静态链接库(通常以.a结尾)
下面我们讲一些在强制链接时使用静态链接库
#p#分页标题#e#
在一般的情况下,GCC会默认使用动态链接库,而且只有当动态链接库不存在的时候才会使用静态链接库。但是你要使用静态链接库也可以,只要在编译的时候嘉盛-static选项,这样就可以强制使用静态链接库。如下
gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test
关于使用静态库链接时的搜索路径顺序:
id先会去找GCC命令中的参数-L,然后再去找在gcc中的环境变量LIBRARY_PATH,最后再去找内定目录/lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的
而动态链接搜索的路径顺序:
1. 在编译目标代码时指定的动态库中搜索路径。
2.环境变量LD_LIBRARY_PATH指定的动态库中搜索路径
3.配置文件/etc/ld.so.conf中指定的动态库中搜索路径
4.默认的动态库中搜索路径/lib
5.默认的动态库中搜索路径/usr/lib
要说一下的是LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径。
库文件连接
开发软件时,很少能遇见完全不使用第三方函数库的,因为在一般情况下程序要通过很多函数库的支持才能运行。从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(so、或lib、dll)的集合。
Linux下的大多数函数都默认将头文件放到/usr/include/目录下,而库文件则放到/usr/lib/目录下;
Windows所使用的库文件主要放在Visual Stido的目录下的include和lib,以及系统文件夹下。
但也有的时候,我们要用的库不再这些目录下,所以GCC在编译时必须用自己的办法来查找所需要的头文件和库文件。例如我们的程序test.c是在linux上使用c连接mysql,这个时候我们需要去mysql官网下载MySQL Connectors的C库,下载下来解压之后,有一个include文件夹,里面包含mysql connectors的头文件,还有一个lib文件夹,里面包含二进制so文件libmysqlclient.so。
要注意的是:其中inclulde文件夹的路径是/usr/dev/mysql/include,lib文件夹是/usr/dev/mysql/lib
文中对在Linux中GCC的常用命令进行了大概的了解并给出了相应的使用代码,但是并不是有代码就能解决一切的,一些关键的地方还需要自己去认真的学习。还有一些易错的点学习的朋友也要记住,最后希望本文能对有需要的朋友带来帮助。