在我的笔记本电脑中:
$ cat /etc/issue
Ubuntu 18.04 LTS \n \l
x86
库和有两个不同的文件夹x86_64
:
~$ ls -1 /
bin
lib
lib64
sbin
...
为什么二进制文件只存在一个目录?
PS 我也对 Android 感兴趣,但我希望答案应该是相同的。
答案1
首先,为什么有单独的/lib
和/lib64
:
这文件系统层次结构标准
提到分离/lib
和/lib64
存在是因为:
10.1.在支持多种需要单独库的二进制格式的系统上,/lib 目录可能有一种或多种变体。 (...) 这通常用于支持多种二进制格式但需要同名库的系统上的 64 位或 32 位支持。在这种情况下,/lib32 和 /lib64 可能是库目录,而 /lib 是其中之一的符号链接。
例如,在我的 Slackware 14.2 上, 分别有 32 位和 64 位库的目录,尽管它
/lib
不像FHS 代码片段所建议的那样是符号链接:/lib64
/lib
$ 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 包含系统管理员和用户都可以使用的命令,但在没有安装其他文件系统时(例如在单用户模式下)需要这些命令。它还可能包含由脚本间接使用的命令。
IMO 之所以没有单独的文件/bin
,/bin64
是因为如果我们在这两个目录中都有同名的文件,我们就无法间接调用其中一个,因为我们必须将/bin
or/bin64
放在第一个目录中
$PATH
。
但是,请注意,上面只是约定 - Linux 内核并不真正关心您是否有单独的/bin
和/bin64
。如果您需要它们,您可以创建它们并相应地设置您的系统。
你还提到了Android - 请注意,除了运行修改后的Linux内核之外,它与Ubuntu等GNU系统无关 - 没有glibc,没有bash(默认情况下,你当然可以手动编译和部署它),还有目录结构是完全不同的。
答案2
原因是 lib/lib64 目录可能包含恰好具有相同的文件姓名因为这些是与不同程序共享的库。将它们放在单独的目录中可以解决冲突。 (通常......)没有充分的理由在同一 32/64 位系统上分发同名的可执行文件,但由于可能存在混合的可执行文件,因此必须提供共享库。