TL;DR: 参考这篇文章来就好:https://blog.csdn.net/hsh969/article/details/106807219。如果你需要优先使用部分 conda动态库,就在此基础上在LD_LIBRARY_PATH
最开始再加一个你自己的lib文件夹,然后把需要的库拷过去。
发现
之前捣鼓环境的时候就遇到这个问题了,是参考开头提到文章解决的。但是随着我继续用conda环境来安装各种各样的非python库(热知识:conda是通用包管理器,可以安C/C++的库哦),和他们打交道的过程中又遇到一系列的问题,需要把LD_LIBRARY_PATH
中的$CONDA_PREFIX/lib
提到前面来解决,但是这一改又会导致这个问题的出现。于是我重新开始审视这个问题和之前的参考文章,并发现了一些它没提到的问题:
也就是说本质是因为这俩xz冲突了。
探索一些方案 (剧透:都不建议用)
到这里其实已经有一个可用的解决方案了:直接退出conda环境(其作用主要还是使得CONDA_PREFIX
没了,设置的LD_LIBRARY_PATH
就相当于/lib
,自然不会对yum产生影响)。但如果我们不想来回切换,有没有两全其美一劳永逸的办法呢?
我们当然不想改系统的库的版本,而且yum upgrade
也升级不上去。还得从conda这里动刀子。
能不能把conda的xz删掉呢?不能,conda remove xz
会自毁一样地导致一大堆基于xz的基础库也被remove掉,而我们现在并不想一个个重装他们,更不要说我们不知道这会带来多少问题。同理,也不能降级conda的xz使其和系统版本一致(也就是conda install xz=5.2.2
),conda会一通操作猛如虎,告诉你版本冲突,如果你尝试降级那些冲突的包,最后又会变成重装一大堆包。
还有一个办法就是,把$CONDA_PREFIX/lib
下的libcurl.so.4
和liblzma.so.5
等指向系统(相关版本换成你自己的):
cd $CONDA_PREFIX/lib
rm libcurl.so.4 libcurl.so liblzma.so.5 liblzma.so
ln -s /lib64/liblzma.so.5.2.2 liblzma.so.5
ln -s liblzma.so.5 liblzma.so
ln -s /lib64/libcurl.so.4.3.0 libcurl.so.4
ln -s libcurl.so.4 libcurl.so
这样之后yum list
确实没问题,但是这样破坏了conda的xz,它就跑不了了……不过conda自己似乎没受多大影响,conda install conda
是可以正常运行的。但是这毕竟不好,人家好好的5.2.5你给人家偷梁换柱换成5.2.2了。而且一堆包都是在此基础上的,会对conda环境造成多大影响我也不好说,总之先放一块恢复软连接的代码(相关版本换成你自己的):
cd $CONDA_PREFIX/lib
rm libcurl.so.4 libcurl.so liblzma.so.5 liblzma.so
ln -s liblzma.so.5.2.5 liblzma.so.5
ln -s liblzma.so.5 liblzma.so
ln -s libcurl.so.4.7.0 libcurl.so.4
ln -s libcurl.so.4 libcurl.so
……或者你也可以黑到底,把conda的xz的可执行文件也换成系统的(这又何尝不是一种NTR?)。但,5.2.2版本已经是2015年的老东西了,这么多年之间更新还是蛮多的,如果有些包用到了新特性,那还是要寄的。
最终方案与总结
在conda环境和系统环境都不能自己乱动的前提下,就只能继续从LD_LIBRARY_PATH
上做文章了:
- 如果你不需要优先使用conda安装的库(相比于使用系统库),那就还是按照开头那篇文章说的来设置
LD_LIBRARY_PATH
吧。别的办法,暂时我也找不到了,毕竟conda环境和系统,哪个都不能乱改。 - 如果需要优先用到个别conda的库(其实不限于conda安装的库),我们可以:
- 创建一个自己的lib文件夹(比如
~/lib
) - 把它添加到
LD_LIBRARY_PATH
的开头(如export LD_LIBRARY_PATH=~/lib:${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
) - 再把你需要用到的库拷贝到
~/lib
(还要建软连接什么的,当然你如果都在捣鼓这个了,那这个对你应该不难)
- 创建一个自己的lib文件夹(比如
总结:其实我一开始就应该优先考虑用最后这个方法的,因为它的影响范围小,操作很快也很容易。唯一的不足只是没从根本解决问题。不过也许这个方法最终也会遇到问题,比如A程序要用系统的P包,B程序又要用conda安装的P包(同名哦),不过这种情况下重新编译其中一个应该可以解决问题……如果可以重新编译的话。