XCode归档(Archive)过程及部分错误的分析
先介绍一下iOS开发中使用的编译器LLVM
开发iOSApp的Objective-C / Swift是编译型语言,从XCode5之后其对应的编译器正式有GCC过渡到LLVM(5.0)。
经典编译器设计:
LLVM的设计简介:
这种前端-优化器-后端的设计,可以方便的接入多种语言,和多种CPU架构。
LLVM包括:
- LLVM核心库:
LLVM提供一个独立的链接代码优化器为许多流行CPU(以及一些不太常见的CPU)的代码生成支持。这些库是围绕一个指定良好的代码表示构建的,称为LLVM中间表示(“LLVM IR”)。LLVM还可以充当JIT编译器 - 它支持x86 / x86_64和PPC / PPC64程序集生成,并具有针对编译速度的快速代码优化。。 - LLVM IR 生成器Clang:
Clang是一个“LLVM原生”C / C ++ / Objective-C编译器,旨在提供惊人的快速编译(例如,在调试配置中编译Objective-C代码时比GCC快3倍),非常有用的错误和警告消息以及提供构建优秀源代码工具的平台。 - LLDB项目:
LLDB项目以LLVM和Clang提供的库为基础,提供了一个出色的本机调试器。它使用Clang AST和表达式解析器,LLVM JIT,LLVM反汇编程序等,以便提供“正常工作”的体验。在加载符号时,它也比GDB快速且内存效率更高。 - List item
libc ++和libc++:
libc ++和libc++ ABI项目提供了C ++标准库的标准符合性和高性能实现,包括对C ++ 11的完全支持。 - lld项目:
lld项目旨在成为clang / llvm的内置链接器。目前,clang必须调用系统链接器来生成可执行文件。
其他的就不再详细介绍了,详情可以参考(LLVM和Clang)
归档过程
1,如果是使用了Pod的workspace,会依次对其包含的工程进行编译。
2,查找Target的Build Phases中设定的依赖Dependencies,首先编译这些依赖的Targets
3,编译过程正式开始。
3.1,检查依赖
3.2,写入辅助文件:将项目的文件结构对应表、将要执行的脚本、项目依赖库的文件结构对应表写成文件,方便后面使用;并且创建一个 .app 包,后面编译后的文件都会被放入包中
3.3,运行预设脚本:Cocoapods 会预设一些脚本,当然你也可以自己预设一些脚本来运行。
3.4,编译文件:针对每一个文件进行编译,生成可执行文件 Mach-O,这过程 LLVM 的完整流程,前端、优化器、后端。先编译.Swift后.m,可以查看每个文件的编译时间以及error和warning。
Swift文件编译命令:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift
.m文件编译命令:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
3.5,链接文件
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -rpath -Xlinker /usr/lib/swift
3.6,拷贝资源文件
3.7,编译storyboard,xib文件
3.8,编译asset文件 CompileAssetCatalog
3.9,处理info.plist文件 ProcessInfoPlistFile
3.10,生成符号表 GenerateDSYMFile
3.11,执行pod配置的脚本,将在编译项目之前已经编译好的依赖库和相关资源拷贝到包中,同时进行签名。
3.12,打包生成app文件 ProcessProductPackaging
对Build Phases中Embed Frameworks中手动添加的第三方库进行授权(Entitlements)和签名(CodeSign)。
3.13,生成最终的.app。对于Swift工程,需要拷贝Swift库CopySwiftLibs。并对改再次进行签名。
3.14,验证(Validate),导出成.ipa文件。
错误及分析
错误1 XCode调整运行正常,但是打包时报错Failed to emit precompiled header for bridging-header.h
解决:删除Podfile.lock重新进行pod install
错误2 执行Pod install后尝试编译,bridging-header中报某个头文件找不到的错误,编译失败。
解决:①添加{PODS_ROOT} recursive 到Search Path -> User Header Search Paths
错误3 打包执行到编译Swift文件时报错:No such module ‘ObjectMapper’
解决:或许这个位置下的文件被清理找不到了,/Users/work/Library/Developer/Xcode/DerivedData/Mara-daajgszwtouixcfnoaiawbxybpvd/Build/Intermediates.noindex/ArchiveIntermediates/Mara/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/ObjectMapper.framework
重新进行pod install可以解决。
错误4 将包上传至商店后收到邮件:ITMS-90381: Too many symbol files - These symbols have no corresponding slice in any binary [DD74A7DF-9480-33CB-A701-873C18862ABA.symbols…
分析:
说的是这些符号文件找不到对应的二进制中对应的切片。
用以下命令查看都是Pod进入的库的armv7的symbol,将pod工程对应的架构跟主工程一致即可。
dwarfdump --uuid *
参考文章:
1,浅谈iOS编译过程
2,iOS开发符号表(dSYM)知识总结
上一篇: Cisco VPP入门(四)——VPP示例插件编译运行
下一篇: Qt学习笔记(二十九):Qt 事件