Get dynamic library directory in c++ (linux)

Is there any programmatic way to get the location of a dynamic library loaded by a program?

I know that it is possible to get the 'executable' running path. But it is not enough for me.

I'm developing an external library that has some dependencies and I need to point accordingly to its location.

For example, the program is running at:

/local/deepLearning/bin

And this program uses a dynamic library located at:

/local/external/libs/faciesAnalysis

What I need is, at runtime, the string

"/local/external/libs/facesAnalysis"

I am working on linux, any suggestion?

Upvotes: 9

Views: 5020

Answers (3)

Peter
Peter

Reputation: 14927

Since this is specifically Linux, dladdr() is a glibc extension to the dl family of functions that will lookup the filename of any symbol. Pass it the address of any function that you know exists in the library you are looking for, and you're basically done.

Presented without appropriate error checking:

#define _GNU_SOURCE
#include <dlfcn.h>

const char *my_fname(void) {
    Dl_info dl_info;
    dladdr((void*)my_fname, &dl_info);
    return(dl_info.dli_fname);
}

Upvotes: 12

First (and this is specific to Linux, since provided by the kernel), you can parse the /proc/self/maps pseudo-file from inside your program. Just read sequentially every line of that textual file, you'll be able to get the full path of every mmap-ed file, including shared libraries. See proc(5) (and use dirname(3) to get a directory out of a path, perhaps also realpath(3)...). Read also dlopen(3) & ld-linux.so(8) and notice the role of LD_LIBRARY_PATH and /etc/ld.so.conf

Then, and this is specific to GNU libc (but apparently musl-libc also has that), you could use dladdr(3) on some function address from that library. Or just use dl_iterate_phdr(3) which looks exactly fit to your question.

Beware of weird cases: some program might generate a plugin and dlopen it later (my MELT is doing that), some other program might remove a plugin after dlopen, some programs might be statically linked, the dlopen-ed plugin could have been moved or renamed (perhaps because a new version has been installed while your program is running)..., the same plugin could have been symlinked and dlopened using different paths, etc...

Read Drepper's paper: How To Write Shared Libraries

Upvotes: 1

Paul Evans
Paul Evans

Reputation: 27567

You could get the full path to the executable (std::string path_and_exe) and then execute the following:

#include <cstdlib>
std::string output("output.txt");

system ("ldd " + path_and_exe + " > " + output);

// read libray paths from output file

Upvotes: 0

Related Questions