iOS Duplicate Symbol静态库冲突解决

集成某三方私有库时,报iOS Duplicate Symbol错误,相关解决方案如下…

处理步骤:
  1. 拷贝Duplicate Symbol信息到sublime

  2. 正则过滤获取冲突的文件

    1
    2
    3
    4
    IFlyAudioSession.o
    IFlyCancelView.o
    IFlyContact.o
    IFlyDataDownloader.o...
  3. 查看库支持的框架类型、使用lipo命令分别将.a拆分成库所支持框架类型的.a库

    1
    2
    3
    4
    5
    lipo -info iflyMSC.framework/iflyMSC
    lipo iflyMSC.framework/iflyMSC -thin armv7 -output iflyMSC_armv7.a;
    lipo iflyMSC.framework/iflyMSC -thin i386 -output iflyMSC_i386.a;
    lipo iflyMSC.framework/iflyMSC -thin x86_64 -output iflyMSC_x86_64.a;
    lipo iflyMSC.framework/iflyMSC -thin arm64 -output iflyMSC_arm64.a
  4. 使用ar命令删除各个.a的冲突的.o,可以使用正则按规则批量生成语句

    1
    ar -d iflyMSC_arm64.a IFlyAudioSession.o;...
  5. 使用lipo命令将处理后的各个框架.a库合并

    1
    lipo -create -output iflyMSC iflyMSC_armv7.a iflyMSC_i386.a iflyMSC_x86_64.a iflyMSC_arm64.a
  6. 检查合并后的库支持的架构类型是否正确

    1
    lipo -info iflyMSC
  7. 将合并后的库(这里是iflyMSC)替换原framework里面的对应文件

知识点补充:
  1. sort -u可以对数据进行排序并去重

    1
    sort -u fileName > resultFileName
  2. ar -x 解压静态库

    1
    ar x libxxx.a
  3. nm -A 在每个符号信息的前面打印所在对象文件名称

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    nm [option(s)] [file(s)]
    有用的options:
    -A 在每个符号信息的前面打印所在对象文件名称;
    -C 输出demangle过了的符号名称;
    -D 打印动态符号;
    -l 使用对象文件中的调试信息打印出所在源文件及行号;
    -n 按照地址/符号值来排序;
    -u 打印出那些未定义的符号;
    eg. nm -A test.o
附件:脚本示例
1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
echo "查看库支持类型..."
lipo -info ACLifeKit.framework/ACLifeKit
echo "拆分.a库"
lipo ACLifeKit.framework/ACLifeKit -thin armv7 -output ACLifeKit_armv7.a
lipo ACLifeKit.framework/ACLifeKit -thin arm64 -output ACLifeKit_arm64.a
echo "移除在对应架构下的对应文件"
ar -d ACLifeKit_armv7.a error_code.o;ar -d ACLifeKit_armv7.a future.o;ar -d ACLifeKit_armv7.a ivMemory.o;ar -d ACLifeKit_armv7.a once.o;ar -d ACLifeKit_armv7.a regex.o;ar -d ACLifeKit_armv7.a test.o;ar -d ACLifeKit_armv7.a thread.o;ar -d ACLifeKit_arm64.a error_code.o;ar -d ACLifeKit_arm64.a future.o;ar -d ACLifeKit_arm64.a ivMemory.o;ar -d ACLifeKit_arm64.a once.o;ar -d ACLifeKit_arm64.a regex.o;ar -d ACLifeKit_arm64.a test.o;ar -d ACLifeKit_arm64.a thread.o;
echo "重新打包"
lipo -create -output ACLifeKit ACLifeKit_armv7.a ACLifeKit_arm64.a
疑问

上述脚本,ar -d多个连在一起的话,一次可能不能完全执行,部分ar -d执行失败,后续优化使用循环来处理,临时解决方案是将ar -d的语句执行3次。