Linux下gcc经验总结

1.gcc的常用参数

-I(大写i)参数:添加头文件目录到索引目录;例如:-I /usr/local/include/

-L参数:添加链接库目录到索引目录;例如:-L /usr/local/lib/

-l(小写L)参数:表示编译时添加链接库文件;例如:-ltest(参数与内容中间没空格)代表着连接(库名为test)链接库文件,库名和实际文件名是不同的,库名是文件名去掉开头的lib和结尾的.a或.so后的名字,比如文件名为libmy.a的链接库的库名是my

-static参数:GCC在默认情况下链接的是动态库,-static选项,它会强制程序连接静态库。在支持动态链接的系统上,可以用来阻止连接动态库。该选项在其它系统上无效。

-Wl,[option](小写L)参数:告知gcc把-Wl,后面的参数传递给链接器ld去处理,其中option是要传递的参数表,option中多个参数由“,”分割,例如-Wl,-ldl,-lm

2.gcc的机制

参数解析顺序:
对于C/C++编译而言,读取编译选项是按照从左到右的顺序执行的。那么当编译器遇到源文件的时候,就开始对源文件中用到的函数进行解析,找到相对应的 函数的函数体或者说是实现(Definition of Function)。这个过程是按照先遇到不能解析的函数(unresolved function),然后在源文件选项后面的一些选项中寻找可能的函数体的信息,是这样的一个顺序进行的。那么对于包含函数体或者函数定义信息的编译选项出现在源文件之前,那么当编译器在源文件中遇到不能解析的函数时,在源文件之后的选项中寻找相关的信息,那么就出现了编译错误,也就是无法找到相关的函数定义。
gcc链接库目录:
gcc把/usr/lib和/usr/lib64作为默认的库索引目录,这是可以控制的,操作方式是这样的
1.编辑/etc/ld.so.conf文件,加入库文件所在目录的路径 
2.运行ldconfig,该命令会重建/etc/ld.so.cache文件

3.静态库问题

生成静态库:
静态库只是一堆object对象的集合,使用ar命令可以将.o文件打包成.a静态库。
假设gcc已经生成了a.o, b.o, c.o,使用下面的命令即可生成libmylib.a
#ar rcs libmylib.a a.o b.o c.o

4.动态库问题

生成动态库:
动态库的生成由gcc直接生成。
假设a.c, b.c两个文件,通过下面的命令可生成libmylib.so
#gcc -shared -fpic -o libmylib.so a.c b.c
“pic”命令行标记告诉GCC产生的代码不要包含对函数和变量具体内存位置的引用,这是因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。这样编译出的hello.o可以被用于建立共享链接库。建立共享链接库只需要用GCC的”-shared”标记即可。

5.链接库问题

混合使用链接库:
程序链接时候如果既需要链接静态库,又需要链接动态库,可以使用Wl,[option]参数解决,此参数的option参数可以用来指定链接方式,-dn(-Bstatic)为静态链接,-dy(-Bdynamic)为指定动态链接;例子如下:gcc -o test test.c -Wl,-dn -lmylib -Wl,-dy -lm 此处的mylib为libmylib.a

6.使用问题

-static选项时候提示cannot find -lc:
原因分析:
gcc编译时候调用了libc.so的链接库文件,如果加入了-static参数,这时候gcc寻找的就是libc.a文件了,如果目录中没有,则出现cannot find -lc;正常情况下用yum安装gcc是不安装静态库的,所以有此错误。
解决方案:
安装gcc对应的静态库,即:yum install glibc-static

在-static选项下使用-lm也就是math库时候报错:undefined reference to `sqrt`:
原因分析:
因为编译选项中有-static, 所以 -lm 指的是libm.a

这就涉及到符号空穴的实现问题。
Sam猜测:因为编译器从左向右读取文件, 当读到-lm时,因为是静态的,但此时还不知道该把哪个符号抽出来。所以只好往后继续处理,等在main.o中发现
*UND* 00000000 sqrt, 也就是这个符号需要填入时,后面的文件却没有这个符号的实现。所以就报错了。

但如果去掉 -static. 则编译器编译出的test中此符号还是未定义。但会在运行时从libm.so中将符号找到。
解决方案:
既然编译器只会向后找符号,那很简单,把-lm放后面就行了。
gcc -o test -static test.o -lm
编译成功。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值