我的linux (SLES-8)服务器目前有glibc-2.2.5-235,但我有一个程序不能在这个版本上工作,需要glibc-2.3.3。

是否可以在同一台主机上安装多个glibc ?

这是我在旧的glibc上运行程序时得到的错误:

./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./myapp)
./myapp: /lib/i686/libpthread.so.0: version `GLIBC_2.3.2' not found (required by ./myapp)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libxerces-c.so.27)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)

所以我创建了一个名为newglibc的新目录,并复制了以下文件:

libpthread.so.0
libm.so.6
libc.so.6
ld-2.3.3.so
ld-linux.so.2 -> ld-2.3.3.so

and

export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH

但是我得到一个错误:

./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libpthread.so.0)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by libstdc++.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libm.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./newglibc/libc.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libc.so.6)

因此,它们似乎仍然链接到/lib,而不是从我放置它们的位置拾取。


当前回答

使用LD_PRELOAD: 把你的库放在man lib目录之外的地方,然后运行:

LD_PRELOAD='mylibc.so anotherlib.so' program

参见:维基百科的文章

其他回答

当我想在Ubuntu precise (glibc-2.15)上运行chromium浏览器时,我得到了 (典型的)消息“…libc.so。6:版本' GLIBC_2.19'未找到…" 我考虑了这样一个事实,即文件不是永久需要的,而只是在开始时需要。 因此,我收集了浏览器和sudo所需的文件,并创建了一个mini-glibc-2.19- 环境,启动浏览器,然后将原始文件复制回来 一次。所需的文件在RAM中,原始的glibc是相同的。

as root
the files (*-2.15.so) already exist 

Mkdir -p /glibc-2.19/i386-linux-gnu

/glibc-2.19/ld-linux.so.2 -> /glibc-2.19/i386-linux-gnu/ld-2.19.so
/glibc-2.19/i386-linux-gnu/libc.so.6 -> libc-2.19.so
/glibc-2.19/i386-linux-gnu/libdl.so.2 -> libdl-2.19.so
/glibc-2.19/i386-linux-gnu/libpthread.so.0 -> libpthread-2.19.so

Mkdir -p /glibc-2.15/i386-linux-gnu

/glibc-2.15/ld-linux.so.2 -> (/glibc-2.15/i386-linux-gnu/ld-2.15.so)
/glibc-2.15/i386-linux-gnu/libc.so.6 -> (libc-2.15.so)
/glibc-2.15/i386-linux-gnu/libdl.so.2 -> (libdl-2.15.so)
/glibc-2.15/i386-linux-gnu/libpthread.so.0 -> (libpthread-2.15.so)

运行浏览器的脚本:

#!/bin/sh
sudo cp -r /glibc-2.19/* /lib
/path/to/the/browser &
sleep 1
sudo cp -r /glibc-2.15/* /lib
sudo rm -r /lib/i386-linux-gnu/*-2.19.so

你可以考虑使用Nix http://nixos.org/nix/吗?

Nix支持多用户包管理:多个用户可以共享一个 普通Nix存储安全,不需要有root权限即可 安装软件,并可以安装和使用不同版本的一个 包中。

“受雇的俄罗斯人”是最好的答案之一,我认为所有其他建议的答案可能都行不通。原因很简单,因为当应用程序第一次创建时,它需要的所有api都在编译时解析。使用"ldd"你可以看到所有静态链接的依赖项:

ldd /usr/lib/firefox/firefox
    linux-vdso.so.1 =>  (0x00007ffd5c5f0000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f727e708000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f727e500000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f727e1f8000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f727def0000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f727db28000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f727eb78000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f727d910000)

但在运行时,firefox也会加载许多其他动态库,例如(对于firefox)有许多“glib”标记的库加载(即使静态链接没有):

 /usr/lib/x86_64-linux-gnu/libdbus-glib-1.so.2.2.2
 /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0
 /usr/lib/x86_64-linux-gnu/libavahi-glib.so.1.0.2

很多时候,您可以看到一个版本的名称被软链接到另一个版本。例如:

lrwxrwxrwx 1 root root     23 Dec 21  2014 libdbus-glib-1.so.2 -> libdbus-glib-1.so.2.2.2
-rw-r--r-- 1 root root 160832 Mar  1  2013 libdbus-glib-1.so.2.2.2

因此,这意味着在一个系统中存在不同版本的“库”——这不是问题,因为它们是同一个文件,而且当应用程序具有多个版本依赖关系时,它将提供兼容性。

因此,在系统级别上,所有的库几乎都是相互依赖的,仅仅通过操纵LD_PRELOAD或LD_LIBRARY_PATH来改变库的加载优先级是没有帮助的——即使它可以加载,运行时它仍然可能崩溃。

http://lightofdawn.org/wiki/wiki.cgi/-wiki/NewAppsOnOldGlibc

最好的替代方案是chroot (ER简要提到过):但为此你需要重新创建原始二进制执行的整个环境——通常从/lib, /usr/lib/x86等开始。你可以使用“builroot”,或者YoctoProject,或者直接从现有的发行版环境中tar。(比如Fedora/Suse等)。

使用LD_PRELOAD: 把你的库放在man lib目录之外的地方,然后运行:

LD_PRELOAD='mylibc.so anotherlib.so' program

参见:维基百科的文章

如果仔细观察第二个输出,可以看到使用了库的新位置。可能仍然有作为glibc一部分的库丢失。

我还认为您的程序使用的所有库都应该根据该glibc版本进行编译。如果您可以访问程序的源代码,那么重新编译似乎是最好的解决方案。