
В моем ноутбуке:
$ cat /etc/issue
Ubuntu 18.04 LTS \n \l
x86
Для библиотек существуют две разные папки x86_64
:
~$ ls -1 /
bin
lib
lib64
sbin
...
Почему для двоичных файлов существует только один каталог?
PS Меня также интересует Android, но я надеюсь, что ответ будет таким же.
решение1
Во-первых, почему существуют отдельные /lib
и /lib64
:
TheСтандарт иерархии файловой системы
упоминает, что они разделяются /lib
и /lib64
существуют, потому что:
10.1. Может быть один или несколько вариантов каталога /lib в системах, которые поддерживают более одного двоичного формата, требующего отдельных библиотек. (...) Это обычно используется для 64- или 32-битной поддержки в системах, которые поддерживают несколько двоичных форматов, но требуют библиотек с одинаковыми именами. В этом случае /lib32 и /lib64 могут быть каталогами библиотек, а /lib — символической ссылкой на один из них.
Например, в моем Slackware 14.2 есть /lib
и /lib64
каталоги для 32-битных и 64-битных библиотек соответственно, хотя
/lib
это и не символическая ссылка, как предполагает фрагмент FHS:
$ ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11 2016 /lib/libc.so.6 -> libc-2.23.so
$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11 2016 /lib64/libc.so.6 -> libc-2.23.so
Есть две libc.so.6
библиотеки в /lib
и /lib64
.
Каждый динамически построенный
двоичный файл ELF
содержит жестко заданный путь к интерпретатору, в данном случае либо ,
/lib/ld-linux.so.2
либо /lib64/ld-linux-x86-64.so.2
:
$ file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
$ readelf -a main | grep 'Requesting program interpreter'
[Requesting program interpreter: /lib/ld-linux.so.2]
$ file ./main64
./main64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
$ readelf -a main64 | grep 'Requesting program interpreter'
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
Работа интерпретатора заключается в загрузке необходимых разделяемых библиотек. Вы можете спросить интерпретатор GNU, какие библиотеки он будет загружать, даже не запуская двоичный файл с использованием LD_TRACE_LOADED_OBJECTS=1
или ldd
оберткой:
$ LD_TRACE_LOADED_OBJECTS=1 ./main
linux-gate.so.1 (0xf77a9000)
libc.so.6 => /lib/libc.so.6 (0xf760e000)
/lib/ld-linux.so.2 (0xf77aa000)
$ LD_TRACE_LOADED_OBJECTS=1 ./main64
linux-vdso.so.1 (0x00007ffd535b3000)
libc.so.6 => /lib64/libc.so.6 (0x00007f56830b3000)
/lib64/ld-linux-x86-64.so.2 (0x00007f568347c000)
Как видите, данный интерпретатор точно знает, где искать библиотеки — 32-разрядная версия ищет библиотеки в , /lib
а 64-разрядная версия ищет библиотеки в /lib64
.
Стандарт FHS гласит следующее /bin
:
/bin содержит команды, которые могут использоваться как системным администратором, так и пользователями, но которые требуются, когда не смонтированы другие файловые системы (например, в однопользовательском режиме). Он также может содержать команды, которые используются косвенно скриптами.
По моему мнению, причина отсутствия отдельных файлов /bin
заключается /bin64
в том, что если бы у нас был файл с одинаковым именем в обоих этих каталогах, мы не смогли бы вызвать один из них косвенно, поскольку нам пришлось бы сначала поместить /bin
или /bin64
в
$PATH
.
Однако обратите внимание, что вышеизложенное является всего лишь соглашением — ядру Linux на самом деле все равно, есть ли у вас отдельные /bin
и /bin64
. Если они вам нужны, вы можете создать их и настроить свою систему соответствующим образом.
Вы также упомянули Android — обратите внимание, что за исключением работы модифицированного ядра Linux, он не имеет ничего общего с системами GNU, такими как Ubuntu — нет glibc, нет bash (по умолчанию, вы, конечно, можете скомпилировать и развернуть его вручную), а также структура каталогов совершенно другая.
решение2
Причина в том, что каталоги lib/lib64 могут содержать файлы, которые имеют одинаковыеимяпотому что это библиотеки, используемые совместно с различными программами. Размещение их в отдельных каталогах решает конфликт. Нет (обычно...) веской причины для распространения исполняемых файлов с одинаковыми именами в одной и той же системе, которая является 32/64-битной, но поскольку может быть смесь исполняемых файлов, общие библиотеки должны быть предусмотрены.