Linux编译的时候由于链接库出现的各种问题

一 动态库与机器位数不符合

报错内容:

/usr/bin/ld: skipping incompatible /usr/lib/libcrypto.so when searching for -lcrypto
/usr/bin/ld: skipping incompatible /usr/lib/libc.so when searching for -lc

此种情况就是libc.so以及libcrypto.so编译的时候是64位而本机器的位数为32位,或者相反情况,我遇到的情况是动态库是32位编译的,但是本机器是64位,所以需要连接的库应该连接到64位,这两个库都是系统库,在/usr/lib64/这个目录下就有现成的64位对应动态库,所以只要将Makefile里面的-L/usr/lib改成-L/usr/lib64就可以,非系统库的话就需要自己去找与自己机器匹配的位数对应的库

如果自己的机器是32位,但是只有64位的库,那么可以修改编译的参数,gcc编译的时候加上-m64:
gcc -m64 test.c (test会按照64位机器来进行编译)

二 找不到系统库

报错内容:
/usr/bin/ld: cannot find -lcrypto

1.定位库的位置:
    a.find / -name libcrypto*(需要root权限)
    b.locate crypto(无需root权限)
2.如果找到了/usr/local/lib/libcrypto.so.1
则做一个软连接(系统默认库路径:/usr/lib,/lib):
    ln -s /usr/local/lib/libcrypto.so.1 /usr/lib/libcrypto.so

三 找不到自定义库(非系统提供的库)

报错内容:

/usr/bin/ld:cannot find -lcomm
/usr/bin/ld:cannot find -lipc
找不到这两个库,这种情况基本上就是没有加上这两个库所在的路径,Makefile中加上-L/home/test/example/lib就可以(库在此目录下)

四 未定义的符号

报错内容:
/home/test/src/../lib/libSDKcomm.a(cli_sndrcv_v1.o): In function `cli_sndrcv_v1`:
/home/sunlan/SDK2.6/obj/../tcp/cli_sndrcv_v1.c:73: undefined reference to `MD5_Update’

代表这些函数的头文件之类的已经包含,但是没有提供函数库
编译选项中需要加入:-lmd5(假设libmd5.so库未链接)
假设libev.a libcoro.a ,其中libcoro.a中调用来libev.a中的函数,则链接的顺序是:
BUILD_LIBS = -lcoro -lev

当C文件中出现的结构体,写对了但是编译报错找不到里面的对应成员,1.可能头文件未包含 2.头文件包含了,则很有可能是依赖库的原因,头文件路径或者库文件路径没有加到链接选项中(-L),总之就是makefile中缺少了一个依赖的文件或文件路径,致使它找不到

五 运行的时候出错

报错内容:
/usr/local/bin/luajit ./test.lua
/usr/local/bin/luajit: error loading module ‘lualog’ from file ‘./lualog.so’:
libluajit-5.1.so.2: cannot open shared object file: No such file or directory
stack traceback:
[C]: at 0x0044d340
[C]: in function ‘require’
./test.lua:3: in main chunk
[C]: at 0x00404180

第一步:确认有哪些Lib无法Load
[root@testsupex]# ldd /home/xuli/Desktop/supex/open/lib/lua-log/lualog.so
linux-vdso.so.1 => (0x00007fff23e00000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fbf2cbe8000)
libluajit-5.1.so.2 => not found
libc.so.6 => /lib64/libc.so.6 (0x00007fbf2c850000)
/lib64/ld-linux-x86-64.so.2 (0x000000371ea00000)

第二步:查找到缺失的动态库在哪里:libluajit-5.1.so.2 => not found
[root@test supex]# find / -name libluajit-5.1.so.2
/usr/local/lib/libluajit-5.1.so.2

第三步:将缺失的动态库软链接到系统默认会搜索的动态库的地方 /usr/lib
[root@test supex]# ln -s /usr/local/lib/libluajit-5.1.so.2 /usr/lib

第四步:运行ldconfig命令重建/etc/ld.so.cache
[root@test supex]# ldconfig

总结:

由于库的原因导致编译失败,第一步就是要确认电脑中确实存在此库,如果不存在当然是需要获取此库到电脑中,电脑中确实有库的存在但是还是编译失败基本上就是路径问题,系统无法找到,以下三种方法解决:

1.用ln -s将需要的so文件链接到/usr/lib或者/lib这两个默认的目录下边,之后ldconfig 一下
如:ln -s /where/you/install/lib/libyourlib.so /usr/lib/libyourlib.so


2.修改/etc/ld.so.conf配置文件,然后刷新(root)
 vim /etc/ld.so.conf.d/local.conf
在自己新建的local.conf文件中加上一句:
/where/you/install/lib
最后运行一下ldconfig

3.修改LD_LIBRARY_PATH系统环境变量
export LD_LIBRARY_PATH=/where/you/install/lib:$LD_LIBRARY_PATH
最后运行一下ldconfig
不过这个只是临时的更改了

注释:

  1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library会找不到
  2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到
    比如安装了一个mysql到/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,这时就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,保存过后ldconfig一下,新的library才能在程序运行时被找到。
  3. 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。
  4. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。
  5. 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。
    再有,诸如libdb-4.3.so文件头中是会含有库名相关的信息的(即含“libdb-4.3.so”,可用strings命令察看),因此仅通过修改文件名以冒充某已被识别的库(如libdb-4.8.so)是行不通的。为此可在编译库的Makefile中直接修改配置信息,指定特别的库名

/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libpubfunc.so when searching for -lpubfunc
/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libpubfunc.so when searching for -lpubfunc
/usr/bin/ld: cannot find -lpubfunc
/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libsyddb.so when searching for -lsyddb
/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libsyddb.so when searching for -lsyddb
/usr/bin/ld: cannot find -lsyddb

解决方案:此处两个库是自己编译的,但还是不兼容,则很可能是自己定义的环境变量的问题,我这里的问题时PLATFORM变量被定义成了Linux64,而从自己本地获取的PLATFORM=Linux,所以两者出现了不一致

在程序运行的时候出现
./monitor: error while loading shared libraries: libodbc.so.1: cannot open shared object file: No such file or directory

在root用户下执行下面的操作
则需要修改/etc/ld.conf.d/local.conf文件(CSDN)
之后执行ldconfig

在执行./monitor程序时报错,在下载某库的时候找不到的处理方式(这里缺失的库是自定义库):

第一步确认缺失的库:
[hztc@hzfcc bin]$ ldd monitor
linux-vdso.so.1 => (0x00007ffe90374000)
libpubfunc.so => not found
libsyddb.so => not found
libodbc.so.1 => not found

第二步查找库的位置:
[hztc@hzfcc bin]$ locate libodbc.so.1
/home/hztc/HZTC/support/unixODBC/Linux64/lib/libodbc.so.1
/home/hztc/HZTC_V1.0/support/unixODBC/Linux64/lib/libodbc.so.1
/home/hztc/HZTC_V1.11/support/unixODBC/Linux64/lib/libodbc.so.1
/home/hztc/monitor/support/unixODBC/Linux64/lib/libodbc.so.1

第三步进入root用户去修改ldconfig配置文件
[hztc@hzfcc bin]$ su root
Password:
[root@hzfcc bin]# vim /etc/ld.so.conf.d/local.conf
在local.conf文件中添加库的路径:/home/hztc/monitor/support/unixODBC/Linux64/lib/

第四步:刷新配置文件,执行下面的命令
[root@hzfcc bin]# ldconfig

第五步:退出root用户
[root@hzfcc monitor]# exit
exit
[hztc@hzfcc bin]$ ls

你可能感兴趣的:(Linux系统)