Files
build_infra/0_笔记/linux打包.txt
T
2026-06-16 10:23:51 +08:00

184 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
linux使用最佳实践:
1.使用稳定linux发行版。
2.永远不要把库下载到自己的系统目录下,要安装到自己定义的--installroot里,而且尽量使用装系统的iso源,永远不更新
3.自己编译安装的库,不要放入--installroot里,要放入单独的目录中
并且目录结构遵循
├─best_env
│ ├─iso_repo //挂载装系统的iso,或者直接就是iso的文件
│ └─iso_root //从iso源下载的库,目录结构和系统根目录一样
│ ├─...
│ └─...
│ └─src //存放源码的tar.gz,和加压后的源码
│ └─build //源码的构建目录
│ └─install //从源码编译安装的库,或者安装包安装的库,里面的第一层是库的名字,下面是版本号,如果是编译安装的库,就保持它原始的结构
│   ├─Library_A
│   │ ├─v2
│   │ └─v3
│   ├─Library_B
│   │ ├─v10
│   │ └─v12
│   └─Library_C
│     ├─v4
│     ├─v5
│     └─v6
==================== glibc 动态加载器找库规则 ====================
官方文档:
当链接器需要额外的共享库时,搜索顺序如下:
1.通过 -rpath-link 指定的目录。
2.通过 -rpath 指定的目录(这些目录会被包含在可执行文件中,并在运行时使用)。
3.在 ELF 系统中,如果没有使用 -rpath 和 -rpath-link,则会检查环境变量 LD_RUN_PATH 的内容。
4.在 SunOS 系统中,如果没有使用 -rpath,则会搜索 -L 选项指定的目录。
5.对于本地链接器,搜索环境变量 LD_LIBRARY_PATH 中的目录。
6.在本地 ELF 系统中,搜索共享库的 DT_RUNPATH 或 DT_RPATH 中的目录(如果 DT_RUNPATH 存在,则忽略 DT_RPATH)。
7.对于 Linux 系统的链接器,如果存在 /etc/ld.so.conf 文件,则搜索该文件中列出的目录。
8.在 FreeBSD 系统上,搜索 _PATH_ELF_HINTS 宏定义的目录。
9.通过链接器脚本中的 SEARCH_DIR 命令指定的目录,包括 -T 选项提供的脚本。
10.默认目录,如 /lib 和 /usr/lib。
11.由插件 LDPT_SET_EXTRA_LIBRARY_PATH 指定的目录。
12.默认链接器脚本中的 SEARCH_DIR 命令指定的目录。
查阅非官方文档的补充:
1.linux关于查库的规则主要是由glibc里的链接器(不仅能运行时查找库,还能编译时链接库)实现的,
2. rpath和runpath对间接依赖库的作用。 在搜索程序或库的间接依赖时,rpath和runpath是不同的,rpath设置的路径对间接库的搜索也生效。
即搜索间接库时,也会优先从rpath指定的路径中搜索。而runpath设置的路径在对间接库搜索时是不起作用的。
所谓的间接库是指一个库所依赖的库中又依赖的别的库,如test程序依赖liba.so,而liba.so又依赖libb.so
那么对于test程序来说,libb.so就是一个间接依赖库。那么加载器在加载test程序时,寻找libb.so的时候,rpath和runpath的作用是不同的
3. runpath和rpath的行为,和linux发行版中链接器的实现有关,不同的发行版,可能实现并不相同(elf文件格式,也属于用户空间,但是是标准化比较好的,各个发行版通用)
==================== 动态链接器找库规则 ====================
任务:打包可执行文件EXE到目录DIR下
首先把EXE间接或直接依赖的库,按文件结构复制到DIR/root下(注意:软连接的处理)
然后把DIR/root下所有的库的RPATH和RUNPATH的所有绝对路径换成相对与这个root的路径
然后把/etc/ld.so.cache转换为相对与这个root的路径存入PATHS里
然后为EXE下所有库的RPATH添加PATHS路径
这样的话只要我开发环境的内核 与 我发布环境的内核 二进制兼容 我就可以在任何地方跑
LD_DEBUG=libs来帮助调试库的加载过程
-rpath=dir
将目录添加到运行时库搜索路径。在将 ELF 可执行文件与共享目标文件链接时,将使用此选项。
所有 -rpath 参数都连接在一起并传递给运行时链接程序,运行时链接程序使用它们在运行时查找共享目标文件。
在查找链接中显式包含的共享对象所需的共享对象时,也会使用 -rpath 选项;请参阅 -rpath-link 选项的说明。
以这种方式搜索 -rpath 仅支持配置了 --with-sysroot 选项的本机链接器和交叉链接器。
如果在链接 ELF 可执行文件时未使用 -rpath,则将使用环境变量 “LD_RUN_PATH” 的内容(如果已定义)
-rpath选项也可以在SunOS上使用。在SunOS上默认情况下,链接器将从所有-L中形成一个运行时搜索路径
它提供了选项。如果使用-rpath选项,运行时搜索路径将仅使用-rpath选项形成,忽略-L选项。这在使用gcc时很有用
添加了许多-L选项,这些选项可能位于NFS挂载的文件系统上。
为了与其他 ELF 链接器兼容,如果 -R 选项后跟目录名称而不是文件名,则会将其视为 -rpath 选项。
-rpath=dir
Add a directory to the runtime library search path. This is used
when linking an ELF executable with shared objects. All -rpath
arguments are concatenated and passed to the runtime linker, which
uses them to locate shared objects at runtime.
The -rpath option is also used when locating shared objects which
are needed by shared objects explicitly included in the link; see
the description of the -rpath-link option. Searching -rpath in
this way is only supported by native linkers and cross linkers
which have been configured with the --with-sysroot option.
If -rpath is not used when linking an ELF executable, the contents
of the environment variable "LD_RUN_PATH" will be used if it is
defined.
The -rpath option may also be used on SunOS. By default, on SunOS,
the linker will form a runtime search path out of all the -L
options it is given. If a -rpath option is used, the runtime
search path will be formed exclusively using the -rpath options,
ignoring the -L options. This can be useful when using gcc, which
adds many -L options which may be on NFS mounted file systems.
For compatibility with other ELF linkers, if the -R option is
followed by a directory name, rather than a file name, it is
treated as the -rpath option.
-rpath-link=dir
使用 ELF 或 SunOS 时,一个共享库可能需要另一个共享库。当 “ld -shared” 链接包含共享库作为输入文件之一时,会发生这种情况。
当链接器在执行非共享、不可重定位的链接时遇到此类依赖项时,它将自动尝试查找所需的共享库并将其包含在链接中(如果未显式包含)。
在这种情况下,-rpath-link 选项指定要搜索的第一组目录。-rpath-link 选项可以通过指定以冒号分隔的名称列表或多次出现来
指定目录名称序列。
令牌 $ORIGIN 和 $LIB 可以显示在这些搜索目录中。对于 $ORIGIN,它们将被替换为包含程序或共享目标文件的目录的完整路径,
如果是 $LIB,则为 lib - 对于 32 位二进制文件,或 lib64 - 对于 64 位二进制文件。
也可以使用这些令牌的替代形式 - ${ORIGIN} 和 ${LIB}。不支持令牌 $PLATFORM。
应谨慎使用此选项,因为它会覆盖可能已硬编译到共享库中的搜索路径。在这种情况下,可能会无意中使用与运行时链接程序不同的搜索路径。
链接器使用以下搜索路径来查找所需的共享库:
1. 由 -rpath-link 选项指定的任何目录。
2. 由 -rpath 选项指定的任何目录。-rpath 和 -rpath-link 之间的区别在于,
由 -rpath 选项指定的目录包含在可执行文件中并在运行时使用,而 -rpath-link 选项仅在链接时有效。
以这种方式搜索 -rpath 仅支持配置了 --with-sysroot 选项的本机链接器和交叉链接器。
3. 在 ELF 系统上,对于本机链接器,如果未使用 -rpath 和 -rpath-link 选项,请搜索环境变量 “LD_RUN_PATH” 的内容。
4. 在 SunOS 上,如果未使用 -rpath 选项,请搜索使用 -L 选项指定的任何目录。
5. 对于本机链接器,搜索环境变量 “LD_LIBRARY_PATH” 的内容。
6. 对于本机 ELF 链接器,将在共享库的 “DT_RUNPATH” 或 “DT_RPATH” 中的目录中搜索其所需的共享库。
如果存在 “DT_RPATH” 条目,则忽略 DT_RUNPATH 条目。
7. 默认目录,通常为 lib 和 usr/lib。
8. 对于 ELF 系统上的本机链接器,如果文件 etcld.so.conf 存在,则为该文件中找到的目录列表。
如果未找到所需的共享库,链接器将发出警告并继续链接。
-rpath-link=dir
When using ELF or SunOS, one shared library may require another.
This happens when a "ld -shared" link includes a shared library as
one of the input files.
When the linker encounters such a dependency when doing a non-shared,
non-relocatable link, it will automatically try to locate
the required shared library and include it in the link, if it is
not included explicitly. In such a case, the -rpath-link option
specifies the first set of directories to search. The -rpath-link
option may specify a sequence of directory names either by
specifying a list of names separated by colons, or by appearing
multiple times.
The tokens $ORIGIN and $LIB can appear in these search directories.
They will be replaced by the full path to the directory containing
the program or shared object in the case of $ORIGIN and either lib
- for 32-bit binaries - or lib64 - for 64-bit binaries - in the
case of $LIB.
The alternative form of these tokens - ${ORIGIN} and ${LIB} can
also be used. The token $PLATFORM is not supported.
This option should be used with caution as it overrides the search
path that may have been hard compiled into a shared library. In
such a case it is possible to use unintentionally a different
search path than the runtime linker would do.
The linker uses the following search paths to locate required
shared libraries:
1. Any directories specified by -rpath-link options.
2. Any directories specified by -rpath options. The difference
between -rpath and -rpath-link is that directories specified by
-rpath options are included in the executable and used at
runtime, whereas the -rpath-link option is only effective at
link time. Searching -rpath in this way is only supported by
native linkers and cross linkers which have been configured
with the --with-sysroot option.
3. On an ELF system, for native linkers, if the -rpath and
-rpath-link options were not used, search the contents of the
environment variable "LD_RUN_PATH".
4. On SunOS, if the -rpath option was not used, search any
directories specified using -L options.
5. For a native linker, search the contents of the environment
variable "LD_LIBRARY_PATH".
6. For a native ELF linker, the directories in "DT_RUNPATH" or
"DT_RPATH" of a shared library are searched for shared
libraries needed by it. The "DT_RPATH" entries are ignored if
"DT_RUNPATH" entries exist.
7. The default directories, normally /lib and /usr/lib.
8. For a native linker on an ELF system, if the file
/etc/ld.so.conf exists, the list of directories found in that
file.
If the required shared library is not found, the linker will issue
a warning and continue with the link.