Beginner
Beginner

Reputation: 5457

Fix library location inside a binary by editing the executable

My goal is to get a binary to work on a different system as part of an installation process even if the libs are not at the place where the linker found them on my original system.

For example: I have a binary 'program' which links against several shared libraries 'library1.so', 'library2.so' and 'library3.so'.

With ldd I can see that libary3.so cannot be found even though it is in /usr/local/lib:

$ ldd program
        library1.so.1 => (0x00007fff26ffe000)
        library2.so.10 => /usr/local/lib/library2.so.10 (0x00007fa67087d000)
        library3.so => not found

The strange thing is that the other lib 'library2.so' is found at exactly the location where 'library3.so' is.

Of course I could fix this using LD_LIBRARY_PATH, but I would like to avoid that.

Question: Which other options do I have to fix a missing library?


Edit 2: I have found this suggestion

Canonical rules for handling LD_LIBRARY_PATH

  1. Never ever set LD_LIBRARY_PATH globally.
  2. If you must ship binaries that use shared libraries and want to allow your clients to install the program outside a 'standard' location, do one of the following:

    • Ship your binaries as .o files, and as part of the install process relink them with the correct installation library path.
    • Ship executables with a very long “dummy” run-time library path, and as part of the install process use a binary editor to substitute the correct install library path in the executable.
  3. If you are forced to set LD_LIBRARY_PATH, do so only as part of a wrapper.

Sub-Question: How can I change the library path using a binary editor?

Upvotes: 4

Views: 2392

Answers (2)

Oleg Gopkolov
Oleg Gopkolov

Reputation: 1684

I think that editing binary for changing paths is bad idea. Try including options

-Wl,-Bstatic -lstdc++

during the linking process. In that case you will have statically linked binary that will be invoked on a different systems.

Upvotes: 2

Beginner
Beginner

Reputation: 5457

I found patchELF, which does what I need:

[...] Likewise, you can change the RPATH, the linker search path embedded into executables and dynamic libraries:

patchelf --set-rpath /opt/my-libs/lib:/foo/lib program    

This causes the dynamic linker to search in /opt/my-libs/lib and /foo/lib for the shared libraries needed by program. Of course, you could also set the environment variable LD_LIBRARY_PATH, but that’s often inconvenient as it requires a wrapper script to set up the environment.

Upvotes: 4

Related Questions