【问题标题】:Priority of LIBRARY_PATH with custom gcc installations带有自定义 gcc 安装的 LIBRARY_PATH 的优先级
【发布时间】:2018-04-25 04:31:12
【问题描述】:

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

背景

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

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

问题

当库定义 soname 时遇到问题 - 这在 /usr/libLIBRARY_PATH 中的两个 libfoo.so 版本(分别是 libfoo.so.1libfoo.so.2 的符号链接)之间是不同的。然后ld 将链接到/usr/lib 中的sonameLD_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 --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

我以为这和configure时的--libdir参数有关,我在系统安装时省略了,是/usr/lib,但即使我指定--libdir=$PREFIX/lib --libexecdir=$PREFIX/lib,它也更喜欢../lib64

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

叮当

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

如何让 Clang 透明地确定我的库路径的优先级?

注意事项

【问题讨论】:

  • 一个特别难看但可行的解决方案是围绕gccccg++c++ 进行包装,并在那里强制使用适当的-L
  • 自定义规格文件可以解决您的问题。详情请见https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html
  • @nit 我不确定从这个文件的哪里开始。只有 4 次提到“图书馆/IES”,而且似乎都没有提到我的问题。您能否以答案的形式详细说明?
  • 你找到解决办法了吗?
  • 不超出问题中所写的内容。

标签: gcc linker clang ld


【解决方案1】:

我发现了自定义安装 GCC 不同的原因。 Debian 发行版修补了 GCC 生成文件,这就是它如何获得正确的优先级 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

【讨论】:

    猜你喜欢
    • 2012-03-03
    • 2011-04-01
    • 2020-04-15
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多