【问题标题】:Undefined symbols: for -fvisibility=hidden未定义符号:for -fvisibility=hidden
【发布时间】:2012-02-13 16:52:48
【问题描述】:

我遇到了无法修复的链接器问题(使用 MacOS 和 xcode)。

首先,当我使用 -fvisibility=hidden 编译时,一切都很好。如果我省略那个标志,我会得到

"XYZ::IPlugView::iid", referenced from:
     __ZN9XYZ9IPlugView3iidE$non_lazy_ptr in pluginview.o
     (maybe you meant: __ZN9XYZ9IPlugView3iidE$non_lazy_ptr)

我不知道这是否相关,但在此之前有几个警告,例如

ld: 警告:非虚拟 thunk 到 XYZ...::release() 在 xyz/foo.o 和 xyz/bar.o 中具有不同的可见性(隐藏)和(默认)

任何想法将不胜感激...... 谢谢!

【问题讨论】:

    标签: xcode linker symbols


    【解决方案1】:

    这些警告实际上可能是相关的。这些警告试图告诉您的是,有一个名为 XYZ...::release() 的符号,并且该符号被定义了两次,一次在文件 xyz/foo.o(可能从 xyz/foo.cc 编译)中,一次在文件 xyz/bar.o(可能编译自xyz/bar.cc),但是,该符号不是两次以相同的可见性定义的,一个符号是默认的(在您正在编译的当前二进制文件/库之外可见),一个是隐藏的(仅在您当前的二进制文件/库中可见)正在编译)。当然,同一个符号不能有两种不同的可见性。

    通过使用-fvisibility=hidden,您可以告诉编译器:只要没有定义符号可见性的代码注释,就隐藏这个符号。这可能会解决您的问题,因为曾经隐藏一次且默认一次的重复符号现在被隐藏了两次,因为曾经默认的定义可能被隐式设为默认,而现在它被隐式设为隐藏,这意味着该符号被隐藏了两次这解决了冲突,因为这两个符号可能被链接器视为一个符号。

    在您的源代码中,有两种方法可以设置符号的可见性,通过属性或编译指示。要隐藏符号,您可以在其定义前面附加__attribute__ ((visibility ("hidden"))),也可以在源文件中的某处放置一个编译指示#pragma GCC visibility push(visibility),导致它下面的所有符号定义都被设置为隐藏,直到您使用编译指示@ 987654329@ 返回之前的可见性状态(如果没有之前的状态,则返回默认状态),使用另一个 pragma 将可见性更改为其他内容或文件末尾,无论先出现什么。

    我认为在您的情况下,有问题的符号曾经在 foo.cc 中以显式可见性(隐藏)定义,在 bar.cc 中定义一次且没有显式可见性,因此它是默认的或隐藏的,具体取决于您的 @ 987654330@标志。

    【讨论】:

      猜你喜欢
      • 2011-04-03
      • 2020-08-22
      • 2017-12-13
      • 1970-01-01
      • 2016-06-22
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      相关资源
      最近更新 更多