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
RPATH
instead ofRUNPATH
. This is however deemed a bad idea, sinceRPATH
is 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.so
depends on.
Are there better ways to accomplish this? Other things I've tried without success:
- Use
cc_library
instead ofcc_import
- Use
data
instead ofdeps
.
Thanks!