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.