views:

231

answers:

5

Say I have a library libfoo.so.1, which depends (according to ldd) on libbar.so.1. However, libbar.so.1 is not available at the moment. My app needs to call a function in libfoo.so.1 which doesn't require libbar.so.1 at all.

Is there a way to load libfoo.so.1, resolve the function symbol and then call it without having libbar.so.1 to satisfy the dependency? It's a case of "I know what I'm doing, just let me do it already". I tried the RTLD_LAZY flag, but it still tries to load the libbar.so.1 library before not loading the symbols.


EDIT

Here's the exact situation.

We have 3 players:

  • libbar.so.1, a shared library located in a path not in LD_LIBRARY_PATH or ldconfig, and whose dependencies are all resolved
  • libfoo.so.1, a shared library located in a different directory than libbar, but which depends on libbar. At runtime, libfoo will know where to locate libbar.
  • App, a binary application which needs to load libfoo at some point during runtime.

App doesn't know where to find libbar, but knows that libfoo knows. What I'm trying to accomplish is having an init function in libfoo which would simply change App's current working directory to where libbar is located to finally resolve all the dependencies and make everyone happy.

libfoo will eventually need to call stuff in libbar, just not in this init function. I don't think creating a stub would work since the symbols would eventually need to resolve to the real functions.

+3  A: 

Well, variables are still resolved even with RTLD_LAZY, so in general you do need all the libraries to be linked. Seems like you should create a stub libbar.so.1 that has no functionality and can be found by the linker.

Adam Goode
I think this would work, but you need the stub to define all the symbols that libfoo.so depends on. The definitions themselves can be stubs though.
Jay Conrod
As tommieb75 points out, the stubs don't actually have to be in libbar.so, but their symbols must be defined somewhere.
Jay Conrod
I don't think you need to define all the symbols, isn't that what `RTLD_LAZY` will do?
Adam Goode
A: 

Just a thought, have you thought of interpositioning dependency - simply create a identical function with the same signature, parameters etc and let the linker resolve this function and ignore libbar.so.1? Since you did not mention this, I thought I'd suggest this.

Hope this helps, Best regards, Tom.

tommieb75
I don't think this would work. Each library has a list of dependencies encoded into it at link time that is independent of the set of undefined symbols. The loader will try to find those dependencies whether or not they are actually needed.
Jay Conrod
@Jay: The loader's path is embedded into the executable in order for the dynamic loading of the function...I was thinking of in terms of preventing the dynamic load by specifying a duplicate function with same signature thus forcing the linker to use that version instead...
tommieb75
@Jay: Just saw your response to Adam's answer, that was my line of thinking...a stub for want of a better word...
tommieb75
@tommieb75, that would be fine. It doesn't matter where the symbols are defined as long as they're defined somewhere. libbar.so still has to exist though, even if it's empty.
Jay Conrod
A: 

Use dlopen to load the library and dlsym to get the function you need.

Richard Pennington
That's how he tried the RTLD_LAZY flag; you don't get to specify that when the library is linked in at startup.
Jonathan Leffler
@Jonathan, you're right. Brain freeze.
Richard Pennington
A: 

Another thought: Would extracting (use ar(1)) the necessary function(s) from libfoo.so.1, either into a .o or into another .so file, and then linking against that extract help? I'm assuming the reference to libbar.so.1 is in a libfoo function that is not called (even indirectly) from your program.

mpez0
Actually, dynamic libraries aren't `ar`chives.
Adam Goode
A: 

What's the actual requirement here? Merely linking a library doesn't do much, and is usually benign. Do you lack the library? Just create a stub library of the same name. You want to control or preempt the use of symbols in the library? Put them in another library (with the right version tags!) and LD_PRELOAD it.

I guess the meta-question here is that I don't see what value being able to preempt the dependency linkage has. It's just a helper function.

Andy Ross