Подтвердить что ты не робот

Несколько библиотек glibc на одном хосте

Несколько библиотек glibc на одном хосте

В моем сервере linux (SLES-8) в настоящее время есть glibc-2.2.5-235, но у меня есть программа, которая не будет работать в этой версии и требует glibc-2.3.3.

Возможно ли установить несколько glibcs ​​на один и тот же хост?

Это ошибка, которую я получаю при запуске моей программы на старом 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

и

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 и не собираются с того места, где я их помещал?

Спасибо

4b9b3361

Ответ 1

Очень возможно иметь несколько версий glibc в одной системе (мы делаем это каждый день).

Однако вам нужно знать, что glibc состоит из множества частей (200+ разделяемых библиотек), которые должны совпадать. Одна из частей - ld-linux.so.2, и она должна соответствовать libc.so.6, или вы увидите ошибки, которые видите.

Абсолютный путь к ld-linux.so.2 жестко закодирован в исполняемый файл во время соединения и не может быть легко изменен после завершения связи.

Чтобы создать исполняемый файл, который будет работать с новым glibc, сделайте следующее:

g++ main.o -o myapp ... \
   -Wl,--rpath=/path/to/newglibc \
   -Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2

Опция компоновщика -rpath заставит загрузчик времени выполнения искать библиотеки в /path/to/newglibc (поэтому вам не нужно было устанавливать LD_LIBRARY_PATH перед запуском), а опция -dynamic-linker будет "испечь" путь к верните ld-linux.so.2 в приложение.

Если вы не можете перенаправить приложение myapp (например, потому что это сторонний двоичный файл), не все потеряно, но становится сложнее. Одним из решений является установка для него надлежащей среды chroot. Другая возможность заключается в использовании rtldi и двоичный редактор.

Ответ 2

Этот вопрос старый, остальные ответы старые. Ответ "Занятого русского" очень хороший и информативный, но он работает только при наличии исходного кода. Если нет, альтернативы тогда были очень хитрыми. К счастью, в настоящее время у нас есть простое решение этой проблемы (как прокомментировано в одном из его ответов) с использованием patchelf. Все, что вам нужно сделать, это:

$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp

И после этого вы можете просто выполнить свой файл:

$ ./myapp

К счастью, нет необходимости chroot или редактировать двоичные файлы вручную. Но не забудьте сделать резервную копию вашего бинарного файла перед его исправлением, если вы не уверены, что делаете, потому что он изменяет ваш бинарный файл. После того, как вы исправите его, вы не сможете восстановить старый путь к интерпретатору /rpath. Если это не сработает, вам придется продолжать исправлять его, пока не найдете путь, который действительно будет работать... Ну, это не должен быть процесс проб и ошибок. Например, в примере с OP ему нужен GLIBC_2.3, поэтому вы можете легко найти, какая библиотека предоставляет эту версию, используя strings:

$ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
$ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3

Теоретически, первый grep будет пустым, потому что системный libc не имеет нужной версии, а второй должен вывести GLIBC_2.3, потому что у него есть версия, которую использует myapp, поэтому мы знаем, что можем patchelf наш бинарный файл, используя это дорожка.

Когда вы пытаетесь запустить бинарный файл в Linux, бинарный файл пытается загрузить компоновщик, а затем библиотеки, и все они должны быть в пути и/или в нужном месте. Если ваша проблема связана с компоновщиком, и вы хотите узнать, какой путь ищет ваш двоичный файл, вы можете узнать с помощью этой команды:

$ readelf -l myapp | grep interpreter
  [Requesting program interpreter: /lib/ld-linux.so.2]                                                                                                                                                                                   

Если ваша проблема с библиотеками, команды, которые дадут вам используемые библиотеки:

$ readelf -d myapp | grep Shared
$ ldd myapp 

Это перечислит библиотеки, которые нужны вашему бинарному файлу, но вы, вероятно, уже знаете проблемные, поскольку они уже дают ошибки, как в случае с OP.

