我尝试在虚拟 Centos 7 发行版上构建一些 C++ 库。 由于我还没有发现这个操作系统无法像其他 Linux 发行版一样看到安装这些库的 /usr/local/lib 或 /usr/local/lib64 的原因。所以我必须将这些文件夹添加到/etc/ld.so.conf 中。然后 C++ 链接器就能够看到这些库。 然而后来我给了
sudo yum update
我收到以下消息:
/usr/lib64/python2.7/site-packages/pycurl.so:未定义符号:CRYPTO_num_locks
经过查找,发现是由于libcurl的两个版本的存在造成的。我给了
ldconfig -v | grep libcurl
我得到了以下信息:
ldconfig: Path `/usr/lib' given more than once
ldconfig: Path `/usr/lib64' given more than once
libcurl.so.4 -> libcurl.so.4.4.0
libcurl.so.4 -> libcurl.so.4.3.0
这意味着我安装了新版本的 libcurl,现在两个版本共存。
当我从 /etc/ld.so.conf 中删除文件夹路径时,yum 工作正常,但 c++ 链接器找不到我的应用程序所需的 c++ 库。我也尝试更新 LD_LIBRARY_PATH 但我遇到了同样的问题。
有没有办法解决这个问题,而无需在新位置重新安装库?删除旧版本安全吗?
ls -lsa /usr/lib64/*curl*
给了
0 lrwxrwxrwx. 1 root root 16 Aug 10 10:19 /usr/lib64/libcurl.so.4 -> libcurl.so.4.3.0
428 -rwxr-xr-x. 1 root root 435120 Nov 14 2016 /usr/lib64/libcurl.so.4.3.0
我尝试给予
sudo unlink /usr/lib64/libcurl.so.4
sudo ln -s /usr/local/lib/libcurl.so.4.4.0 /usr/lib64/libcurl.so.4
我什至将它们作为root,但每次我给予
ldconfig
我都会得到
libcurl.so.4 -> libcurl.so.4.3.0
在 ldconfig 给出之前
libcurl.so.4 -> /usr/local/lib/libcurl.so.4.4.0
我遇到了同样的问题,但我的系统上没有安装两个版本的curl 或pycurl。我安装的一个最终用户软件更改了 LD_LIBRARY_PATH,它不包括 /usr/lib 或 /usr/lib64。我尝试将它们添加到路径的末尾,但仍然收到相同的错误。我把它们加到前面了,没有再出错了。我必须询问我的最终用户是否有正当理由从环境变量中排除默认库。
据我所知,CentOS上标准库的默认路径是/usr/lib和/usr/lib64。如果从源代码编译,在使用
./configure
时没有显式指定库路径,这些库将默认安装在 /usr/local/lib 或 /usr/local/lib64 中(通常在 64 位操作系统上可以找到 lib64) 。因此,如果库安装在那里,您应该在 /etc/ld.so.conf 中添加这些路径,然后运行 ldconfig
;
根据你的例子:
ldconfig: Path `/usr/lib' given more than once
ldconfig: Path `/usr/lib64' given more than once
libcurl.so.4 -> libcurl.so.4.4.0
libcurl.so.4 -> libcurl.so.4.3.0
libcurl.so.4 链接到 2 个不同的库版本,我认为这就是您问题的原因。
您可以删除第二个链接
libcurl.so.4 -> libcurl.so.4.3.0
,仅将 libcurl.so.4 链接到 libcurl.so.4.4.0,运行 ldconfig 并重试。
许多问题都可能导致此问题:
undefined symbol: CRYPTO_num_locks
。
但我们必须弄清楚为什么会发生这种情况?
调用链如下图,函数
CRYPTO_num_locks
由libcrypto.so
提供,它是OpenSSL的一部分。
CRYPTO_num_locks
自OpenSSL 1.1.0以来已被删除,因此我们要么使用正确的上层库不再调用此函数,要么我们可以使用强制提供该函数的旧库。
就我而言,我用后面的方法解决了这个问题,找到旧版本的OpenSSL库(< 1.1.0, usually located under /lib64), and using LD_PRELOAD to specify them:
LD_PRELOAD=/lib64/libssl.so.1.0.2k:/lib64/libcrypto.so.1.0.2k yum update