makefile 语法 /usr/bin/ld: cannot find -lxxxx

GCC编译错误

1./usr/bin/ld:/tmp/ccd/UkmoA.o :undefined reference to symbol ‘ERR_free_strings@OPENSSL_1.0.0’
//lib/i386-linux-gnu/libcrypto.so.1.0.0:error adding symbols:DSO missing from command line

error1:
makefile 语法 /usr/bin/ld: cannot find -lxxxx_第1张图片

解决方法:
makefile 文件中加入 –lcrypto (放在-lssl之后)
指定程序的动态链接库libcrypto.so.1.0.0
这里写图片描述

2./usr/lib/ld :can’t find -lmysqlclient

error2:
这里写图片描述

解决方法:
因为动态库文件mysqlclient没在默认路径下(/usr/lib /lib /usr/local/lib).
所以需要指明动态链接库的路径 :-L/usr/lib/mysql/ -lmysqlclient
这里写图片描述

3.error while loading shared libraries:libmysqlclient.so.18:can’t open shared object file :no such file or directory

error3:
这里写图片描述

解决方法:
1. 编辑/etc/ld.so.conf文件,加入 libmysqlclient.so.18所在在的路径:/usr/lib/mysql

这里写图片描述
2. 然后执行命令:
$ ldconfig
ldconfig 命令的用途主要是在默认目录 (/usr/lib、/lib)以及动态库配置文件/etc/ld.so.conf所列目录下搜索出可共享的动态链接库(libxxxx.so*),进而创建出动态装入程序(ld.so)。所需的连接和缓存文件。缓存文件默认是/etc/ld.so.cache,此文件保存以排好序的动态链接库名字列表。

GCC编译基本过程

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

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

GCC动态库与共享库

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

  • 如何知道一个可执行程序依赖哪些库
    这里写图片描述
    解释:
    可执行程序ln依赖于libc库和ld-linux库

  • 如何定位共享库文件
    a. -l(小写的l)
    用于指定程序要链接的库,-l后面紧接着(没有空格)就是库名xxxx(去掉lib和.so)
    Ps:放在默认路径(/lib ,/usr/lib , /usr/local/lib)的库直接用-i参数就能链接,只需编译时加上 –lxxxx 就能使用libxxxx.so,程序中include libxxxx.so对应的头文件,就可以调用该库的函数。
    b. -L(大写的L)
    但是libxxxx.so没有放在默认的三个路径下时,就需要-L指定libxxxx.so的路径,否则程序就会报错(can’t find -lxxxx)。
    假设libxxxx.so所在目录为/aa/bb/cc,那么使用格式如下:-L/aa/bb/cc –lxxxx

ldconfig指令详解

ldconfig 命令的用途主要是在默认目录 (/usr/lib、/lib)以及动态库配置文件/etc/ld.so.conf所列目录下搜索出可共享的动态链接库(libxxxx.so*),进而创建出动态装入程序(ld.so)。所需的连接和缓存文件。缓存文件默认是/etc/ld.so.cache,此文件保存以排好序的动态链接库名字列表。

程序连接(运行)时首先在/etc/ld.so.cache查找共享库,找不到的话然后再到/etc/ld.so.conf的路径里面去查找。
linux启动时会执行一次该命令,之后如果修改了/lib/或/usr/lib,安装了新的动态链接库时,一定要执行一次$ldconfig。

Ps:

  • 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig
  • 默认目录以外添加动态链接库,一定要修改/etc/ld.so.conf,然后再调用ldconfig
  • 比如之前安装mysql-connector-c-6.1.11-linux-glibc2.12-i686,将其lib文件夹中的mysqlclient动态链接库拷贝到/usr/lib/mysql文件夹下,这时就需要在/etc/ld.so.conf下面加一行/usr/lib/mysql/,保存过后ldconfig一下,新的library才能在程序运行时被找到。
  • 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。
  • ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。
  • 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。

你可能感兴趣的:(gcc)