【问题标题】:Trouble linking C++ with Xcode 5无法将 C++ 与 Xcode 5 链接
【发布时间】:2014-02-12 21:47:15
【问题描述】:

所以我有这个遗留项目,我正试图将它带到 iOS 7 和 Xcode 5。遗留,我的意思是真正的遗留。就像 2004 年的遗产一样。

无论如何,我正在尝试构建这个东西,它会吐出一些库,包括一些常见的第三方库。链接时,我收到如下错误:

Undefined symbols for architecture ${arch}:
  "google::protobuf::internal::WireFormatLite::WriteBytes(int, std::string const&, google::protobuf::io::CodedOutputStream*)"

在使用nm 进行检查后,仍包含在项目中的旧(仅限 arm)二进制库包含以下内容:

         U __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS0_2io17CodedOutputStreamE
00000a8c T __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS0_2io17CodedOutputStreamE
00002b28 S __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS0_2io17CodedOutputStreamE.eh</code>

当我通过 Xcode 5(因此,clang/llvm)运行项目时创建的新库(通用)包含以下内容:

         U __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKSsPNS0_2io17CodedOutputStreamE
00000514 T __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKSsPNS0_2io17CodedOutputStreamE
00000b2c S __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKSsPNS0_2io17CodedOutputStreamE.eh

对我来说,看起来错位名称中缺少参数。

这正常吗,我需要看看其他地方吗?

或者如果这是问题所在:知道如何解决吗?

编辑:我把旧的和新的混在一起了。我保持原帖不变

【问题讨论】:

    标签: c++ ios xcode clang llvm


    【解决方案1】:

    旧的,只有 arm 的库似乎表明:

    google::protobuf::internal::WireFormatLite::WriteBytes(int, std::string const&, google::protobuf::io::CodedOutputStream*)
    

    它具有使用 libstdc++ 编译的所有特征。

    新的通用库表明:

    google::protobuf::internal::WireFormatLite::WriteBytes(int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::io::CodedOutputStream*)
    

    这具有使用 libc++ 编译的所有特征

    你的链接错误说明发现有问题:

     google::protobuf::internal::WireFormatLite::WriteBytes(int, std::string const&, google::protobuf::io::CodedOutputStream*)
    

    如果链接到库的代码是使用 libstdc++ 编译的,就会出现这种情况,因为您的新通用库是使用 libc++ 编译的,所以代码不会链接。

    您必须使用相同的 libc++/libstdc++ 支持编译所有内容,您不能混用和匹配,因为它们会拒绝链接。确保项目中的每个元素都是使用相同的 C++ 标准库编译的,并且应该解决链接错误。

    通常,对符号进行分解(使用c++filt)可以让您看到正确的签名,并且在此代码的情况下,一旦您开始在符号中看到std::__1::,则表明该库是使用编译的libc++,并且当您看到链接失败并带有未经修饰的std:: 符号(即没有内部__1::)时,则表明执行链接的项目正在使用libstdc++

    【讨论】:

    • 对不起,我好像把新旧混在一起了,我想这是有道理的。这可能表明我正在链接的应用程序仍在链接 libstdc++,对吧?
    • 似乎更有可能的是,如果您交换了新旧的提及,则表明基于 protobuf 的库现在已使用 libc++ 构建,并且您的应用程序正在使用 libstdc++ 构建 - 这就是错误的链接线正在声明。应用程序中链接的签名似乎表明这是问题所在(我会在跑步回来后更新答案)
    【解决方案2】:

    您是否正在混合和匹配 SDK 或编译器?编译器之间的名称修饰可能会有所不同。我所知道的唯一可能影响名称修饰的另一件事是'extern "C"' 关键字,但这通常会完全关闭它,所以我不认为就是这样。

    因此,如果旧代码仍然是使用 GCC 2.x 构建的,而您的新代码是由 clang 构建的,那么它们可能只是进行了不同的处理。

    错误信息真的是 $(arch) 吗?不是特定的架构?如果它给出了一个具体的架构,我希望你有一个可以构建的项目,例如对于 arm5 和 arm6,链接到只有其中一种架构的库中。然后它通常会抱怨该库中的符号不​​可用,我想。

    【讨论】:

    • (不,我输入了 ${arch} 表示它对 arm 和 x86 都失败了}
    猜你喜欢
    • 1970-01-01
    • 2013-09-26
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2015-03-15
    • 2013-10-18
    相关资源
    最近更新 更多