"patchelf" работает для многих различных проблем, с которыми вы можете столкнуться при попытке запустить программу, связанных с этими двумя проблемами. Например, если вы получите: ELF file OS ABI invalid, это можно исправить, установив новый загрузчик (часть команды --set-interpreter), как я объясню здесь. Другой пример - проблема No such file or directory при запуске файла, который существует и является исполняемым, как показано здесь. В этом конкретном случае у OP отсутствовала ссылка на загрузчик, но, возможно, в вашем случае у вас нет root-доступа и вы не можете создать ссылку. Установка нового переводчика решит вашу проблему.

Спасибо Employed Russian и Михаилу Панкову за понимание и решение!

Ответ 3

Используйте LD_PRELOAD: поместите свою библиотеку где-нибудь из каталогов man lib и запустите:

LD_PRELOAD='mylibc.so anotherlib.so' program

Смотрите: статья в Википедии

Ответ 4

Прежде всего, наиболее важной зависимостью каждой динамически связанной программы является компоновщик. Все так библиотеки должны соответствовать версии компоновщика.

Возьмем простой пример: у меня есть система новостей ubuntu, в которой я запускаю некоторую программу (в моем случае это компилятор D - ldc2). Я хотел бы запустить его на старой CentOS, но из-за старой библиотеки glibc это невозможно. Я получил

ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)

Мне нужно скопировать все зависимости от ubuntu в centos. Правильный метод:

Сначала проверьте все зависимости:

ldd ldc2-1.5.0-linux-x86_64/bin/ldc2 
    linux-vdso.so.1 =>  (0x00007ffebad3f000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f965f597000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f965f378000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f965f15b000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f965ef57000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f965ec01000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f965e9ea000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f965e60a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f965f79f000)

linux-vdso.so.1 не является реальной библиотекой, и нам не нужно заботиться об этом.

/lib64/ld-linux-x86-64.so.2 - это компоновщик, который используется linux, связывает исполняемый файл со всеми динамическими библиотеками.

Остальные файлы являются настоящими библиотеками, и все они вместе с компоновщиком должны быть скопированы где-то в центрах.

Предположим, что все библиотеки и компоновщики находятся в каталоге "/mylibs".

ld-linux-x86-64.so.2 - как я уже сказал, - это компоновщик. Это не динамическая библиотека, а статический исполняемый файл. Вы можете запустить его и увидеть, что у него даже есть некоторые параметры, например, --library-path (я вернусь к нему).

В linux динамически связанная программа может быть запущена просто по ее имени, например

/bin/ldc2

Linux загружает такую ​​программу в оперативную память и проверяет, какой компоновщик установлен для нее. Обычно в 64-битной системе это /lib 64/ld-linux-x86-64.so.2 (в вашей файловой системе это символическая ссылка на реальный исполняемый файл). Затем linux запускает компоновщик и загружает динамические библиотеки.

Вы также можете немного изменить это и сделать такой трюк:

/mylibs/ld-linux-x86-64.so.2 /bin/ldc2

Это метод принуждения linux к использованию конкретного компоновщика.

И теперь мы можем вернуться к упомянутому ранее параметру -library-path

/mylibs/ld-linux-x86-64.so.2 --library-path /mylibs /bin/ldc2

Он запустит ldc2 и загрузит динамические библиотеки из /mylibs.

Это метод вызова исполняемого файла с выбранными (не системными) библиотеками.

Ответ 5

Можно ли использовать Nix http://nixos.org/nix/?

Nix поддерживает многопользовательское управление пакетами: несколько пользователей могут совместно использовать общий Nix-магазин надежно, не нужно иметь права root устанавливать программное обеспечение, а также устанавливать и использовать разные версии пакет.

Ответ 6

Настройка 1: скомпилируйте свой собственный glibc без выделенного GCC и используйте его

Эта настройка может работать и быстро, так как не перекомпилирует весь набор инструментов GCC, только glibc.

Но это ненадежно, так как использует объекты среды выполнения C, такие как crt1.o, crti.o и crtn.o предоставляемые glibc. Об этом упоминается по адресу: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location. Эти объекты выполняют раннюю настройку, на которую опирается glibc, поэтому я не удивлюсь, если что-нибудь не получится и удивительно тонкие способы.

Для более надежной настройки см. настройка 2 ниже.

Соберите glibc и установите локально:

