Find out if library is in path

55,538

Solution 1

ldconfig can list all the libraries it has access to. These libraries are also stored in its cache.

/sbin/ldconfig -v -N will crawl all the usual library paths, list all the available libraries, without reconstructing the cache (which is not possible if you're a non-root user). It does NOT take into account libraries in LD_LIBRARY_PATH (contrarily to what this post said before edit) but you can pass additional libraries to the command line by using the line below:

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

Solution 2

You can compile a simple test program with gcc and link your library. Then you can check the used libraries with ldd. I use something like this:

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

-Wl,--no-as-needed prevents the linker from discarding the library, because no symbols from the library are used.

Solution 3

Globally substitute (space) for : with LD_LIBRARY_PATH

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

Solution 4

I implemented such a script here:

#!/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()
Share:
55,538

Related videos on Youtube

nbubis
Author by

nbubis

Updated on September 18, 2022

Comments

  • nbubis
    nbubis over 1 year

    Assuming I want to test if a library is installed and usable by a program. I can use ldconfig -p | grep mylib to find out if it's installed on the system. but what if the library is only known via setting LD_LIBRARY_PATH?

    In that case, the program may be able to find the library, but ldconfig won't. How can I check if the library is in the combined linker path?

    I'll add that I'm looking for a solution that will work even if I don't actually have the program at hand (e.g. the program isn't compiled yet), I just want to know that a certain library exists in ld's paths.

    • Admin
      Admin almost 8 years
      You could use ldd <binary> to check if all libraries linked are in the path. Maybe there is a more elegant way.
    • Admin
      Admin almost 8 years
      @Thomas I think you should make an answer of your comment. ldd serves exactly this purpose.
    • Admin
      Admin almost 8 years
      @Thomas - but what if I the program isn't compiled yet, and that library is needed for compilation?
    • Admin
      Admin almost 8 years
      @Igeorget - see my edit / comment
    • Admin
      Admin almost 8 years
      @nbubis: when you need the library for compilation, you normally have to use LIBRARY_PATH environment variable which is looked up e.g. by the gcc compiler. The LIBRARY_PATH environment variable also has a colon seperated list of directories.
  • schily
    schily almost 8 years
    ldconfig is a tool from the 1980s that was given up in the 1990s. For this reason, ldconfig is not portable as it only applies to implementations that are based on the SunOS-4.0 a.out based dynamic linker from 1987.
  • nbubis
    nbubis almost 8 years
    How does that help listing libs which are only on LD_LIBRARY_PATH? I guess I could write a script to parse that and then read that through ldconfig, but it seems a bit like an over kill.
  • lgeorget
    lgeorget almost 8 years
    @nbubis you can always pass the libraries in LD_LIBRARY_PATH to ldconfig. Like /sbin/ldconfig -N -v $(sed 's/:/ /' <<< $LD_LIBRARY_PATH) not too much of an overkill to my taste.
  • lgeorget
    lgeorget almost 8 years
    @schily Really? It works pretty well with ELF libraries as far as I can tell. And it's still used, ld.so relies on the cache built by ldconfig.
  • schily
    schily almost 8 years
    Typo fix: change the tree stooges to the three stooges.