查明库是否在路径中

查明库是否在路径中

假设我想测试一个库是否已安装并可由程序使用。我可以用来ldconfig -p | grep mylib查明它是否安装在系统上。但是如果只能通过设置了解该库怎么办LD_LIBRARY_PATH

在这种情况下,程序可能能够找到该库,但ldconfig实际上却找不到。如何检查图书馆是否在合并的链接器路径?

我要补充的是,我正在寻找一个即使我手头实际上没有该程序(例如该程序尚未编译)也能工作的解决方案,我只想知道“中存在某个库ld”的路径。

答案1

ldconfig 可以列出它有权访问的所有库。这些库也存储在其缓存中。

/sbin/ldconfig -v -N将抓取所有常用的库路径,列出所有可用的库,而不重建缓存(如果您是非 root 用户,这是不可能的)。它不考虑 LD_LIBRARY_PATH 中的库(与本文在编辑之前所说的相反),但您可以使用以下行将其他库传递到命令行:

/sbin/ldconfig -N -v $(sed 's/:/ /g' <<< $LD_LIBRARY_PATH)

答案2

您可以使用 gcc 编译一个简单的测试程序并链接您的库。然后你可以用ldd检查使用的库。我用这样的东西:

echo "int main(){}" | gcc -x c++ -Wl,--no-as-needed -lmylib - && ldd a.out | grep mylib

-Wl,--no-as-needed防止链接器丢弃库,因为没有使用库中的符号。

答案3

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

#!/usr/bin/env python3

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

from __future__ import print_function
from argparse import ArgumentParser
from glob import glob
import sys
import os


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)
    LDPATH = os.getenv("LD_LIBRARY_PATH") 
    PREFIX = os.getenv("PREFIX") # Termux & etc.
    paths = []
    if LDPATH: 
        paths.extend(LDPATH.split(":"))
    if os.path.exists("/etc/ld.so.conf"):
        paths.extend(parse_ld_conf_file("/etc/ld.so.conf"))
    else:
        print('WARNING: file "/etc/ld.so.conf" not found.')
    if PREFIX:
        if os.path.exists(PREFIX + "/etc/ld.so.conf"):
            paths.extend(parse_ld_conf_file(PREFIX + "/etc/ld.so.conf"))
        else:
            print('WARNING: file "' + PREFIX + '/etc/ld.so.conf" not found.')
        paths.extend([PREFIX + "/lib", PREFIX + "/usr/lib", PREFIX + "/lib64", PREFIX + "/usr/lib64"])
    paths.extend(["/lib", "/usr/lib", "/lib64", "/usr/lib64"])
    return paths


def main():
    arg_parser = ArgumentParser()
    arg_parser.add_argument("lib", help="Name of the library (e.g. libncurses.so)")
    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()

答案4

$ gcc --print-file-name=libqdbm.so
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/libqdbm.so

相关内容