Here's the current situation I'm in:
I want to distribute a binary app on Linux that would run on several distros (not all of them, just the main ones matter at the moment, let's focus on Ubuntu and Fedora for the sake of this discussion). The app in question links to libbz2
for some of its work. A simple "Hello World" will illustrate the situation :
/* main.cpp */
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Hello World!\n";
return 0;
}
The app is built as such :
g++ -lbz2 -o test.bin main.cpp
My build system is on Ubuntu. When I perform a check with ldd on the resulting binary, it lists libbz2.so.1.0 as a runtime dependency. When I take this app to a Fedora machine, the app doesn't run and ldd reveals that it can't find libbz2.so.1.0
. Fedora only has libbz2.so.1
and libbz2.so.1.0.4
, but not libbz2.so.1.0
.
Red Hat's Bugzilla database reveals that this behavior is not a bug, but a feature. I don't really need libbz2.so.1.0
, and I would be satisfied with simply linking to libbz2.so.1
, but I have yet to figure out how.
I have seen a similar question asked here previously, but the accepted answer (You can pass the actual .so file instead of -l on the linker command line) doesn't seem to work. I tried building with the following command :
g++ /lib/libbz2.so.1 -o test.bin main.cpp
However, ldd still mentions that the app depends on libbz2.so.1.0
, even though I passed the full name to g++.
Now, the question is, is there a way on Ubuntu to build the app to have it depend only on libbz2.so.1
rather than on libbz2.so.1.0
?
Thanks.
Here's a bit of background to explain what got linked. On ELF platforms the -L and -l flags you pass only locate the binary at link time. If the linker linker determines that a library is required it generates a reference to the SONAME in that binary, regardless of what it was called. For example:
$ objdump -p /lib64/libbz2.so.1 | grep SONAME SONAME libbz2.so.1
So regardless of what libbz2 is named, that is what will show up as a dependency. Again by example, doing something totally whacked:
$ ln -s /lib64/libbz2.so.1 libblah.so $ g++ t.C -L. -l blah
You have the apparency of having linked to libblah but because its the SONAME in that binary that matters, your dependency is still this libbz2.so.1
$ ldd a.out | grep bz2 libbz2.so.1 => /lib64/libbz2.so.1 (0x00002b3d1a000000)
Other than the -static trickery (which can break things in interesting ways), there is not easy way out of the mess (ideally the library would do nice symbol versioning like glibc and never or rarely change its SONAME).
Why don't you just link statically instead?
I have done that in the past for builds on Ubuntu and deployment on RHEL which works just fine using static builds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With