Linux共享库概述( 十 )

  • 在某些情况下 , 调用gcc来创建对象文件也需要包含“-Wl , -export-dynamic”选项 。 通常 , 动态符号表仅包含动态对象使用的符号 。 此选项(创建ELF文件时)将所有符号添加到动态符号表(有关详细信息 , 请参阅ld(1)) 。 当有“反向相关性”时 , 您需要使用此选项 , 即 , DL库具有未解决的符号 , 按照惯例 , 必须在要加载这些库的程序中定义它们 。 对于“反向相关性”工作 , 主程序必须使其符号动态可用 。 请注意 , 如果您只使用Linux系统 , 则可以使用“-rdynamic”而不是“-Wl , export-dynamic” , 但根据ELF文档 , “-rdynamic”
  • 在开发过程中 , 修改也被许多其他程序使用的库的潜在问题 - 您不希望其他程序使用“开发”库 , 只是您正在测试的特定应用程序 。 您可能使用的一个链接选项是ld的“rpath”选项 , 它指定正在编译的特定程序的运行时库搜索路径 。 从gcc , 您可以通过这样指定来调用rpath选项:
    -Wl , -rpath , $(DEFAULT_LIB_INSTALL_PATH)如果您在构建库客户机程序时使用此选项 , 则不需要再打扰LD_LIBRARY_PATH(下文将介绍) , 除了确保它不冲突 , 或者使用其他技术来隐藏库 。
    安装和使用共享库创建共享库后 , 您需要安装它 。 简单的方法是将库复制到标准目录(例如/ usr / lib)中 , 并运行ldconfig(8) 。
    首先 , 您需要在某个地方创建共享库 。 然后 , 您将需要设置必要的符号链接 , 特别是从soname到真实名称的链接(以及从无版本的soname , 即以“.so”结尾的soname)为用户谁没有指定版本) 。 最简单的方法是运行:
    ldconfig -n directory_with_shared_libraries最后 , 当你编译你的程序时 , 你需要告诉链接器你正在使用的任何静态和共享库 。 使用-l和-L选项 。
    如果您不能或不想在标准位置安装库(例如 , 您没有权限修改/ usr / lib) , 则需要更改方法 。 在这种情况下 , 您需要将其安装在某个地方 , 然后为您的程序提供足够的信息 , 以便程序可以找到库...并且有几种方法可以做到这一点 。 您可以在简单的情况下使用gcc的-L标志 。 您可以使用“rpath”方法(如上所述) , 特别是如果您只有一个特定的程序将库放置在“非标准”位置 。 您也可以使用环境变量来控制事物 。 特别是 , 您可以设置LD_LIBRARY_PATH , 这是一个冒号分隔的目录列表 , 用于在通常的位置之前搜索共享库 。 如果你使用bash ,
    LD_LIBRARY_PATH = 。 :$ LD_LIBRARY_PATH my_program如果要仅覆盖几个选定的函数 , 可以通过创建一个覆盖目标的文件并设置LD_PRELOAD来实现; 此对象文件中的函数将仅覆盖这些函数(留下其他函数) 。
    通常你可以不需要更新库; 如果有API更改 , 则库创建者应该更改soname 。 这样 , 多个库可以在单个系统上 , 并为每个程序选择正确的库 。 但是 , 如果一个程序中断更新到保持相同soname的库 , 您可以强制它使用旧的库版本通过将旧的库复制到某个地方 , 重命名该程序(比如说旧的名称加上“.orig '') , 然后创建一个小的“包装器”脚本 , 该脚本重置库以使用并调用真实(重命名)程序 。 您可以将旧图书馆放在自己的特殊区域 , 如果您愿意 , 尽管编号约定允许多个版本生活在同一目录中 。 包装脚本可能看起来像这样:
    #!/ bin / sh的导出LD_LIBRARY_PATH = / usr / local / my_lib:$ LD_LIBRARY_PATHexec /usr/bin/my_program.orig $ *编写自己的程序时请不要依赖这个; 尝试确保您的库向后兼容 , 或者您?每次进行不兼容的更改时都会在soname中增加版本号 。 这只是处理最坏情况问题的“紧急”方法 。
    您可以使用ldd(1)查看程序使用的共享库列表 。 所以 , 例如 , 您可以通过键入以下方式查看ls使用的共享库: