Ubuntu Linux Library Path
How do I determine the Ubuntu Linux Library Path? That is, how does the linker know where to got to grab the object files when linking my program?
5 Answers 5
Look at /etc/ld.so.conf and the files in the /etc/ld.so.conf.d/ directory — that’s where it is set.
The file paths can be set explicitly when linking using the -L parameter, as well as the environment variable LD_LIBRARY_PATH .
There are also some paths hard-coded into the linker, using the -L param. You can see these with the command:
If it’s not a standard path ( /lib , /usr/lib ), you can specify the location with the compiler flag. For g++ , it’s -L/some/path/lib . If you use autotools, you can just configure with LDFLAGS=-L/some/path/lib if you need a specific path. If configure has been properly designed for the project, it should have a —with-some-library=PATH option, where you can also specify a path for that library only.
When linking, you need to specify the -L flag to indicate where the library is located. At runtime, the dynamic linker uses the paths given in «/etc/ld.so.conf», «/etc/ld.so.conf.d/*» and the value of LD_LIBRARY_PATH.
«sudo ldconfig» updates the system’s cache if you’ve just installed something new.
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
How can I find the full file path given a library name like libfoo.so.1?
Without implementing a linker or using ldd , how can I find the full path to a library? Is there a standard library available for that on Linux? (POSIX maybe?) Using ldd and grep on a file that is knowingly using libGL.so.1 , it looks like:
$ ldd /usr/bin/glxinfo | grep libGL libGL.so.1 => /usr/lib/libGL.so.1 (0x00007f34ff796000)
Given a library name like libGL.so.1 , how can I find the full path /usr/lib/libGL.so.1 ?. Preferably accepting an option for finding 32-bit and 64-bit libraries. If no library does that, does a program exist to do this? Something like find-library-path libGL.so.1 . The locate libGL.so.1 command does not count. I don’t want to actually load the library using dlopen or something if it executes code from that library.
5 Answers 5
Use ldconfig which is the tool that manages link space.
The -p flag lets you browse all available linkable libraries.
Thanks for your answer ,but -p prints cached entries from a file, not the current state (directories in $LD_LIBRARY_PATH are not respected for example)
@Lekensteyn If you want to find the library in any location and not rely on any mechanic that is actually used to manage libraries, find or the locate DB might be your only options. As your questions is stated, looking at the source for the loader might also be an option.
Expanding on Honky Tonk’s answer, the command echo «$(ldconfig -p | grep libGL.so.1 | tr ‘ ‘ ‘\n’ | grep /)» will give you the path alone.
If you don’t mind actually loading the library and using some nonstandard but widely-available functions, calling dladdr on any symbol from the library will return information containing the full pathname that was loaded.
I’ll have a look at the manpage, I also added another requirement to the question: the library should not execute code of the library that is being checked. EDIT: It looks like that dladdr is not going to help me as it needs dlopen first.
Well you can’t (portably) avoid executing global constructors in the library that’s loaded. There might be some non-portable hacks to get back control before the constructors run, using library dependencies and the implementation-specific order in which constructors run to call _exit (doing all of this from a forked child process) from another library’s constructor beforehand, but I think that’s getting into far-fetched hack territory. Ideally dlopen would have a RTLD_NOEXEC flag to prevent any code execution in the library, useful for tasks like yours.
Yeah, that is wishful thinking. There is a RTLD_NOLOAD, but that just returns NULL when the library is not loaded before. I don’t think there is even a solution available that takes 32-bit/64-bit into account (without building a 32-bit and 64-bit program designed to check this, that is).
Well there’s another ugly hack — you could fork a child process and ptrace it, and terminate it on the first mmap system call made. The prior open call should give you the pathname. 🙂 By the way, why do you need to know the pathname? I suspect there’s a better way to do what you’re trying to achieve.
primus intercepts GL calls and splits rendering from accelerating. These libraries do not have to sit in $LD_LIBRARY_PATH , hence I cannot pass libGL.so.1 to the dlopen function in that program and therefore I have to pass the absolute path to the libraries. In a second program, I want to lookup the libraries as stated in the question so I can pass it to the the primus program.
For systems with GNU libc and Python the following is the closest I found. It uses LD_DEBUG (described in the man page of 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"
The output (for libssl.so.1.0.0 ) is the following:
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:
I implemented such a script here:
#!/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()
Finding the absolute path of shared libraries used by an executable
$ ldd /usr/sbin/lshw linux-vdso.so.1 => (0x00007fff8bdaf000) libresolv.so.2 => /lib64/libresolv.so.2 (0x000000360e400000) libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x0000003631600000) libstdc++.so.6 => /lib64/libstdc++.so.6 (0x000000360ec00000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000360d800000) libc.so.6 => /lib64/libc.so.6 (0x000000360c000000) libpthread.so.0 => /lib64/libpthread.so.0 (0x000000360cc00000) libdl.so.2 => /lib64/libdl.so.2 (0x000000360c800000) libm.so.6 => /lib64/libm.so.6 (0x000000360c400000) /lib64/ld-linux-x86-64.so.2 (0x000000360bc00000)
If I want to find the absolute locations of the shared libraries (and want to exclude linux-vdso.so.1 for obvious reasons), how do I go about it? Using awk with regular expressions seems brittle here. ldd has a verbose flag (-v) which does print the complete paths of the shared libraries, but it is not very friendly for machine reading. Is there another way to go about this? If someone knows of a system call to do so, I am fine with that too. PS: For a bit of context, I want to run this program in chroot jail, so I need to make sure that the shared libraries are all available. Compiling it statically works without all this drama, but that is a path I am looking to avoid. Update: I think I may have found something which may be more suitable while reading Michael Kerrisk’s book, «The Linux Programming Interface». If I run a program as $ LD_DEBUG=libs lshw , it outputs various helpful information. For example:
$ LD_DEBUG=libs lshw 32058: find library=libresolv.so.2 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libresolv.so.2 32058: 32058: find library=libstdc++.so.6 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libstdc++.so.6 32058: 32058: find library=libgcc_s.so.1 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libgcc_s.so.1 32058: 32058: find library=libc.so.6 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libc.so.6 32058: 32058: find library=libm.so.6 [0]; searching 32058: search cache=/etc/ld.so.cache 32058: trying file=/lib64/libm.so.6 32058: 32058: 32058: prelink checking: ok 32058: 32058: calling init: /lib64/ld-linux-x86-64.so.2 32058: 32058: 32058: calling init: /lib64/libc.so.6 32058: 32058: 32058: calling init: /lib64/libm.so.6 32058: 32058: 32058: calling init: /lib64/libgcc_s.so.1 32058: 32058: 32058: calling init: /lib64/libstdc++.so.6 32058: 32058: 32058: calling init: /lib64/libresolv.so.2
I think, if I look for the ‘calling init’ lines, I will have the shared library paths it is initializing before starting to execute the program.
Where are package library and header files installed?
After downloading and installing a package in Ubuntu, how can I check where the library and header files were written to? I believe that this has something to do with the package’s .pc file, but I do not know how to find that file either. For example, I have downloaded the PCL (Point Cloud Library) package, and then in a sample CMakeLists.txt file, I have been given the following:
include_directories($) link_directories($) add_definitions($)
Where are these environment variables defined, and how can I see them? If I compiled the libraries from source rather than through a package, will this be any different? Will a .pc file be created automatically?
That just returns an empty line. However, compiling my project as above works fine so it must be using the PCL libraries. Is it searching anywhere else?
If you installed a debian package you can see the content via dpkg -L
I had similar confusions. You can check to what values $ resolves to by using message command in your CMakeLists.txt i.e. add this line: message(«$) or message(«PCL_INCLUDE_DIRS = » $) . It will display the result when you run cmake .. Do the same for other macros/variables i.e. $ and $
2 Answers 2
If you install the package containing the libpcl development files
sudo apt-get install libpcl-dev
You can list the installed files
an see the location of all headers.
. /usr/include/pcl-1.7/pcl/filters/fast_bilateral.h /usr/include/pcl-1.7/pcl/filters/voxel_grid_covariance.h /usr/include/pcl-1.7/pcl/filters/voxel_grid_occlusion_estimation.h /usr/include/pcl-1.7/pcl/filters/median_filter.h /usr/include/pcl-1.7/pcl/filters/crop_box.h /usr/include/pcl-1.7/pcl/filters/voxel_grid_label.h /usr/include/pcl-1.7/pcl/filters/covariance_sampling.h /usr/include/pcl-1.7/pcl/filters/random_sample.h /usr/include/pcl-1.7/pcl/filters/normal_refinement.h /usr/include/pcl-1.7/pcl/filters/project_inliers.h /usr/include/pcl-1.7/pcl/filters/fast_bilateral_omp.h /usr/include/pcl-1.7/pcl/filters/clipper3D.h /usr/include/pcl-1.7/pcl/filters/convolution.h /usr/include/pcl-1.7/pcl/filters/passthrough.h /usr/include/pcl-1.7/pcl/filters/conditional_removal.h /usr/include/pcl-1.7/pcl/filters/impl /usr/include/pcl-1.7/pcl/filters/impl/frustum_culling.hpp /usr/include/pcl-1.7/pcl/filters/impl/conditional_removal.hpp /usr/include/pcl-1.7/pcl/filters/impl/convolution_3d.hpp /usr/include/pcl-1.7/pcl/filters/impl/voxel_grid_covariance.hpp /usr/include/pcl-1.7/pcl/filters/impl/fast_bilateral_omp.hpp /usr/include/pcl-1.7/pcl/filters/impl/project_inliers.hpp /usr/include/pcl-1.7/pcl/filters/impl/morphological_filter.hpp /usr/include/pcl-1.7/pcl/filters/impl/crop_box.hpp /usr/include/pcl-1.7/pcl/filters/impl/covariance_sampling.hpp /usr/include/pcl-1.7/pcl/filters/impl/local_maximum.hpp /usr/include/pcl-1.7/pcl/filters/impl/plane_clipper3D.hpp /usr/include/pcl-1.7/pcl/filters/impl/bilateral.hpp /usr/include/pcl-1.7/pcl/filters/impl/voxel_grid_occlusion_estimation.hpp .