I'm struggling with a path problem on Fedora 26. I am building updated programs and libraries and placing them at /usr/local. Programs in /usr/local/bin use the libraries in /usr/local/lib. For some reason that's unknown at the moment, Fedora 26's gawk, which is located in /usr/bin/gawk, is using a library at /usr/local/lib.

The library in /usr/local/lib not compatible with the one gawk expects, so its breaking my scripts. Or more correctly, my script calls Autotools, and then Autotools breaks even though paths are not messed with. More information on the background problem is available at libreadline.so.7: undefined symbol: UP on Stack Overflow.

I would like to enforce a policy which says, any program in /usr/bin must link to libraries in /usr/lib. I don't care about swizzling or inter-positioning. If I need to do it, then I'll build the package from sources and install it into /usr/local.

Other OSes solved this problem long ago with things like install_names on OS X and manifests on Windows. Linux just allows the same problems to fester (I think --enable-new-dtags is the latest band-aide that does not fix the problem).

How do I force the programs in /usr/bin to link to libraries in /usr/lib?

  • Are you setting this with LD_PRELOAD? Have you modified ld.so.conf? – mattdm Oct 23 '17 at 15:36

You can override the search path in the executable by specifying a DT_RUNPATH dynamic section. See the ld.so man page. Using the standard location in /usr/lib should be the norm, and the (hopefully not too many) programs you want to use your /usr/local/lib libraries should be linked by adding the following gcc options for the linker:

gcc ... -Wl,-rpath,/usr/local/lib -Wl,--enable-new-tags ...
  • Thanks. How do I add the section to Fedora's gawk in /usr/bin? It seems easier to apply a system-wide policy of "if the program originates in /usr/bin, then it can only link to libraries in /usr/lib. But I'm will to use something like editelf to add the section since to gawk since the dynamic linker cannot get things right. – jww Oct 23 '17 at 9:50
  • If you search on the web, you'll find some utilities that can be used. For example, patchelf. DT_RPATH and DT_RUNPATH do the same thing, but DT_RPATH has been deprecated in favor of DT_RUNPATH which is searched after LD_LIBRARY_PATH. – Johan Myréen Oct 23 '17 at 10:49
export LD_LIBRARY_PATH=/usr/lib

or directly run the command as:

LD_LIBRARY_PATH=/usr/lib gawk

You can configure the default search order in /etc/ld.so.conf

  • Thanks. If I am parsing things correctly, this does not seem to scale and casts an overly broad net. It does not scale because I'm not sure how to apply it to all aspects of the system, and not just the stuff launched from one of my terminals. Its overly broad because it applies to more than the binaries in /usr/bin. – jww Oct 23 '17 at 8:48

When manually compiling libraries that already are present in the system, no matter where they go /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64, the newest installation takes precedence. The library path is specified in /etc/ld.so.conf which in turn reads files in /etc/ld.so.conf.d. You can create a new file there with the path to any library you want and then run ldconfig when you're done.

Alternatively, in your script, you can set your own paths to libraries using the LD_LIBRARY_PATH environment variable. This will force the script to take whatever library paths are specified there. Multiple paths can be provided delimited by semicolons.

  • Thanks. How do I tell ld.so that any program in /usr/bin must link to libraries in /usr/lib? Is there even a way to do it? (I also think the answer suffers similar issues as Ipor's answer). – jww Oct 23 '17 at 8:50
  • The locations /usr/lib and the like are used for shared libraries, so no, you cannot specify that all /bin binaries should use libraries from /usr/lib only. All binaires compiled to use shared libraries will look for the libraries in the shared libraries paths specified in ld.so.conf. Instead, I woul recompile the program that's produced the /usr/local/lib library, the one that's messing up gawk, with static libraries. This way you will force that program alone to use the newly compiled library, which will not be used by any other program. Just compile that library as static, instead of shared – Alex Austin Oct 23 '17 at 9:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.