GCC编译:
预处理->编译->连接->加载
- 预处理:处理程序中#开头的内容
- 编译:程序构建过程, 生成.o文件,gcc 依赖顺序问题(从后向前),如果文件a依赖于文件b,那么编译的时候必须把a放前面,b放后面。
- 连接:将所有的对象文件和库串联起来,成为可运行程序。静态库已经植入程序,共享库在程序中包含其引用。
- 加载:程序启动,引用共享库,GCC编译器假定所有的共享库以lib开头,以.so或者.a结尾。
GCC命令详解:
-o
gcc test.c –o test -o用于指定生成程序的名称-
-l(小写的l)
用于指定程序要链接的库,-l后面紧接着(没有空格)就是库名xxxx(去掉lib和.so)Ps:放在默认路径(/lib ,/usr/lib , /usr/local/lib)的库直接用-i参数就能链接,只需编译时加上 –lxxxx 就能使用libxxxx.so,程序中include libxxxx.so对应的头文件,就可以调用该库的函数。
-L(大写的L)
但是libxxxx.so没有放在默认的三个路径下时,就需要-L指定libxxxx.so的路径,否则程序就会报错(can’t find -lxxxx)。
假设libxxxx.so所在目录为/aa/bb/cc,那么使用格式如下:-L/aa/bb/cc –lxxxx-O
用于优化程序-shared
用于编译动态库:-I(大写的i)
头文件不在/usr/include目录下时,用于指定头文件目录-S
输出汇编代码
GCC动态库(共享库)与静态库的生成与加载:
什么是动态链接库与静态链接库?
每个人的代码不可能从0写起,需要调用各种库函数,静态库编译时加载,动态库运行时加载。
静态库的格式:libxxxx.a
动态库的格式:libxxxx.so.major.minor xxxx为该lib的名称 major主版本号 minor副版本号如何知道一个可执行程序依赖那些库
由上图可知,可执行程序ln依赖于libc库和ld-linux库。
总结以上基本知识是因为程序链接过程中遇到了如下错误:
/usr/bin/ld:/tmp/ccdUkmoA.o:
undefined reference to symbol ‘ERR_free_strings@@OPENSSL_1.0.0’
/lib/i386-linux-gun/libcrypto.so.1.0.0:error adding symbols: DSO missing from command line
解决方法:makefile 文件中加入 –lcrypto (放在-lssl之后)
指定程序的动态链接库libcrypto.so.1.0.0
为什么会出现undefined reference to ‘xxxxx’错误?
首先这是链接错误,不是编译错误,说明程序源码本身没有问题,而是makefile文件中的参数用得不对,没有指定链接程序要用到得库。