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.