export glibc_install="$(pwd)/glibc/build/install"

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
mkdir build
cd build
../configure --prefix "$glibc_install"
make -j 'nproc'
make install -j 'nproc'

Настройка 1: проверить сборку

test_glibc.c

#define _GNU_SOURCE
#include <assert.h>
#include <gnu/libc-version.h>
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>

atomic_int acnt;
int cnt;

int f(void* thr_data) {
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
    }
    return 0;
}

int main(int argc, char **argv) {
    /* Basic library version check. */
    printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());

    /* Exercise thrd_create from -pthread,
     * which is not present in glibc 2.27 in Ubuntu 18.04.
     * https://stackoverflow.com/questions/56810/how-do-i-start-threads-in-plain-c/52453291#52453291 */
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);
    printf("The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}

Скомпилируйте и запустите с test_glibc.sh:

#!/usr/bin/env bash
set -eux
gcc \
  -L "${glibc_install}/lib" \
  -I "${glibc_install}/include" \
  -Wl,--rpath="${glibc_install}/lib" \
  -Wl,--dynamic-linker="${glibc_install}/lib/ld-linux-x86-64.so.2" \
  -std=c11 \
  -o test_glibc.out \
  -v \
  test_glibc.c \
  -pthread \
;
ldd ./test_glibc.out
./test_glibc.out

Программа выводит ожидаемое:

gnu_get_libc_version() = 2.28
The atomic counter is 10000
The non-atomic counter is 8674

Команда адаптирована из https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location, но --sysroot:

cannot find /home/ciro/glibc/build/install/lib/libc.so.6 inside /home/ciro/glibc/build/install

так что я его убрал.

Вывод ldd подтверждает, что ldd и библиотеки, которые мы только что создали, фактически используются должным образом:

+ ldd test_glibc.out
        linux-vdso.so.1 (0x00007ffe4bfd3000)
        libpthread.so.0 => /home/ciro/glibc/build/install/lib/libpthread.so.0 (0x00007fc12ed92000)
        libc.so.6 => /home/ciro/glibc/build/install/lib/libc.so.6 (0x00007fc12e9dc000)
        /home/ciro/glibc/build/install/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fc12f1b3000)

Вывод отладочной информации компиляции gcc показывает, что использовались мои объекты среды выполнения хоста, что плохо, как упоминалось ранее, но я не знаю, как обойти это, например, он содержит:

COLLECT_GCC_OPTIONS=/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crt1.o

Настройка 1: изменить glibc

Теперь давайте изменим glibc:

diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
index 113ba0d93e..b00f088abb 100644
--- a/nptl/thrd_create.c
+++ b/nptl/thrd_create.c
@@ -16,11 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */

