是否有一种方法可使编译器更喜欢LIBRARY_PATH
中的库而不是系统路径。我特别在寻找Clang。在编写此问题时,我为GCC解决了部分问题,但也不太清楚。
LIBRARY_PATH
是方便的环境变量,允许透明地链接非标准目录中的库,例如用户安装,在我的情况下,这些环境模块提供库的[[不同版本。这个想法是做一个module load libfoo/version
,编译器将透明地使用正确的libfoo.so
。
LD_LIBRARY_PATH
设置为ld.so
才能找到正确的库。如果libfoo.so
和LD_LIBRARY_PATH
中都存在多个/usr/lib
,则ld.so
指定在默认路径之前搜索LD_LIBRARY_PATH
。问题
soname
时遇到了问题-在libfoo.so
和libfoo.so.1
中的两个libfoo.so.2
版本(分别是到/usr/lib
和LIBRARY_PATH
的符号链接)之间是不同的。然后,ld
将链接到soname
中的/usr/lib
,并且LD_LIBRARY_PATH
不能再对目标库进行优先级设置。我首先在boost上遇到了这个,但这是一个小例子:
echo "void foo() {}" > foo.c
# create an old libfoo version in /usr/lib
sudo gcc foo.c -fpic -shared -o /usr/lib/libfoo.so.1 -Wl,-soname,libfoo.so.1
sudo ln -s libfoo.so.1 /usr/lib/libfoo.so
# create the new libfoo that we want to transparently override
mkdir -p /tmp/XXX/lib
gcc foo.c -fpic -shared -o /tmp/XXX/lib/libfoo.so.2 -Wl,-soname,libfoo.so.2
ln -s libfoo.so.2 /tmp/XXX/lib/libfoo.so
export LIBRARY_PATH=/tmp/XXX/lib
export LD_LIBRARY_PATH=/tmp/XXX/lib
echo "void foo(); int main() { foo(); }" > main.c
gcc main.c -lfoo
ldd a.out| grep foo
# under some conditions this shows libfoo.so.1 instead of .2
libfoo.so.1 => /usr/lib/libfoo.so.1
GCC我最初在GCC的自定义安装过程中遇到了此问题,而该过程正在按系统安装的预期进行。
gcc --print-search-dirs
显示一个模式:
/tmp/XXX/lib/x86_64-pc-linux-gnu/7.2.0/ /tmp/XXX/lib/x86_64-linux-gnu/ /tmp/XXX/lib/../lib64/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../x86_64-pc-linux-gnu/lib/x86_64-pc-linux-gnu/7.2.0/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../x86_64-pc-linux-gnu/lib/x86_64-linux-gnu/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../x86_64-pc-linux-gnu/lib/../lib64/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../x86_64-pc-linux-gnu/7.2.0/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../x86_64-linux-gnu/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../lib64/ /lib/x86_64-pc-linux-gnu/7.2.0/ /lib/x86_64-linux-gnu/ /lib/../lib64/ /usr/lib/x86_64-pc-linux-gnu/7.2.0/ /usr/lib/x86_64-linux-gnu/ /usr/lib/../lib64/ /tmp/XXX/lib/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../x86_64-pc-linux-gnu/lib/ /opt/gcc/7.2.0/lib/gcc/x86_64-pc-linux-gnu/7.2.0/../../../ /lib/ /usr/lib/
除了常规搜索优先级-LIBRARY_PATH
在系统路径之前,GCC优先考虑一些“前缀”,包括../lib64
。可以通过创建另一个符号链接来解决此问题:
ln -s lib /tmp/XXX/lib64
我以为这与Clang--libdir
期间的configure
参数有关,在系统安装中我省略了该参数,在系统安装中为/usr/lib
,但是即使我指定了--libdir=$PREFIX/lib --libexecdir=$PREFIX/lib
,它还是更喜欢../lib64
。如何在运行时编译或控制
gcc
,以便至少使用../lib
而不是../lib64
后缀?
LIBRARY_PATH
中找到--print-search-dirs
,则它在-L/tmp/XXX/lib
的输出中不包含ld
,甚至不包含对libfoo.so
的调用中的/usr/lib
。如何让Clang透明地对我的库路径进行优先级排序?
注意-L
替代搜索顺序有效,但不透明。gcc --print-search-dirs
列出的目录多于gcc -v
。后者过滤掉不存在的路径。LIBRARY_PATH
正确优先级的方式。在构建GCC之前,找到gcc/config/i386/t-linux64
,然后将所有MULTILIB_OSDIRNAMES
更改为以下行: