33

如果不实现链接器或使用ldd,如何找到库的完整路径?Linux 上是否有可用的标准库?(可能是POSIX?)

在有意使用 的文件上使用lddand ,它看起来像:greplibGL.so.1

$ ldd /usr/bin/glxinfo | grep libGL
libGL.so.1 => /usr/lib/libGL.so.1 (0x00007f34ff796000)

给定一个库名称libGL.so.1,我怎样才能找到完整路径/usr/lib/libGL.so.1. 最好接受查找 32 位和 64 位库的选项。如果没有图书馆这样做,是否存在执行此操作的程序?类似的东西find-library-path libGL.so.1locate libGL.so.1命令不算数。

dlopen如果它执行该库中的代码,我不想实际加载该库。

4

5 回答 5

17

使用管理链接空间的工具ldconfig 。

-p标志允许您浏览所有可用的可链接库。

于 2012-10-31T11:24:32.767 回答
16

扩展 Honky Tonk 的答案,该命令echo "$(ldconfig -p | grep libGL.so.1 | tr ' ' '\n' | grep /)"将为您提供单独的路径。

于 2017-10-17T08:32:28.480 回答
2

如果您不介意实际加载库并使用一些非标准但广泛可用的函数,则调用dladdr库中的任何符号都将返回包含已加载完整路径名的信息。

于 2012-10-30T22:50:11.907 回答
1

我在这里实现了这样一个脚本:

#!/usr/bin/env python3

"""
Like `type` but for libs.
"""

import sys
import os
from argparse import ArgumentParser
from glob import glob


def parse_ld_conf_file(fn):
    paths = []
    for l in open(fn).read().splitlines():
        l = l.strip()
        if not l:
            continue
        if l.startswith("#"):
            continue
        if l.startswith("include "):
            for sub_fn in glob(l[len("include "):]):
                paths.extend(parse_ld_conf_file(sub_fn))
            continue
        paths.append(l)
    return paths


def get_ld_paths():
    # To be very correct, see man-page of ld.so.
    # And here: http://unix.stackexchange.com/questions/354295/what-is-the-default-value-of-ld-library-path/354296
    # Short version, not specific to an executable, in this order:
    # - LD_LIBRARY_PATH
    # - /etc/ld.so.cache (instead we will parse /etc/ld.so.conf)
    # - /lib, /usr/lib (or maybe /lib64, /usr/lib64)
    paths = []
    if "LD_LIBRARY_PATH" in os.environ:
        paths.extend(os.environ["LD_LIBRARY_PATH"].split(":"))
    paths.extend(parse_ld_conf_file("/etc/ld.so.conf"))
    paths.extend(["/lib", "/usr/lib", "/lib64", "/usr/lib64"])
    return paths


def main():
    arg_parser = ArgumentParser()
    arg_parser.add_argument("lib")
    args = arg_parser.parse_args()

    paths = get_ld_paths()
    for p in paths:
        fn = "%s/%s" % (p, args.lib)
        if os.path.exists(fn):
            print(fn)
            return

    print("Did not found %r in %r." % (args.lib, paths), file=sys.stderr)
    sys.exit(1)


if __name__ == "__main__":
    main()
于 2021-03-05T22:45:33.127 回答
1

对于具有 GNUlibc和 Python 的系统,以下是我发现的最接近的。它使用LD_DEBUG(在手册页中ld.so(8)描述)。

LD_DEBUG=libs python3 -c "import ctypes; ctypes.CDLL('libssl.so.1.0.0')" 2>&1 | \
    grep -A 1000 "initialize program: python" | grep -A 3 "find library"

输出(对于libssl.so.1.0.0)如下:

 15370: find library=libssl.so.1.0.0 [0]; searching
 15370:  search cache=/etc/ld.so.cache
 15370:   trying file=/lib/x86_64-linux-gnu/libssl.so.1.0.0
 15370: 
 15370: find library=libcrypto.so.1.0.0 [0]; searching
 15370:  search cache=/etc/ld.so.cache
 15370:   trying file=/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
 15370: 
于 2018-07-03T10:25:20.577 回答