如何解决ios中第三方框架中的重复符号?

时间:2014-05-27 14:48:55

标签: ios google-plus amazon

我正在开发我的项目中的亚马逊登录和Google Plus共享。我在项目中添加了Amazon和Google plus框架。当我尝试构建项目时,它会显示“GooglePlus和Amazon Framework中的重复符号”错误。

错误消息

 duplicate symbol _kClientId in:
/Users/test/Amazon/Apps-SDK/iOS/LoginWithAmazon/LoginWithAmazon.framework/LoginWithAmazon(AIConstants.o)
/Users/test/GooglePlus/google-plus-ios-sdk-1.5.1/GooglePlus.framework/GooglePlus(GPPOzLogger.o)
 ld: 1 duplicate symbol for architecture i386
 clang: error: linker command failed with exit code 1 (use -v to see invocation)

如何解决此类错误?

3 个答案:

答案 0 :(得分:2)

您真正要做的就是联系Google和/或亚马逊并告诉他们修复冲突的框架。当像这样的名字发生冲突的可能性非常高时,他们俩在他们的框架中使用像_kClientId这样的全局符号名称是愚蠢的。对于每个相应的框架,名称实际上应该是_kGooglePlus_iOS_Framework_ClientId_kAmazon_iOS_Framework_ClientId,以减少符号名称冲突的可能性。

要么这样做,要么使用不同的框架或库用于Google Plus或Amazon,如果可以的话。或者,如果您不能这样做,请使用HEX编辑器手动更改其中一个框架中对_kClientId符号的所有引用。

答案 1 :(得分:1)

我以前遇到过同样的问题。最后我想出了如何解决这个问题。 作为图书馆的客户,我们无法避免它,但我们仍然有机会处理它。 我的答案包括两个部分,一个用于描述问题,一个用于解决这个问题作为框架的客户端(这意味着我们必须通过我们自己解决这个问题而不是要求框架开发人员来解决这个问题)。

1)碰撞是如何发生的,链接错误是什么意思?

框架实际上是一个文件夹,进入框架你会发现一个lib文件。有时lib文件的扩展名为* .a或者没有扩展名。 lib文件的结构如下所示:

libFoo.a  /  i386  /
                      hello.o
                      world.o
             arm64 /  
                      hello.o
                      world.o

在这种情况下,libFoo.a是一个胖库,这意味着它包含多个体系结构。链接错误告诉您在同一架构中有两个包含相同.o(符号)文件的库。

例如您的案例:

duplicate symbol _kClientId in:
/Users/test/Amazon/Apps-SDK/iOS/LoginWithAmazon/LoginWithAmazon.framework/LoginWithAmazon(AIConstants.o)
/Users/test/GooglePlus/google-plus-ios-sdk-1.5.1/GooglePlus.framework/GooglePlus(GPPOzLogger.o)
ld: 1 duplicate symbol for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这意味着在两个框架中,您在i386架构中有重复的.o文件。

2)如何解决问题。

我们需要一些工具来解决这个问题。幸运的是,您应该在计算机中安装这些工具。 我们需要做的是打开一个框架并做一些手术以删除重复的符号并将其关闭。

我在这里演示了在i386架构下删除LoginWithAmazon中的重复符号AIConstants.o的过程:

lipo -info LoginWithAmazon //this is going to show us the architectures in the fat library
lipo LoginWithAmazon -thin i386 -output LoginWithAmazon-i386 //we extract the i386 architecture as xxx-i386 from fat library
//use the same command to extract every architecture from fat libraray as xxx-archname

ar -t LoginWithAmazon-i386 // list of symbols in this architecture, we should see AIConstants.o in it
ar -d LoginWithAmazon-i386 AIConstants.o // delete AIConstants.o from LoginWithAmazon-i386
//now work is done, we put everything back to the fat library

lipo LoginWithAmazon-i386 LoginWithAmazon-arm64 <every architecture you extracted from the fat library> -create -output LoginWithAmazon-new
ranlib -s LoginWithAmazon-new //sometime we need to rebuild the symbol table
//now you have done the work, use LoginWithAmazon-new to replace the old LoginWithAmazon, and try to compile your program again

<强> REF:

http://blog.sigmapoint.pl/avoiding-dependency-collisions-in-ios-static-library-managed-by-cocoapods/

答案 2 :(得分:0)

似乎这个问题并不是亚马逊团队登录的重中之重。

作为临时解决方案(信不信由你),您可以使用文本编辑器替换所有出现的&#34; _kClientId&#34;在LoginWithAmazon二进制文件中使用其他内容(例如&#34; _kClientIe&#34;)。

另见我的回答:

https://github.com/aws/aws-sdk-ios/issues/18