+#include <stdio.h>
+
 #include "thrd_priv.h"

 int
 thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
 {
+  puts("hacked");
   _Static_assert (sizeof (thr) == sizeof (pthread_t),
                   "sizeof (thr) != sizeof (pthread_t)");

Затем перекомпилируйте и переустановите glibc, перекомпилируйте и перезапустите нашу программу:

cd glibc/build
make -j 'nproc'
make -j 'nproc' install
./test_glibc.sh

и мы видим hacked напечатанный несколько раз, как и ожидалось.

Это еще раз подтверждает, что мы фактически использовали скомпилированный glibc, а не хост.

Проверено на Ubuntu 18.04.

Настройка 2: первоначальная настройка crosstool-NG

Это альтернатива настройке 1, и это наиболее правильная установка, которую я достиг до сих пор: насколько я могу наблюдать, все правильно, включая объекты времени выполнения C, такие как crt1.o, crti.o и crtn.o,

В этой настройке мы скомпилируем полный выделенный набор инструментов GCC, который использует glibc, который мы хотим.

Единственным недостатком этого метода является то, что сборка займет больше времени. Но я бы не стал рисковать настройкой производства чем-то меньшим.

crosstool-NG - это набор скриптов, который загружает и компилирует для нас все из исходного кода, включая GCC, glibc и binutils.

Да, система сборки GCC настолько плоха, что для этого нам нужен отдельный проект.

Эта настройка не идеальна, потому что crosstool-NG не поддерживает -Wl исполняемых файлов без дополнительных флагов -Wl, что странно, так как мы создали сам GCC. Но все, кажется, работает, так что это только неудобство.

Получите crosstool-NG, настройте и соберите его:

git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout a6580b8e8b55345a5a342b5bd96e42c83e640ac5
export CT_PREFIX="$(pwd)/.build/install"
export PATH="/usr/lib/ccache:${PATH}"
./bootstrap
./configure --enable-local
make -j 'nproc'
./ct-ng x86_64-unknown-linux-gnu
./ct-ng menuconfig
env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS='nproc'

Сборка занимает от тридцати минут до двух часов.

Единственный обязательный параметр конфигурации, который я вижу, - это соответствие версии ядра вашего хоста для использования правильных заголовков ядра. Найдите версию ядра своего хоста с помощью:

uname -a

который показывает мне:

4.15.0-34-generic

так в menuconfig я делаю:

  • Operating System
    • Version of linux

поэтому я выбираю:

4.14.71

которая является первой равной или более старой версией. Он должен быть старше, поскольку ядро обратно совместимо.

Настройка 2: дополнительные конфигурации

.config который мы сгенерировали с помощью ./ct-ng x86_64-unknown-linux-gnu имеет:

CT_GLIBC_V_2_27=y

Чтобы изменить это, в menuconfig выполните:

  • C-library
  • Version of glibc

сохраните .config и продолжайте сборку.

Или, если вы хотите использовать свой собственный исходный код glibc, например, чтобы использовать glibc из последней версии git, выполните следующее:

  • Paths and misc options
    • Try features marked as EXPERIMENTAL: установите в true
  • C-library
    • Source of glibc
      • Custom location: скажи да
      • Custom location
        • Custom source location: укажите на каталог, содержащий ваш исходный код glibc

где glibc был клонирован как:

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28

Настройка 2: проверить это

Как только вы соберете нужный набор инструментов, протестируйте его с помощью:

#!/usr/bin/env bash
set -eux
install_dir="${CT_PREFIX}/x86_64-unknown-linux-gnu"
PATH="${PATH}:${install_dir}/bin" \
  x86_64-unknown-linux-gnu-gcc \
  -Wl,--dynamic-linker="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2" \
  -Wl,--rpath="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib" \
  -v \
  -o test_glibc.out \
  test_glibc.c \
  -pthread \
;
ldd test_glibc.out
./test_glibc.out

Кажется, все работает как в программе установки 1, за исключением того, что теперь использовались правильные объекты времени выполнения:

COLLECT_GCC_OPTIONS=/home/ciro/crosstool-ng/.build/install/x86_64-unknown-linux-gnu/bin/../x86_64-unknown-linux-gnu/sysroot/usr/lib/../lib64/crt1.o

Установка 2: неудачная попытка перекомпиляции glibc

Это не представляется возможным с Crosstool-NG, как объяснено ниже.

Если вы просто перестроить;

env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS='nproc'

тогда ваши изменения в пользовательском расположении источника glibc будут приняты во внимание, но он строит все с нуля, что делает его непригодным для итеративной разработки.

Если мы делаем:

./ct-ng list-steps

он дает хороший обзор шагов сборки:

Available build steps, in order:
  - companion_tools_for_build
  - companion_libs_for_build
  - binutils_for_build
  - companion_tools_for_host
  - companion_libs_for_host
  - binutils_for_host
  - cc_core_pass_1
  - kernel_headers
  - libc_start_files
  - cc_core_pass_2
  - libc
  - cc_for_build
  - cc_for_host
  - libc_post_cc
  - companion_libs_for_target
  - binutils_for_target
  - debug
  - test_suite
  - finish
Use "<step>" as action to execute only that step.
Use "+<step>" as action to execute up to that step.
Use "<step>+" as action to execute from that step onward.

поэтому мы видим, что есть этапы glibc, переплетенные с несколькими этапами GCC, прежде всего libc_start_files предшествует cc_core_pass_2, который, вероятно, является самым дорогим шагом вместе с cc_core_pass_1.

Чтобы построить только один шаг, вы должны сначала установить опцию "Сохранить промежуточные шаги" в .config для начальной сборки:

  • Paths and misc options
    • Debug crosstool-NG
      • Save intermediate steps

и тогда вы можете попробовать:

env -u LD_LIBRARY_PATH time ./ct-ng libc+ -j'nproc'

но, к сожалению, + требуется, как указано на: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536

Однако обратите внимание, что перезапуск с промежуточного шага сбрасывает каталог установки в состояние, в котором он находился на этом шаге. Т.е. у вас будет перестроенный libc, но нет окончательного компилятора, скомпилированного с этим libc (и, следовательно, также нет библиотек компиляторов, таких как libstdc++).

и в основном все еще делает перестройку слишком медленной, чтобы ее можно было реализовать для разработки, и я не вижу, как преодолеть это, не исправляя crosstool-NG.

Кроме того, начиная с шага libc, похоже, больше не копируете исходный код из Custom source location, что делает этот метод непригодным для использования.

Бонус: stdlibc++

Бонус, если вы также заинтересованы в стандартной библиотеке C++: Как отредактировать и перестроить исходный код стандартной библиотеки GCC libstdc++ C++?

Ответ 7

Если вы посмотрите внимательно на второй вывод, вы увидите, что используется новое место для библиотек. Возможно, все еще отсутствуют библиотеки, которые являются частью glibc.

Я также думаю, что все библиотеки, используемые вашей программой, должны быть скомпилированы против этой версии glibc. Если у вас есть доступ к исходному коду программы, свежая компиляция представляется лучшим решением.

Ответ 8

"Занятый русский" - один из лучших ответов, и я думаю, что любой другой предлагаемый ответ может не работать. Причина в том, что, когда приложение впервые создано, все его API-интерфейсы, которые ему нужны, разрешаются во время компиляции. Использование "ldd" u может видеть все статически связанные зависимости:

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/,/usr/lib/x86 и т.д. Вы можете использовать "Buildroot", или YoctoProject, или только tar из существующей среды Distro. (например, Fedora/Suse и т.д.).

Ответ 9

Я не уверен, что вопрос по-прежнему актуальный, но есть еще один способ решить проблему: Docker. Можно установить почти пустой контейнер Source Distribution (Распространение, используемый для разработки), и скопировать файлы в Container. Таким образом, вам не нужно создавать файловую систему, необходимую для chroot.

Ответ 10

Когда я захотел запустить хромированный браузер на точной Ubuntu (glibc-2.15), я получил (типичное) сообщение "... libc.so.6: version" GLIBC_2.19 "не найден...". Я считал, что файлы не нужны постоянно, но только для начала. Поэтому я собрал файлы, необходимые для браузера и sudo, и создал среду mini-glibc-2. 19-, запустил браузер, а затем снова скопировал исходные файлы. Необходимые файлы находятся в ОЗУ, а оригинальный 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

Ответ 11

@msb дает безопасное решение.

Я столкнулся с этой проблемой, когда import tensorflow as tf в среде import tensorflow as tf в CentOS 6.5 которая имеет только glibc-2.12.

ImportError: /lib64/libc.so.6: version 'GLIBC_2.16' not found (required by /home/

Я хочу предоставить некоторые детали:

Сначала установите glibc в свой домашний каталог:

mkdir ~/glibc-install; cd ~/glibc-install
wget http://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.gz
tar -zxvf glibc-2.17.tar.gz
cd glibc-2.17
mkdir build
cd build
../configure --prefix=/home/myself/opt/glibc-2.17  # <-- where you install new glibc
make -j<number of CPU Cores>  # You can find your <number of CPU Cores> by using **nproc** command
make install

Во-вторых, следуйте тем же способом, чтобы установить patchelf;

В-третьих, исправьте ваш Python:

[[email protected] ~]$ patchelf --set-interpreter /home/myself/opt/glibc-2.17/lib/ld-linux-x86-64.so.2 --set-rpath /home/myself/opt/glibc-2.17/lib/ /home/myself/miniconda3/envs/tensorflow/bin/python

как упомянуто @msb

Теперь я могу использовать tensorflow-2.0 alpha в CentOS 6.5.

ссылка: https://serverkurma.com/linux/how-to-update-glibc-newer-version-on-centos-6-x/