GCC 编译过程/编译命令详解/静态库与动态链接库/ error:undefined reference to

GCC编译:

预处理->编译->连接->加载

  • 预处理:处理程序中#开头的内容
  • 编译:程序构建过程, 生成.o文件,gcc 依赖顺序问题(从后向前),如果文件a依赖于文件b,那么编译的时候必须把a放前面,b放后面。
  • 连接:将所有的对象文件和库串联起来,成为可运行程序。静态库已经植入程序,共享库在程序中包含其引用。
  • 加载:程序启动,引用共享库,GCC编译器假定所有的共享库以lib开头,以.so或者.a结尾。

GCC命令详解:

  1. -o
    gcc test.c –o test -o用于指定生成程序的名称

  2. -l(小写的l)
    用于指定程序要链接的库,-l后面紧接着(没有空格)就是库名xxxx(去掉lib和.so)

    Ps:放在默认路径(/lib ,/usr/lib , /usr/local/lib)的库直接用-i参数就能链接,只需编译时加上 –lxxxx 就能使用libxxxx.so,程序中include libxxxx.so对应的头文件,就可以调用该库的函数。

  3. -L(大写的L)
    但是libxxxx.so没有放在默认的三个路径下时,就需要-L指定libxxxx.so的路径,否则程序就会报错(can’t find -lxxxx)。
    假设libxxxx.so所在目录为/aa/bb/cc,那么使用格式如下:-L/aa/bb/cc –lxxxx

  4. -O
    用于优化程序

  5. -shared
    用于编译动态库:
    这里写图片描述

  6. -I(大写的i)
    头文件不在/usr/include目录下时,用于指定头文件目录

  7. -S
    输出汇编代码
    这里写图片描述


GCC动态库(共享库)与静态库的生成与加载:

  1. 什么是动态链接库与静态链接库?
    每个人的代码不可能从0写起,需要调用各种库函数,静态库编译时加载,动态库运行时加载。
    静态库的格式:libxxxx.a
    动态库的格式:libxxxx.so.major.minor xxxx为该lib的名称 major主版本号 minor副版本号

  2. 如何知道一个可执行程序依赖那些库
    这里写图片描述
    由上图可知,可执行程序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文件中的参数用得不对,没有指定链接程序要用到得库。

展开阅读全文

没有更多推荐了,返回首页