【问题标题】:Link error adding library built with Clang to iOS app built with GCC将使用 Clang 构建的库添加到使用 GCC 构建的 iOS 应用程序时出现链接错误
【发布时间】:2013-09-10 14:06:42
【问题描述】:

我正在尝试将 Dropbox Sync API (v1.1.2) 添加到使用 Marmalade (v6.3) 构建的 iOS 应用中。我收到以下链接错误:

Undefined symbols for architecture armv7:
"___udivmodsi4", referenced from:
_sqlite3BitvecSet in libDropbox.a(sqlite3.o)
_sqlite3BitvecClear in libDropbox.a(sqlite3.o)
_sqlite3BitvecTest in libDropbox.a(sqlite3.o)
ld: symbol(s) not found for architecture armv7

通过谷歌搜索该错误消息的相关部分,发现某个 SQLCipher 库的许多用户遇到了同样的问题,并建议该问题是由用于构建该库的编译器和使用它的各种项目的不一致引起的.

由于我们项目的构建系统是由 Marmalade 工具集设置的,因此我认为更改编译器(我相信目前是 Marmalade 提供的 GCC 4.4 版本)不是一种选择。

谁能更准确地告诉我出了什么问题?这个问题还有其他解决方法吗?

【问题讨论】:

    标签: ios linker dropbox-api marmalade marmalade-edk


    【解决方案1】:

    在像 ARM 这样的处理器上,指令集相对简单,一些更复杂的操作被映射到函数调用而不是指令序列。当您使用“正确”编译器进行链接时,它们的实现会被引入并且可以正常工作!你通常看不到它。

    这里明显的解决方案是使用 marmalade 来编译 Dropbox 库,然后它将使用兼容的编译器。

    那么问题来了,我猜你是否有理由不这样做?当前的 Marmalade 编译器不支持 ARC。我想这将是不在 ARC 下编译的原因。

    【讨论】:

    • 感谢您的信息。 Dropbox 库是 Dropbox 提供的二进制文件。我没有源代码,无法重新编译。 (事实上​​,即使我有源代码,我也无法使用 Marmalade 重新编译它,因为 Dropbox 告诉我它使用了 Marmalade 的 GCC 4.4 不支持的 Objective-C 功能。)
    【解决方案2】:

    另一个答案是正确的。但是,对于这个特定问题(如果这些是您遇到的唯一链接器错误),我看到了两种解决方法:

    1. 从包含sqlite3BitvecSet 的sqlite3 中获取源代码并在您自己的项目中编译这些函数以覆盖该库。他们将获取您自己的编译器提供的任何 divmod 支持。
    2. 实现您自己的udivmodsi4。您不必实现按位除法(尽管您可以从 GCC 源代码中获取基本的 C 实现)。您只需在本机操作中实现它并让您的编译器调用它需要的任何内部支持。

    这是未经测试的,但应该给你基本的想法。您可能需要在名称上添加更多下划线以匹配其他构建环境的行为/命名:

    unsigned long
    udivmodsi4(unsigned long num, unsigned long den, int modwanted)
    {
        if (modwanted)
            return num % den;
        else
            return num / den;
    }
    

    【讨论】:

    • 在阅读了您对其他问题的回答后,我昨天实际上实施了解决方法 2,并且代码现在链接了,但最好确认这是一种明智的方法。谢谢!
    • 看起来问题只是 libgcc 直到 4.7 版才添加 udivmodsi4 函数。是的,我必须添加两个下划线才能使其正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2022-07-04
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多