Optional shared libraries
Asked Answered
D

2

12

I've noticed a failing with apps depending on shared libraries: that if you're missing some dependency, the app will fail at load time even if the user has no intention of using the dependency's functionality.

I'd like my apps to be better than that. Ideally, rather than distribute as many as n different packages, where n = numberOfSupportedArchitectures * numberOfSupportedOS * ∏(for each shared library)(the number of alternatives) I'd catch an "error while loading shared libraries" exception emitted at load time when the library I'd like- but don't need- is found to be absent, then continue execution in a way that simply avoids using the unresolved links concerned. But obviously there's no exception one can catch. If something's missing, it all falls down before main() even starts.

The closest I can get to having control over the loading process is resolving all the links myself with dlopen, dlsym and such. So tiresome. I'd expect there'd already be a library available to do that for me?

I note that this wouldn't be an issue on a source based distro nor on windows. I was going to put binary-packages in the tags but apparently I don't have the rep to coin tags.

'seems like the most elegant solution would lie in refining the behavior of OS's loader/linkers.

Dionisio answered 22/12, 2011 at 21:46 Comment(0)
S
3

You can take a look at weak symbols. However, this is not a part of C or C++ standard - thus a bit dependent on the compiler. But if you are going for GCC, it's going to work for you, I guess.

Savory answered 22/12, 2011 at 22:14 Comment(4)
Wouldn't this require me to define inert bodies for every symbol in libraries' headers?Dionisio
Not really. You can test for existence of symbol. If you have void foo(); you can call them in the following way: if (foo) foo();Savory
Ah. But I will have to declare them all as weak symbols?Dionisio
Yes, I am afraid you cannot avoid telling, at some point, to the compiler that this is going to be a weak symbol. However, if you do not want to modify headers, there is alternative way, do: #pragma weak foo for already declared void foo() (or any other function foo)Savory
L
0

You could include the shared libraries yourself and adjust the linker search path via -rpath $ORIGIN.

Latta answered 22/12, 2011 at 22:5 Comment(2)
Or run the program through a script that sets the environment variable LD_LIBRARY_PATH.Rhine
The alternatives to loading the library arn't just different versions of the thing, they'll have completely different interfaces, or they'll be absent altogether and the functionality they would provide would just not manifest in the UX. Although this may provide an avenue for handling absent libraries; I could create inert shill libraries with the same interface as the missing targets, where, should the targets be missing, they could satisfy the linker's need to link to something. Seems silly though.Dionisio

© 2022 - 2024 — McMap. All rights reserved.