关于-static静态链接报出/usr/bin/ld: cannot find -lxxx的问题

Posted 白龙码~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于-static静态链接报出/usr/bin/ld: cannot find -lxxx的问题相关的知识,希望对你有一定的参考价值。

g++ -o mysql_cgi mysql_cgi.cc -std=c++11 -I./include -L./lib -lmysqlclient -lpthread -ldl -static
/usr/bin/ld: cannot find -lmysqlclient
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -ldl
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
  • 我们可以使用locate libxxx.a查看对应静态库的位置,并将其添加至LD_LIBRABY_PATH环境变量中

  • 如果上一方法查看不到位置,说明当前机器没有配置相关的编译环境,即静态库确实是不存在的。此时可以通过sudo yum install glibc-static来安装相关的环境。

对于cannot found stdc++,需要额外使用yum install libstdc++-static安装对应的编译环境。

补充动静态库的知识

一、什么是库

将多个目标文件(.o)打包成一个单独的文件,这样的文件被称为库。

由于目标文件中包含二进制的可执行代码和数据,因此其它目标文件可以与库进行链接,形成可执行文件

库根据生成和链接方式不同分为静态库和动态库。

二、静态库

静态库的命名方式为libxxx.a,如C标准静态库libc.a,去掉lib.a,剩下c的就是静态库名。

静态库与其它目标文件链接的方式称为静态链接

1、静态库的优缺点

优点:

  1. 静态库在编译阶段加载,程序在运行时不需要依赖任何的外部函数库
  2. 使用静态库的函数速度相比动态库较快。

缺点:

  1. 静态链接会将库中的所有代码和数据整合到可执行文件中,因此使用该方式创建的可执行文件一般占用较大的空间,如果有多个进程都使用了该静态库,那么在内存中就会存在好几份相同的代码数据
  2. 一旦静态库作了改动,就要重新链接生成可执行文件。

2、静态库的打包

  1. 通过gcc -c将源文件编译成目标文件

  1. 使用ar -rc命令将目标文件整合为静态库

注:可以使用ar -tv xxx查看xxx静态库包含了哪些目标文件。

3、静态库的使用

静态库需要通过gcc编译器完成链接。

方法一:指明静态库的完整路径(包含库名)

方法二:指明静态库和头文件的路径(不包含库名)

其中,-I指明静态库相关头文件的路径-L指明静态库所在路径,-l指明静态库的具体名称(去掉lib和.a)。

补充:

事实上,仅使用C官方库时,只需要使用gcc -static选项即可完成静态链接,因为官方库和头文件都会存储在操作系统的默认路径下(头文件在**/usr/include**,库在**/lib64**)。

如果想避免复杂的gcc选项,可以直接将自己的库和头文件添加到默认路径,但是一般不推荐,因为会污染系统。

三、动态库

动态库的命名方式为libxxx.so,如C标准动态库libc.so,去掉lib.so,剩下的c就是动态库名。

动态库又被称为共享库,与其它目标文件链接的方式称为动态链接

1、动态库的优缺点

优点:

  • 动态库被内核加载到内存的某个位置,如果进程使用了动态库,那么内存中的动态库就会被映射到该进程地址空间的共享区,从而避免了静态库中相同代码在内存中重复的问题。

缺点:

  • 使用动态链接的程序对动态库具有依赖性。一旦动态库缺失,就会导致程序无法运行。
  • 动态库需要在运行时加载,并计算映射的地址,因此速度相对较慢。

1、动态库的打包

  • -shared指明gcc生成动态库
  • -fpic指明gcc生成与位置无关的代码

注:

静态库的代码对应地址可以在链接时确定,但是动态库不能这样做。因为动态链接往往是运行时进行的,一旦动态库代码的地址确定,这就意味着进程需要为动态库保留这些地址,但事实上一个进程可能只使用了动态库中的一小部分代码,因此保留所有地址就是一种浪费!故而需要-fpic选项生成与位置无关的代码,这些代码的地址在运行时才被确定,避免在链接时保留地址的情况。

2、动态库的使用

方法一:指明动态库的完整路径(包含库名)

方法二:指明动态库和头文件的路径(不包含库名)

通过ldd命令即可查看当前可执行文件使用了哪些动态库:

四、库的意义

  1. 使用高水平开发者写出来的库,能够提高开发效率和代码鲁棒性
  2. 将目标文件封装成库,能够保护源代码,用户只要知道头文件的内容,对应调用需要的接口即可。

以上是关于关于-static静态链接报出/usr/bin/ld: cannot find -lxxx的问题的主要内容,如果未能解决你的问题,请参考以下文章

关于存储持续性,作用域,链接性,static与extern

关于类型的存储时间和链接

关于static静态

关于static

Android开发 关于静态static类与static方法持有Context是否导致内存泄露的疑问

java 关于static