I'm trying to build a binary application with Bazel. This binary depends on an external, pre-compiled library, let's call it liba.so. In turn, liba.so depends on libb.so (this information I obtain via readelf -d liba.so | grep NEEDED.
To build this, I have the following setup in Bazel:
cc_import(
name = "liba",
shared_library = "liba.so",
deps = [":libb"],
)
cc_import(
name = "libb",
shared_library = "libb.so",
)
cc_binary(
name = "my_app",
srcs = ["main.cpp"],
deps = [":liba"],
)
Building works fine, however when running (either via bazel run or directly) ldd fails to find libb.so.
I've been reading about this and the reason is that Bazel adds to the RUNPATH of the binary only its direct dependencies. Since libb.so is a transitive dependency, the binary cannot find it.
To solve this, I can think of the following hacks:
Add ugly linker flags to tell Bazel to add to the
RPATHinstead ofRUNPATH. This is however deemed a bad idea, sinceRPATHis being deprecated and doesn't allow override viaLD_LIBRARY_PATH.Patch the third-party .so file to add to their
RUNPATH. This works but it doesn't feel good to patch libraries I don't own.Make the transitive dependencies direct dependencies of the binary. This is not good, each library should be responsible of its dependencies. The binary doesn't need to know what
liba.sodepends on.
Are there better ways to accomplish this? Other things I've tried without success:
- Use
cc_libraryinstead ofcc_import - Use
datainstead ofdeps.
Thanks!