【问题标题】:How to programmatically check whether a library dependent program can run in a Linux system?如何以编程方式检查依赖库的程序是否可以在 Linux 系统中运行?
【发布时间】:2017-11-07 01:32:25
【问题描述】:

我有一个程序(二进制文件),它依赖于 pthread、sqlite3、libcrypto 和 libcurl 等库。我想在多个用户 PC 上运行这个程序。如何在安装二进制文件之前以编程方式检查是否满足依赖关系?

./configure 不能用于构建程序,如Making os independent configure file which checks for curl dependency 中所述。 如果我没记错的话,.deb 和 .rpm 有自己的方法。

谁能告诉我他们为此遵循的方法是什么。它只是一个文件名检查吗?例如,如果我使用 libcurl.so.3 构建程序,它是否会检查将运行它将运行的系统是否将 libcurl.so.3 作为常规文件或 simulink。或者是否有任何其他检查图书馆?

在安装和运行二进制文件时检查依赖关系的可靠方法是什么?

【问题讨论】:

标签: linux rpm deb ldd .so


【解决方案1】:

构建包

您可以将您的程序分发为.deb.rpm 包。两种格式都支持指定需要存在的依赖项:

使用 ldd 手动检查

您可以使用ldd(1) 来检查是否安装了必要的共享库以及它们是如何解决的:

$ ldd /usr/bin/xterm
        linux-vdso.so.1 =>  (0x00007fff649ff000)
        libXft.so.2 => /usr/lib/x86_64-linux-gnu/libXft.so.2 (0x00007fc5195cd000)
        libXaw.so.7 => /usr/lib/x86_64-linux-gnu/libXaw.so.7 (0x00007fc51935b000)
        libutempter.so.0 => /usr/lib/libutempter.so.0 (0x00007fc519158000)
        libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fc518f2f000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc518ba2000)
        libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007fc51896a000)
        libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fc51862f000)
        libXmu.so.6 => /usr/lib/x86_64-linux-gnu/libXmu.so.6 (0x00007fc518415000)
        libXt.so.6 => /usr/lib/x86_64-linux-gnu/libXt.so.6 (0x00007fc5181ad000)
        libICE.so.6 => /usr/lib/x86_64-linux-gnu/libICE.so.6 (0x00007fc517f92000)
        libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007fc517cf3000)
        libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fc517ae9000)
        libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007fc5178d7000)
        libXpm.so.4 => /usr/lib/x86_64-linux-gnu/libXpm.so.4 (0x00007fc5176c6000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc5197f8000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc5174ae000)
        libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fc517284000)
        libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fc517064000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc516e5f000)
        libSM.so.6 => /usr/lib/x86_64-linux-gnu/libSM.so.6 (0x00007fc516c58000)
        libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fc516a54000)
        libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fc51684f000)
        libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fc51664a000)

当没有找到需要的库时,打印“not found”:

$ ldd bar
        linux-vdso.so.1 =>  (0x00007fffde7ff000)
        libfoo.so => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5954eae000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f5955251000)

很遗憾,ldd does not return useful exit code in that case

保持简单,愚蠢

你可以尝试运行你的程序,当它由于缺少库而失败时,然后……你知道你缺少一些库;)

【讨论】:

  • 他可能需要在%pre%%install% 部分编写脚本,例如Failing an RPM install programmatically in a spec step
  • @el.pescado..在这种情况下,我必须检查“未找到”字符串是否存在失败的依赖项。实际上 ....ldd 反过来将使用一些逻辑来找出依赖项。有什么想法吗?我想我得分析一下ldd的源码了。
  • ldd 是一个shell脚本,它使用ld-linux(可能安装在不同的地方,例如/lib64/ld-linux-x86-64.so.2)和--verify标志。
  • @el.pescado..这个程序需要安装在成千上万的用户PC上,用户对linux没有深入的了解。他们期望像windows一样点击安装。所以,安装脚本应该找到缺少的依赖项并在后台安装这些依赖项。这就是我尝试自动化的原因。如果没有其他方法,我必须使用基于 rpm 或 debian 的安装。我会非常有用如果我能知道基于 rpm 和 debian 的安装如何找到依赖关系。
【解决方案2】:

RPM 会自动检测使用过的库并将所需的 Requires 放入最终的 RPM 包中。您可以使用以下方式进行检查:

rpm -qpR foo.rpm

它应该打印如下内容:

libc.so.6(GLIBC_2.8)(64bit)
libdl.so.2()(64bit)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-08
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    相关资源
    最近更新 更多