加入到新的团队后,首先发现的问题就是项目编译速度太慢了!简直慢到令人发指,什么概念呢,当你修改了项目的配置文件或者重新 pod install 或者其他改动,导致工程触发全量编译时,编译时间居然在30分~40分钟不等!
虽然以前了解过一些编译优化的工作,但没有亲自参与过,这一次也算是亲自实践了。比较明确的是,在进行优化之前,首先要做的一定是深入研究一下 Xcode 的编译过程,找到导致工程编译慢的罪魁祸首,对症下药方能解决问题。
一个简单的 Demo
为了方便辅助介绍 Xcode 的编译过程,用 Xcode 创建一个简单的 single view app,考虑到采用 Cocoapods 进行第三方库管理已经成了几乎所有 iOS 项目的标配,我这里使用本地源码创建的一个本地 pod 来实验。Log 目录下存在一个 TestLog.podpec 的文件,执行 pod install 后,就得到的集成后的工程,工程结构如下图所示:
注,Podfile 和 podspec 均使用官方命令产出:
pod init
pod spec create TestLog
页面启动后调用 XcodeLog 的类方法:+[XcodeLog log],打印一行日志:
ok,Demo 准备好了,也运行起来了,我们一起看下编译它过程。
Demo 编译过程
Xcode 非常的强大,强大到整个编译细节你都可以看到!
于是,我们 cmd + B 后,看到详细的编译日志:
流程大致分为:
- 编译 TestLog 这个 Target
- 编译 Pods-XcodeDemo 这个 Target
- 编译 XcodeDemo 这个主工程
- 编译完成
默认情况下,上面细节的界面隐藏了大量编译信息,我们可以通过点击每一条单独的任务进行展开,更详细的信息就在这里面了。
Target 编译
- Write auxiliary files
生成一些辅助文件,主要是 .hmap、LinkFileList 文件,用于辅助执行编译用的,可以提高二次编译速度。
Write auxiliary files
write-file /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-all-target-headers.hmap
write-file /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-generated-files.hmap
/bin/mkdir -p /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64
write-file /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/TestLog.LinkFileList
write-file /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-own-target-headers.hmap
write-file /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog.hmap
write-file /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-project-headers.hmap
write-file /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-all-non-framework-target-headers.hmap
- 编译 .m 文件
.m 是主要的源文件,经过预编译操作后,这里的 .m 是展开后的,可以独立编译生成最后的 .o 文件。
这里 CompileC 命令和 clang 命令
CompileC /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/XcodeLog.o /Users/ranger/tmp/XcodeDemo/XcodeDemo/Log/XcodeLog.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
cd /Users/ranger/tmp/XcodeDemo/Pods
export LANG=en_US.US-ASCII
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu11 -fobjc-arc -fobjc-weak -fmodules -fmodules-cache-path=/Users/ranger/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/Users/ranger/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -Wno-trigraphs -fpascal-strings -O0 -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-arc-repeated-use-of-weak -Wimplicit-retain-self -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wdeprecated-implementations -DPOD_CONFIGURATION_DEBUG=1 -DDEBUG=1 -DCOCOAPODS=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -mios-simulator-version-min=9.0 -g -Wno-sign-conversion -Winfinite-recursion -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wunguarded-availability -fobjc-abi-version=2 -fobjc-legacy-dispatch -index-store-path /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Index/DataStore -iquote /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-generated-files.hmap -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-own-target-headers.hmap -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-all-target-headers.hmap -iquote /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-project-headers.hmap -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog/include -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Private -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Private/TestLog -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Public -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Public/TestLog -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/DerivedSources/x86_64 -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/DerivedSources -F/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog -include /Users/ranger/tmp/XcodeDemo/Pods/Target\ Support\ Files/TestLog/TestLog-prefix.pch -MMD -MT dependencies -MF /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/XcodeLog.d --serialize-diagnostics /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/XcodeLog.dia -c /Users/ranger/tmp/XcodeDemo/XcodeDemo/Log/XcodeLog.m -o /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/XcodeLog.o
- 编译 xxx-dummy.m 文件
xxx-dummy.m 文件是 CocoaPods 使用的用于区分不同 pod 的编译文件,每个第三方库有不同的 target,所以每次编译第三方库时,都会新增几个文件:包含编译选项的.xcconfig文件,同时拥有编译设置和 CocoaPods 配置的私有 .xcconfig 文件,编译所必须的prefix.pch文件以及编译必须的文件 dummy.m
CompileC /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/TestLog-dummy.o Target\ Support\ Files/TestLog/TestLog-dummy.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
cd /Users/ranger/tmp/XcodeDemo/Pods
export LANG=en_US.US-ASCII
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu11 -fobjc-arc -fobjc-weak -fmodules -fmodules-cache-path=/Users/ranger/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/Users/ranger/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -Wno-trigraphs -fpascal-strings -O0 -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-arc-repeated-use-of-weak -Wimplicit-retain-self -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wdeprecated-implementations -DPOD_CONFIGURATION_DEBUG=1 -DDEBUG=1 -DCOCOAPODS=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -mios-simulator-version-min=9.0 -g -Wno-sign-conversion -Winfinite-recursion -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wunguarded-availability -fobjc-abi-version=2 -fobjc-legacy-dispatch -index-store-path /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Index/DataStore -iquote /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-generated-files.hmap -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-own-target-headers.hmap -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-all-target-headers.hmap -iquote /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/TestLog-project-headers.hmap -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog/include -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Private -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Private/TestLog -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Public -I/Users/ranger/tmp/XcodeDemo/Pods/Headers/Public/TestLog -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/DerivedSources/x86_64 -I/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/DerivedSources -F/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog -include /Users/ranger/tmp/XcodeDemo/Pods/Target\ Support\ Files/TestLog/TestLog-prefix.pch -MMD -MT dependencies -MF /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/TestLog-dummy.d --serialize-diagnostics /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/TestLog-dummy.dia -c /Users/ranger/tmp/XcodeDemo/Pods/Target\ Support\ Files/TestLog/TestLog-dummy.m -o /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/TestLog-dummy.o
- 创建静态库
创建当前架构的静态库,例如栗子中用的是模拟器,对应的是 x86_64 架构。
Libtool /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog/libTestLog.a normal x86_64
cd /Users/ranger/tmp/XcodeDemo/Pods
export IPHONEOS_DEPLOYMENT_TARGET=9.0
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only x86_64 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk -L/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog -filelist /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/TestLog.build/Objects-normal/x86_64/TestLog.LinkFileList -o /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog/libTestLog.a
- 拷贝头文件
将所有的头文件拷贝到 Pods 目录对应的 pod 里,没有头文件配合使用的二进制库是不能使用的。
CpHeader /Users/ranger/tmp/XcodeDemo/XcodeDemo/Log/XcodeLog.h /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog/XcodeLog.h
cd /Users/ranger/tmp/XcodeDemo/Pods
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -resolve-src-symlinks /Users/ranger/tmp/XcodeDemo/XcodeDemo/Log/XcodeLog.h /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog
- 拷贝资源文件(如果有)
主工程编译
- Write auxiliary files
- Process product packaging
- 执行 cocoapods 资源拷贝脚本
- 编译 .m 文件
- 链接静态库
- 编译资源文件
- Process info.plist file
- 执行 cocoapods 资源拷贝脚本
- 创建 .app
- 打包及签名
仔细观察
我们知道,XcodeDemo 是工程的主 Target,那 TestLog 和 Pods-XcodeDemo 是哪儿来的呢?
嗯,了解 CocoaPods 原理的同学都知道,CocoaPods 创建了 Pods 工程,引入新的工程来隐藏第三方库的依赖,从而管理第三方 pods。简单说就是主工程依赖 Pods 工程,Pods 工程依赖子
pods,从而间接被主工程依赖。而新的 Target 就是 CocoaPods 创建的。
仔细观察编译过程,我们会发现,除了主工程直接生成最终的 .app 外,其他工程(Target)都会编译成一个静态库被主工程去 Link,如果某个工程特别大,包含众多的 .m 文件或者其他资源文件,那么 Xcode 就会花费较多的时间去编译。
而在 Link 阶段,Xcode 会将前面创建的所有二进制文件做一次链接得到最后的二进制包
Ld /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/XcodeDemo.app/XcodeDemo normal x86_64
cd /Users/ranger/tmp/XcodeDemo
export IPHONEOS_DEPLOYMENT_TARGET=9.0
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk -L/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator -L/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/TestLog -F/Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator -filelist /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/XcodeDemo.build/Debug-iphonesimulator/XcodeDemo.build/Objects-normal/x86_64/XcodeDemo.LinkFileList -Xlinker -rpath -Xlinker @executable_path/Frameworks -mios-simulator-version-min=9.0 -dead_strip -Xlinker -object_path_lto -Xlinker /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/XcodeDemo.build/Debug-iphonesimulator/XcodeDemo.build/Objects-normal/x86_64/XcodeDemo_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc -fobjc-link-runtime -ObjC -lTestLog -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/XcodeDemo.build/Debug-iphonesimulator/XcodeDemo.build/XcodeDemo.app-Simulated.xcent -lPods-XcodeDemo -Xlinker -dependency_info -Xlinker /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Intermediates.noindex/XcodeDemo.build/Debug-iphonesimulator/XcodeDemo.build/Objects-normal/x86_64/XcodeDemo_dependency_info.dat -o /Users/ranger/Library/Developer/Xcode/DerivedData/XcodeDemo-fmyuqhxixlpjqqdzsflmuzdvhmgt/Build/Products/Debug-iphonesimulator/XcodeDemo.app/XcodeDemo
整体流程大概就是这样,即使再复杂的工程,也是类似的流程和操作。