有没有办法让编译器更喜欢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
的符号链接)的版本不同{ {1}}和/usr/lib
。然后,LIBRARY_PATH
将与ld
中的soname
相关联,/usr/lib
无法再对预期的库进行优先排序。
我第一次使用boost遇到了这个问题,但这是一个小例子:
LD_LIBRARY_PATH
我最初在GCC的自定义安装时遇到了这个问题,而它正在按照系统安装的预期工作。
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 --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/
在系统路径之前,GCC优先考虑一些“前缀”,包括LIBRARY_PATH
。这可以通过创建另一个符号链接来解决:
../lib64
我认为这与ln -s lib /tmp/XXX/lib64
期间的--libdir
参数有关,我在系统安装中省略了configure
,但即使我指定/usr/lib
,它也是更喜欢--libdir=$PREFIX/lib --libexecdir=$PREFIX/lib
。
如何在运行时编译或控制../lib64
,以便它至少使用gcc
代替../lib
后缀?
Clang更不合作。它在../lib64
的输出中不包含LIBRARY_PATH
,如果--print-search-dirs
已在-L/tmp/XXX/lib
中找到ld
,则libfoo.so
甚至不会包含/usr/lib
-L
。
如何让Clang透明地优先考虑我的库路径?
gcc --print-search-dirs
覆盖搜索顺序,但不透明。gcc -v
列出的目录多于import Chance from 'chance';
。后者过滤掉了不存在的路径。答案 0 :(得分:0)
我发现GCC的自定义安装不同的原因。 Debian发行版修补了GCC makefile,这就是它获得LIBRARY_PATH
正确优先级的方式。在构建GCC之前,找到gcc/config/i386/t-linux64
,然后将所有MULTILIB_OSDIRNAMES
更改为以下几行:
MULTILIB_OSDIRNAMES = m64=../lib$(call if_multiarch,:x86_64-linux-gnu)
MULTILIB_OSDIRNAMES+= m32=../lib32$(call if_multiarch,:i386-linux-gnu)
MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-linux-gnux32)
还将--libexecdir=/your/custom/path/lib --libdir=/your/custom/path/lib
添加到configure
。