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

来源:互联网 发布:视频特效软件下载 编辑:程序博客网 时间:2024/06/09 16:56

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

报错内容:

/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就可以,非系统库的话就需要自己去找与自己机器匹配的位数对应的库

二 找不到系统库

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

1.在根目录中查找是否存在:    find -name / libcrypto*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.so2.修改/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中直接修改配置信息,指定特别的库名
0 0
原创粉丝点击