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

本文介绍了C++编译时遇到找不到库的错误,如-lmysqlclient等,解决方案包括检查LD_LIBRARY_PATH或安装缺失的静态库。同时,详细阐述了库的定义,静态库与动态库的优缺点、打包及使用方法,强调了库在软件开发中的重要性,如提高效率和代码复用。
摘要由CSDN通过智能技术生成
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将源文件编译成目标文件

img

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

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

img

3、静态库的使用

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

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

img

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

img

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

补充:

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

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

三、动态库

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

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

1、动态库的优缺点

优点:

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

缺点:

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

1、动态库的打包

image-20220807143749930

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

注:

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

2、动态库的使用

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

image-20220807143854982

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

img

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

img

四、库的意义

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白龙码~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值