【问题标题】:Limiting the scope of global symbols from linked objects限制链接对象的全局符号范围
【发布时间】:2014-05-15 12:57:11
【问题描述】:

我在存档文件中有一个 C 库,clib.a。我为它编写了一个 C++ 包装器cpp.o,并希望将其用作静态库:

ar cTrvs cppwrap.a clib.a cpp.o

除非包含正确的标头,否则链接到此的代码将无法直接使用来自clib.a 的内容。但是,如果有人巧合地创建了一个合适的原型——例如void myCoincidentallyNamedGlobalFunction() -- 我担心myCoincidentallyNamedGlobalFunction 定义将适用。

由于来自clib.a 的符号只需要在cpp.o 中访问,而不是与cppwrap.a 相关的任何东西,有没有办法完全隐藏它们,以免发生冲突(所以即使包括clib标头会失败)?

【问题讨论】:

  • clib.o 是您自己构建的东西,还是您想要包装的由其他人提供的整体二进制文件?
  • @Jeff 我正在构建它,是的。
  • 所以你有几个选择,我想。你可以隐藏你不想在匿名命名空间中导出的方法/变量,这可能是最干净的方式,或者你可以手动 strip -Nobjcopy -N 符号你不想从最终的分布式库中公开。跨度>
  • 好吧,这可能是愚蠢的,但他可以把 c​​lib.o 放在它自己的库中,清理名称,然后将其归档到 cppwrap.a 中吗?
  • 好吧,也许不是完全愚蠢,因为 Jeff 也这么认为。我虽然符号剥离主要应用于调试....

标签: c++ c gcc static-linking unix-ar


【解决方案1】:

您可以手动删除最终组合库中不需要的符号:

$ objcopy -N foo cppwrap.a(删除符号)

或者,如果您需要符号但想确保外部用户无法访问它们:

$ objcopy -L bar cppwrap.a(本地化符号)

或者,如果clib.a 中的符号必须cpp.o 中的某物看到,但您不希望它被其他任何人使用:

$ objcopy -W baz cppwrap.a(弱化符号)

在这种情况下,与来自其他目标文件/库的符号的冲突将推迟到它们的使用,即使该符号仍然可见。为了进一步模糊事物或减少甚至是恭顺的碰撞的机会,您还可以使用:

$ objcopy --redefine-sym old=new cppwrap.a

匿名命名空间在某些情况下可能会有所帮助,但如果您的包装器需要某些功能但试图对外部用户隐藏,则不会。

【讨论】:

  • namespace 的解决方案当然会让cpp.o 中的函数无法调用clib.o 中的函数。
  • objcopy 返回 “不剥离符号 'baz',因为它是在重定位中命名的”。除非我误解了你的例子,否则使用命名空间并不好,因为 A)编译成 clib.o 的代码是 C 代码,B)我根本不想修改 clib,我只想将它完全黑盒化存档。
  • 对,起初我并不清楚她是需要简单地隐藏多余的符号还是试图确保核心功能只能通过 cpp.o 符号名称访问。
  • @goldilocks 好的,我想我知道你现在在哪里好一些了。尝试objcopy -L baz cppwrap.a 本地化符号。
  • 嗯。 objcopy -L baz 听起来对我来说是正确的,但随后又说,whereX/whereX/clib.o: No such file or directory 尽管 ar -t cppwrap.a 列出了 clib.owhereX/clib.o 已创建——也许这与 ar -T 是一个单独的困境? :\
猜你喜欢
  • 2022-08-19
  • 1970-01-01
  • 2011-12-31
  • 2012-01-10
  • 2011-03-23
  • 1970-01-01
  • 2017-05-06
  • 2018-07-25
  • 1970-01-01
相关资源
最近更新 更多