具有自定义gcc安装的LIBRARY_PATH的优先级

时间:2017-11-12 11:32:43

标签: gcc linker clang ld

有没有办法让编译器更喜欢LIBRARY_PATH的库而不是系统路径。我特别想找Clang。在写这个问题时,我部分解决了GCC的问题,但也不太清楚。

背景

LIBRARY_PATH是一个方便的环境变量,允许透明地链接非标准目录中的库,例如用户安装,以及在我的案例中提供库的不同版本的环境模块。 我的想法是做module load libfoo/version,编译器将透明地使用正确的libfoo.so

对于共享库,还需要为LD_LIBRARY_PATH设置ld.so以找到正确的库。如果libfoo.soLD_LIBRARY_PATH中有多个/usr/lib,则ld.so指定在默认路径之前搜索LD_LIBRARY_PATH

问题

我在库定义soname时遇到了问题 - libfoo.so版本(分别是libfoo.so.1libfoo.so.2的符号链接)的版本不同{ {1}}和/usr/lib。然后,LIBRARY_PATH将与ld中的soname相关联,/usr/lib无法再对预期的库进行优先排序。

我第一次使用boost遇到了这个问题,但这是一个小例子:

LD_LIBRARY_PATH

GCC

我最初在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透明地优先考虑我的库路径?

注释

1 个答案:

答案 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