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

Zul*_*lan 6 linker gcc clang ld

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

背景

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

对于共享库,一个还需要设置LD_LIBRARY_PATHld.so找到合适的库.如果有多个libfoo.so在这两个LD_LIBRARY_PATH/usr/lib,ld.so指定LD_LIBRARY_PATH之前默认路径搜索.

问题

我在库定义了一个问题时遇到了问题soname- 两个libfoo.so版本(分别是符号链接libfoo.so.1libfoo.so.2分别是和)的/usr/lib和不同LIBRARY_PATH.然后ld将链接到sonamein /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
Run Code Online (Sandbox Code Playgroud)

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/
Run Code Online (Sandbox Code Playgroud)

除了正常的搜索优先级 - LIBRARY_PATH系统路径之前,GCC优先考虑一些"前缀",包括../lib64.这可以通过创建另一个符号链接来解决:

ln -s lib /tmp/XXX/lib64
Run Code Online (Sandbox Code Playgroud)

我认为这与--libdir参数期间有关configure,我省略了它并且/usr/lib在系统安装中,但即使我指定--libdir=$PREFIX/lib --libexecdir=$PREFIX/lib,它也更喜欢../lib64.

如何gcc在运行时编译或控制,以便它至少使用 ../lib而不是../lib64后缀?

Clang更不合作.它不包括LIBRARY_PATH在输出中--print-search-dirs,甚至不包括-L/tmp/XXX/lib它的调用,ld如果libfoo.so可以找到它/usr/lib.

如何让Clang透明地优先考虑我的库路径?

笔记

fac*_*tus 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)
Run Code Online (Sandbox Code Playgroud)

还添加--libexecdir=/your/custom/path/lib --libdir=/your/custom/path/libconfigure.