c++ - 使用 bazel 链接到版本化的预构建库

标签 c++ linker bazel

假设预编译依赖项由供应商提供:

$ ls /opt/vendor/protobuf/lib
libprotobuf.so.3 -> libprotobuf.so.3.0.0
libprotobuf.so.3.0.0

要将其与 Bazel 一起使用,可以创建以下目标:

cc_import(
  name = "protobuf",
  shared_library = "lib/libprotobuf.3.0.0",
)

这样,bazel构建的应用程序可以链接到库,但是它无法启动:

error while loading shared libraries: libprotobuf.so.3: cannot open shared object file: no such file or directory

根本原因是实际的so文件有一个自定义的SONAME字段:

objdump -x libprotobuf.so.3.0.0|grep SONAME
  SONAME      libprotobuf.so.3

加载程序将查找 libprotobuf.so.3(而不是 3.0.0),但不会在沙箱中找到它,因为我们从未告诉 bazel 有关符号链接(symbolic link)的信息。符号链接(symbolic link)是相对的,在 cc_import 目标中指定它会产生类似的错误。

是否可以使用 bazel 创建一个可运行的二进制文件,链接到应该通过符号链接(symbolic link)找到的共享库?

最佳答案

设置 RPATH 可能是一种解决方法。 cc_import 需要由 cc_library 包装:

cc_library(
  name = "protobuf",
  deps = [":protobuf_impl"],
  linkopts = ["-Wl,-rpath=/opt/vendor/protobuf/lib"],
)

cc_import(
  name = "protobuf_impl",
  shared_library = "lib/libprotobuf.3.0.0",
)

这将使二进制文件运行,但假设每个系统上都存在“/opt/vendor/protobuf/lib”(包括远程执行),并且加载程序在运行时仍然逃脱沙箱。一个更清晰的解决方案会很好。

关于c++ - 使用 bazel 链接到版本化的预构建库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68405534/

相关文章:

c++ - 使用用户分配的内存绘制到 HDC

c++ - 未找到符号又名 undefined symbol

C++ - 如何内联驻留在 .lib 中的函数?

C++ 链接器问题,未解析的外部符号与我自己的代码

python - Bazel 解析 tf.estimator 模型时出错

c++ - atof() 可以根据不同的机器编译器/库(x86-64)产生不同的结果

c++ - 如何证明Copy Constructor是强制的

c++ - 可以链接到非外部符号吗?

java - Bazel 卡在 java 二进制文件上

bazel - 如何从 Bazel 中的另一个规则中创建规则