来自链接器的奇怪警告(ld)[重复]
Posted
技术标签:
【中文标题】来自链接器的奇怪警告(ld)[重复]【英文标题】:Strange warnings from the linker (ld) [duplicate] 【发布时间】:2012-04-11 07:18:29 【问题描述】:我们正在构建一个主要使用 Obj-C/Cocoa 编写的 Mac OSX 应用程序。 然后,该应用程序静态链接到一些用 C/C++ 编写并由我们编译的第 3 方库(在命令行上,使用 MacPorts 或通常的“./configure && make”;都是通用二进制文件)。
应用程序运行良好,但在广告编译时我们总是收到这些奇怪的链接器警告:
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZN5boost10scoped_ptrIN4i18n12phonenumbers15PhoneNumberUtilEED1Ev means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
这来自 C/C++ 库。我们正在链接这些库:
-
libphonenumber,显然是导致 5 个警告中的 4 个的原因。由我们通过“cmake”编译。
boost (libboost_thread-mt),负责 1 个警告。使用 MacPorts 编译。
ICU(libicudata、libicuuc、libicui18n),使用 MacPorts 编译。
Protocol Buffers,通过“./configure && make”编译。
请注意:
-
尽管出现警告,但应用程序运行良好,但我们希望摆脱它们,因为它们很烦人。
xcode with boost : linker(Id) Warning about visibility settings 提出的解决方案不起作用:“默认隐藏符号”一直是“YES”。
【问题讨论】:
您可以通过使用“re2”正则表达式库而不是使用 C 标志-DUSE_RE2=1
的完整 ICU 库来缩小 libphonenumber
@MattConnolly ICU 还不需要吗?它可以将 re2 用于正则表达式,但它仍然需要 ICU 来处理其他事情......最终,我找到了一个“解决方案”。这绝对是一个肮脏的,但有效:使用 JS(是的,javascript)版本并从 Cocoa 调用它。它也比我预期的要快!
您可以链接到 ios 提供的 icucore 库。你不需要设置一个webview来运行javascript吗?如果它使用 v8 优化器,它可能没问题...我也将它 git 看看。
@MattConnolly 不,您不需要设置 Web 视图来运行 JS 代码。您可以使用 JavaScriptCore 框架,它是 WebKit 的一部分并捆绑在 OS 中......性能其实还不错!
【参考方案1】:
xcode 提出的带有 boost 的解决方案:linker(Id) 警告 可见性设置不起作用:“默认情况下隐藏的符号”有 一直都是“YES”。
这与设置为“YES”的关系不大,更多的是与在所有项目中设置为相同的值有关。依赖于其他库的库/项目需要同样设置“默认隐藏符号”,以便正确链接且没有错误/警告。
我以前遇到过这种情况,在 Xcode 中对所有项目进行简单更改以确保设置匹配通常可以解决问题。由于听起来您也在命令行上进行编译,因此您需要查看 gcc
的 -fvisibility
参数。
【讨论】:
感谢您的回答。但是,我不确定我是否理解清楚:您的意思是我应该在编译 boost、libphonenumbers 等时向 GCC 添加“fvisibility”? 是的,如果您使用 gcc 编译这些文件,我将从这里开始。添加-fvisibility=default
将使所有符号“公开”。当然,您项目的最终正确选择取决于您的需求,因此我会通过在终端中运行 man gcc
或在 Google 中搜索它们来阅读有关 -fvisibility
的文档。但是,正如我所提到的,确保所有项目都使用相同的 -fvisibility
设置通常可以解决这个问题。以default
开头(本质上是“public”)。
谢谢。我明天去试试,结果会告诉你的!
仅供参考,我刚刚检查了使用静态库的 Xcode 项目,其中大多数实际上将“默认隐藏的符号”设置为“否”。我不确定 Xcode 如何将其转换为 -fvisibility
设置,因为它似乎只在设置为“YES”时将其包含在命令行输出中(在这种情况下,它确实是 -fvisibility=hidden
,这与 @987654330 基本上相反@)。最坏的情况,在你的 makefile(s) 中使用 -fvisibility=default
并将它添加到你的 Xcode 项目中的“Other C Flags”中。
好的,所以我用开关重新编译了libphonenumber,没有任何改变。但是,之后我按照您的建议将“默认隐藏的符号”更改为“否”,现在所有与 libphonenumber 相关的警告都消失了。只有与 boost 相关的那个(但重新编译 boost 需要 1 小时,所以我稍后会这样做:))。谢谢!【参考方案2】:
出于类似的原因,我也得到了这个,但我认为问题是内联可见性设置不一致。
见http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-December/046505.html
我将所有内联隐藏设置为否,警告(最终)消失了。
【讨论】:
试过inspector-g的答案,但它没有用,但这个摆脱了我的警告。好像是同一个概念,只是设置不同。【参考方案3】:tl:博士;在您编译的所有内容中使用-fvisibility=hidden
作为 gcc 和 llvm 编译器开关,包括您的依赖库,除非您有理由不这样做。
在撰写本文时,Apple's web site 上提供了 -fvisibility 和 -fvisibility-inline-hidden 编译标志的良好介绍。本文还详细介绍了 __attribute__((visibility("hidden")))
和 __attribute__((visibility("default")))
声明。
【讨论】:
是的。有时,如果您使用 -fvisibility=hidden,则必须公开一些带有属性的符号(或 push/pop,如链接中所述)。【参考方案4】:通过将 -fvisibility=hidden -fvisibility-inlines-hidden
放入 OTHER C++ FLAGS,我在 Xcode 中消除了警告。
【讨论】:
有点蹩脚的补充,但把这些放在“其他 C 标志”中,因为 C++ 标志通常设置为从 C 标志继承以上是关于来自链接器的奇怪警告(ld)[重复]的主要内容,如果未能解决你的问题,请参考以下文章