【问题标题】:How can I control what symbols are exported from a shared library in Bazel?如何控制从 Bazel 中的共享库导出的符号?
【发布时间】:2021-04-16 18:19:10
【问题描述】:

我正在学习 Bazel,因为我必须在工作中使用它。我有一个简单的构建规则,它从单个文件创建一个库,我想通过使用链接器版本文件来控制链接器导出的内容。 (我在 Linux 上)

所以我尝试了:

cc_library (
    name ="thelib",
    srcs = ["lib.cpp"],
    linkopts = ["-Wl,--version-script,lib.ver"]
)

它告诉我“没有这样的文件或目录”。

我尝试了什么:

  • 我尝试了相对于我发出 bazel build 命令的目录的路径,但无济于事。
  • cc_library() 的文档说“linkopts”支持 make 变量替换,所以我用 bazel info --show_make_env 列出了 make 变量,它显示了一个名为 workspace 的变量 所以我然后尝试了$(workspace)/lib/lib.ver,但它说$(workspace) not defined所以Bazel是个骗子。
  • 唯一可行的方法是拼写链接描述文件的绝对路径,但我不想强制执行。
  • cc_library() 有一个 win_def_file 选项,但猜猜看,那只是 Windows。
  • self-closed github issue 建议我应该将文件名作为单独的参数传递,它也不起作用。
  • 使用-fvisiblity=hidden 和使用__attribute__ 导出不是一个选项,因为标准C++ 库会覆盖它并强制导出您不想出现在界面上的符号(该库使用extern "只有C"界面,我不希望上面出现任何其他垃圾)。
  • Bazel 中似乎没有选项来指定要本地导出的符号。

在这一点上,我完全没有想法了。任何帮助表示赞赏。

【问题讨论】:

    标签: c++ gcc ld bazel


    【解决方案1】:

    首先,共享库通常使用cc_binary 及其linkshared 属性声明,而不是cc_library。这是违反直觉的,但反映了cc_binary 创建传递链接而cc_library 声明中间库的意图。 (喜欢冒险的朋友可以试试cc_shared_library

    其次,可以通过在linkopts 中使用它们并在deps 中将它们声明为依赖项来使用版本脚本(和其他链接器脚本)。

    所以,一起来:

    cc_binary(
       name = 'mylib.so',
       linkshared = True,
       srcs = ['mylib.cc'],
       linkopts = ['-Wl,-version-script=$(location version-script.lds)'],
       deps = [
          'version-script.lds',
       ]
    )
    

    【讨论】:

    • 我尝试了这个并得到了两个错误:首先,Bazel 想让我在 deps 部分使用 .ld、.lds 或 .ldscript 文件扩展名。第二:gcc 抱怨未定义对 main 的引用,因此它试图使可执行文件不是共享对象。如果我将 lib.ver 重命名为 lib.ld 并使用 cc_library,那么我可以获得我想要的共享对象。
    • 奇怪,但是在我想将版本脚本添加到他们的项目中,他们使用 cc_binary 并为他们创建了一个共享对象。我不知道发生了什么……我想我在做这个项目的时候会把头发都拔掉。
    • 我认为缺少的元素是设置linkshared = True,我第一次忘记提到了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 2016-09-26
    • 2012-03-27
    • 1970-01-01
    • 2010-11-17
    • 2011-03-22
    相关资源
    最近更新 更多