Linux下GCC相关知识点

摘要:

总结GCC的具体使用,动态库静态库的相关问题

参考资料:

《Linux网络编程》  ISBN:9787302207177  p19

1 GCC简介

GCC是Linux下的编译工具集,是GNU Compiler Collection的缩写,包含gcc,g++等编译器,还有工具集如ar,nm

GCC工具集不仅能编译C/C++,还能编译其他语言如Objective-C

GCC还能进行交叉编译

 

文件扩展名含义:

 

默认路径:

 2 编译步骤

预编译:将头文件包含进源代码,并对一些宏进行替换

编译和优化:编程汇编语言

汇编:汇编->机器语言,这一步生成目标文件.o

链接:目标文件通常解析了文件内部的变量和函数,对于引用的函数和变量还没有解析,需要将其他已经编写好的目标文件引进来,通常引用的目标是库

 

3 用GCC编译程序

常用选项

-c  生成目标文件

-o  指定生成文件名称,不指定生成默认文件名

-E   仅作预处理,不进行编译、汇编和链接

-S   仅编译到汇编语言,不进行汇编和链接

-llibrary   进行链接时搜索名为library的库

-Ldir  把dir加入到搜索库文件的路径列表中

-Idir  把dir加入到搜索头文件的路径列表中

-static  仅选用静态程序库进行链接,如果一个目录中静态库和动态库都存在,则仅选用静态库

 

1. 将源文件直接编译成可执行文件

gcc hello.c    //生成hello.out

gcc -o hello hello.c    //指定生成的可执行文件名为hello

 

2. 将源文件先编译成目标文件,再编译成可执行文件

gcc -c hello.c    //生成hell.o

gcc -o hello hello.o        //链接,生成可执行文件hello

4 静态和共享(动态)库

什么是库
在windows平台和linux平台下都大量存在着库。
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
由于windows和linux的平台不同(主要是编译器、汇编器和连接器的不同),因此二者库的二进制是不兼容的。

 

库的种类
linux下的库有两种:静态库和共享库(动态库)。
二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。
共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

 

库存在的意义
库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。
现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

 

注意

库名是不包含函数库和扩展名的字符串

如果系统的搜索路径下存在静态库和动态库,默认情况下会链接动态库,如果要强制链接静态库,需要加上-static选项

无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件

 

静态链接库

先生成目标文件,在用ar -cr生成

ar -cr libstr.a string.o          //生成静态库

gcc -o test main.c libstr.a    //使用静态库

 

动态链接库

动态链接库有别名(soname)、真名、链接名,别名:lib库名.so,真名是在别名基础上加上小版本号。链接名是程序在链接时使用的库名。一般来说使用动态链接库总是将库文件放到某个目录下,然后用软链接生成别名

“PIC”命令行标记告诉GCC产生的代码不要包含对函数和变量具体内存位置的引用,这是因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。这样编译出的hello.o可以被用于建立共享链接库。建立共享链接库只需要用GCC的”-shared”标记即可。

gcc -shared -fPIC -o libmyhello.so hello.o

 为了让新增加的动态链接库能够被系统共享,需要运行动态链接库管理命令ldconfig。ldconfig的作用是在系统默认的搜索路径,和动态链接库配置文件中所列出的目录里搜索动态链接库,创建动态链接装入程序需要的链接和缓存文件,搜索完毕后将结果写入缓存文件/etc/ld.so.cache中

 

环境变量

LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径

LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径

 

静态库链接时搜索路径顺序:

1. ld会去找GCC命令中的参数-L

2. 再找gcc的环境变量LIBRARY_PATH

3. 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的

 

动态链接时、执行时搜索路径顺序:

1. 编译目标代码时指定的动态库搜索路径;

2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径;

4. 默认的动态库搜索路径/lib;

5. 默认的动态库搜索路径/usr/lib。

 

posted on 2016-05-15 23:16  已停更  阅读(1579)  评论(0编辑  收藏  举报