无法将C ++与Xcode 5联系起来

时间:2014-02-12 21:47:15

标签: c++ ios xcode clang llvm

所以我有这个遗留项目,我试图为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

对我而言,看起来错误的名称中缺少参数。

这是正常的,我需要看看别的地方吗?

或者如果这是问题:任何想法如何解决?

编辑:我混淆了OLD和NEW。我原来的帖子保持不变

2 个答案:

答案 0 :(得分:2)

旧的,只有手臂的图书馆似乎表明:

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::)时,则表示执行链接的项目正在使用{{ 1}}。

答案 1 :(得分:0)

您是混合和匹配SDK还是编译器?名称重整可能在编译器之间有所不同。我知道唯一可能会影响名称修改的另一件事是'extern“C”'关键字,但通常会将其完全关闭,所以我认为不是这样。

所以,如果旧的代码仍然是用GCC 2.x构建的,并且你的新代码是铿锵有力的,那么它们可能会以不同的方式进行修改。

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