Обратите внимание, что команды React и Redux обычно препятствуют использованию декораторов. Вместо этого в этом случае вы должны использовать функцию connect()
как функцию:
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
Очень возможно иметь несколько версий 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 и двоичный редактор .
Прежде всего, самая важная зависимость каждой динамически связанной программы - это компоновщик. Все библиотеки должны соответствовать версии компоновщика.
Давайте возьмем простой пример: у меня есть система новостей 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 do, связывает исполняемый файл со всеми динамическими библиотеками.
Остальные файлы являются реальными библиотеками, и все они вместе с компоновщиком должны быть скопированы где-то в центрах.
Предположим, что все библиотеки и компоновщики находятся в каталоге «/ mylibs».
ld-linux-x86-64.so.2 - как я уже сказал, - это компоновщик. Это не динамическая библиотека, а статический исполняемый файл. Вы можете запустить его и увидеть, что у него даже есть некоторые параметры, например, -library-path (я вернусь к нему).
В linux динамически связанная программа может быть отправлена только по ее имени, например
/bin/ldc2
Linux загружает такую программу в ОЗУ и проверяет, какой компоновщик установлен для нее. Обычно в 64-битной системе это /lib64/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.
Это метод вызова исполняемого файла с выбранными (не системными) библиотеками.
Когда я хотел запустить Chrome-браузер в точном соответствии с 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
Вы можете использовать Nix http://nixos.org/nix/ ?
Nix поддерживает многопользовательское управление пакетами: несколько пользователей могут совместно использовать общий Nix хранить надежно, не нужно иметь права root для установки программного обеспечения, а также устанавливать и использовать разные версии пакета.
blockquote>
Этот вопрос старый, другие ответы старые. Ответ «Ответственный русский» очень хорош и информативен, но он работает только в том случае, если у вас есть исходный код. Если вы этого не сделаете, альтернативы тогда были очень сложными. К счастью, в наше время у нас есть простое решение этой проблемы (как прокомментировано в одном из его ответов), используя patchelf . Все, что вам нужно сделать, это:
$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp
И после этого вы можете просто выполнить свой файл:
$ ./myapp
Не нужно chroot
или вручную редактировать двоичные файлы, к счастью , Но не забудьте сделать резервную копию своего двоичного файла, прежде чем исправлять его, если вы не уверены, что делаете, потому что он изменяет ваш двоичный файл. После этого вы не сможете восстановить старый путь к интерпретатору / rpath. Если это не сработает, вам нужно будет исправлять его до тех пор, пока не найдете путь, который действительно будет работать ... Ну, это не должен быть процесс проб и ошибок. Например, в примере OP ему понадобился GLIBC_2.3
, поэтому вы можете легко найти, какая lib предоставляет эту версию, используя 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]
Если ваша проблема связана с libs, команды, которые будут дайте вам используемые libs:
$ readelf -d myapp | grep Shared
$ ldd myapp
Это приведет к отображению библиотек, которые нужны вашим двоичным файлам, но вы, вероятно, уже знаете проблемные, поскольку они уже дают ошибки, как в случае OP.
«patchelf» работает для множества различных проблем, с которыми вы можете столкнуться при попытке запустить программу, связанную с этими двумя проблемами. Например, если вы получаете: ELF file OS ABI invalid
, это может быть исправлено установкой нового загрузчика (часть --set-interpreter
команды), поскольку я объясняю здесь здесь . Другой пример - проблема получения No such file or directory
при запуске файла, который есть и исполняемый, например здесь . В этом конкретном случае OP отсутствовала ссылка на загрузчика, но, возможно, в вашем случае у вас нет доступа root и не может создать ссылку. Настройка нового интерпретатора решит вашу проблему.
Спасибо. Занимался русским и Майклом Панковым за понимание и решение!
patchelf
), но фраза «Нет необходимости ... редактировать двоичные файлы»; может немного ввести в заблуждение (поскольку вы фактически редактируете свои двоичные файлы).
– larsks
4 December 2017 в 02:17
«Занятый русский» - один из лучших ответов, и я думаю, что любой другой предлагаемый ответ может не сработать. Причина в том, что, когда приложение впервые создано, все его 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 и т. д.).
Используйте LD_PRELOAD: выложите свою библиотеку где-нибудь из каталогов man lib и запустите:
LD_PRELOAD='mylibc.so anotherlib.so' program
Смотрите: статья Википедии
Если вы внимательно посмотрите на второй вывод, вы увидите, что используется новое место для библиотек. Возможно, все еще отсутствуют библиотеки, которые являются частью glibc.
Я также считаю, что все библиотеки, используемые вашей программой, должны быть скомпилированы против этой версии glibc. Если у вас есть доступ к исходному коду программы, свежая компиляция представляется лучшим решением.
Я не уверен, что вопрос по-прежнему актуальный, но есть еще один способ решить проблему: Docker. Можно установить почти пустой контейнер Source Distribution (Распространение, используемый для разработки), и скопировать файлы в Container. Таким образом, вам не нужно создавать файловую систему, необходимую для chroot.
-Wl,--dynamic-linker=file
(принимает два '-') работает только при компиляции для исполняемых файлов ELF. Проверьте/sbin/ldconfig -p | grep ld
– Tom 28 May 2012 в 15:08patchelf
( nixos.org/patchelf.html ), которая позволяет вам изменять rpath и интерпретатор уже скомпилированного ELF. – Michael Pankov 13 February 2013 в 14:14-Wl,--rpath
, а неLD_LIBRARY_PATH
может быть важным по причинам, отличным от удобства: если программа запускает дочерние процессы, значениеLD_LIBRARY_PATH
обычно наследуется ими, но если они также не скомпилированы для использования нового glibc (например, если они представляют собой двоичные файлы, напримерbash
), они не будут запускаться. – HighCommander4 5 June 2016 в 02:22/path/to/newglibc/ld-linux.so.2 --library-path /path/tonewglibc/lib64:/path/to/newglibc/usr/lib64 /path/to/myapp
– maximk 14 September 2016 в 11:09