我们的计算集群运行一个非常旧版本的 CentOS,具有旧的内核 (2.6.18),当然还有旧的库和二进制文件。由于更新整个内容需要在所有节点上进行大量工作,因此这不是一个选择。
C++11
我正在尝试编译和使用需要更新版本的gcc
(和/或) 的程序clang
。因为我根本不想搞乱系统,所以我想以非 root 用户身份在某个本地目录树中执行此操作。
问题是,这需要比机器上现有的gcc
更新。glibc
因此,我需要glibc
在本地维护一个单独的更新版本lib/
树中维护一个单独的更新版本,可能如所述这里。
我迷失的是,如何将本地库的路径“硬编码”到所有必需的二进制文件中,即,gcc
等等g++
?将 LD_LIBRARY_PATH 设置为我的本地lib/
树会导致所有系统二进制文件不再工作 ( ELF file OS ABI invalid
),因为它们想要使用我的新libm.so
/libc.so
尚未编译的文件。
那么,总结一下:与旧系统并行维护较新的本地开发堆栈(包含 等)而不用 root 身份搞乱的glibc
正确方法是什么?gcc
作为一个附带问题:当涉及到单独的glibc
.对我来说,当我尝试执行任何系统二进制文件(例如ls
)时,它会导致上述错误。怎么会?我做错了什么还是这是预期的行为?
答案1
您基本上有三个选择:
在你的库周围使用一个包装器,它将进行
LD_LIBRARY_PATH
适当的设置,然后执行所需的库 - 类似于:#!/bin/sh export LD_LIBRARY_PATH="path/goes/here" exec "$@"
-rpath
使用( )链接-Wl,rpath
,将动态链接器的搜索路径添加到二进制文件中(另请参见所以答案- 它还提到了包装纸)。你不会喜欢读这篇文章:更新你的集群(注意强调“你的”)。迟早有一天会完成,所以为什么不是今天。“不是一个选择”大多数情况下有点强。其他用户可能也有同样的问题。
至于有问题的旧二进制文件 - 二进制文件中嵌入了其首选的动态链接器。而且旧的动态链接器不理解新的 ABI。尝试像这样调用二进制文件:path/to/your/ld-linux-<arch>.so binary
。
构建 GCC:您始终可以尝试CFLAGS
在 GCC 的构建环境中导出 - 但我确信它们会被传播。各种发行版的构建脚本可能会给您一些线索(例如:对于 openSUSE,请查看第 1880 行).spec 文件)。