Xcode Build Log 日志解析

2,350 阅读13分钟

本文主要想通过解析 Xcode 编译 log,让我们更加清晰的了解 Xcode 是如何帮助我们生成 app。

如下图,可以发现 xcode 是根据 target 分开进行编译的。每个 target 的具体的编译过程也可以通过展开 log 日志获得。

16631235986243.jpg

日志基本的格式就是首先简明一句说明要干什么,然后缩进的几行说明具体的操作。比如:

(1) ProcessPCH /.../Pods-SSZipArchive-prefix.pch.pch Pods-SSZipArchive-prefix.pch normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    (2) cd /.../Dev/objcio/Pods
        setenv LANG en_US.US-ASCII
        setenv PATH "..."
    (3) /.../Xcode.app/.../clang 
            (4) -x objective-c-header 
            (5) -arch armv7 
            ... configuration and warning flags ...
            (6) -DDEBUG=1 -DCOCOAPODS=1 
            ... include paths and more ...
            (7) -c 
            (8) /.../Pods-SSZipArchive-prefix.pch 
            (9) -o /.../Pods-SSZipArchive-prefix.pch.pch

就是在处理 pch 头文件,首先切换到 pch 的目录下,然后设置环境变量,然后启动 clang 并进行一系列的配置。在这之后一般就会产生具体的 .o文件作为产出(一般是有多个,针对不同的平台架构分别有一个,不过一般紧接着会把这些聚合成一个通用的 library。)。同时注意,不同的 target 也是有编译顺序的,具体的要看 target 之间的依赖关系。

接下来就是编译过程的控制,在 xcode 中可以通过 Build phases, Build settings 以及 Build rules 来进行控制。

Build phases 主要是用来控制从源文件到可执行文件的整个过程的,所以应该说是面向源文件的,包括编译哪些文件,以及在编译过程中执行一些自定义的脚本什么的。编译的时候将根据顺序来进行编译。这里固定的有:

  • Compile Sources:编译源文件。
  • Link Binary With Libraries:相关的链接库。
  • Copy Bundle Resources:要拷贝的资源文件,有时候如果一个资源文件在开发过程中发现找不到,可以在这里找一下,看看是不是加进来了。
  • 如果使用了 Cocoapods,那么将会被添加:
    • [CP] Check Pods Manifest.lock:检查 Podfile.lock 和 Manifest.lock 文件的一致性
    • [CP] Embed Pods Frameworks:将所有 cocoapods 打的 framework 拷贝到包中。
    • [CP] Copy Pods Resources:将所有 cocoapods 的资源文件拷贝到包中。

Build rules 主要是用来控制如何编译某种类型的源文件的,假如说相对某种类型的原文件进行特定的编译,那么就应该在这里进行编辑了。同时这里也会大量的运用一些 xcode 中的环境变量,完整的官方文档在这里:Build Settings Reference ,例如:

  • Copy Plist File:在编译打包的时候,将 info.plist 文件拷贝。
  • Compress PNG File:在编译打包的时候,将 PNG 文件压缩。
  • Swift Compiler:Swift 文件的编译方式,使用 Swift 编译器。

Build settings 则是对编译工作的细节进行设定,在这个窗口里可以看见大量的设置选项,从编译到打包再到代码签名都有,这里要注意 settings 的 section 分类,同时一般通过右侧的 inspector 就可以很好的理解选项的意义了。

最后,要说一下我们的工程文件.pbxproj,以上的所有的这些选项都保存在这个文件中。当然也包括 target 的信息,项目所有文件的信息,这个文件是一个文本文件,可以用文本编辑器打开。里头的内容基本是可读性比较强的。基本的思路很面向对象,每个东西都有属性,如果属性是另一个对象,值就是那个对象的一个『引用』,就是一串数字(唯一的)作为表示。每个对象都有这样的引用。

Building App 命令解析

构建一个应用程序不仅仅是编译和链接Obj-C文件。让我们先来看看这些步骤在整个构建流中的位置。 以下是构建日志中比较关键的流程:

Build target CompileDemo_Example of project CompileDemo with configuration Debug

WriteAuxiliaryFile xxx/CompileDemo_Example.hmap (in target 'CompileDemo_Example' from project 'CompileDemo')
    cd /Users/xxx/workspace/code/CompileDemo/Example
    write-file CompileDemo_Example.hmap 
    
CompileC xxx/CDAppDelegate.o xxx/CDAppDelegate.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC xxx/main.o xxx/main.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
Ld CompileDemo_Example normal (in target 'CompileDemo_Example' from project 'CompileDemo')

CompileStoryboard CompileDemo/Base.lproj/LaunchScreen.storyboard
CompileAssetCatalog CompileDemo/Images.xcassets
ProcessInfoPlistFile CompileDemo/Info.plist
LinkStoryboards ...

Touch CompileDemo_Example.app
CodeSign CompileDemo_Example.app
Build succeeded

主要流程就是把各个文件编译,最后链接到一起制作App。 这里重要的两点:

  • CompileC: Xcode如何编译类c代码
  • Ld: Xcode如何将目标文件链接到可执行文件中

命令解释

  • CreateBuildDirectory : 创建build目录,包含最终路径 Build/Products, 中间产物路径 Build/Intermediates.noindexs

16631262692907.jpg CreateBuildDirectory /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex cd /Users/xxx/workspace/code/CompileDemo/Example builtin-create-build-directory /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex * 每一个类都三个文件 .d、.dia、.o * .d: 表示这个类所依赖的其他类,即使用import导入的头文件,会自动寻找所有的依赖头文件,包含多级依赖 (a依赖b,b又依赖c,那么最终a也会依赖c) * .dia: 是diagnose的简写,就是诊断的意思,我们在Xcode写的源代码,经过编译的时候有时候会生成一些警告信息,都是放到这里面的 * .o: 对象文件,.m经过编译生成.o文件,用来链接到静态库/可执行文件中

  • WriteAuxiliaryFile: 写入辅助文件
    • 处理 Entitlements
    • .LinkFileList (链接的对象文件.o列表) image.png
    • .SwiftFileList (swift 文件路径列表)image.png
    WriteAuxiliaryFile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/all-product-headers.yaml (in target 'CompileDemo_Example' from project 'CompileDemo')
        cd /Users/xxx/workspace/code/CompileDemo/Example
        write-file /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/all-product-headers.yaml
    
    WriteAuxiliaryFile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/CompileDemo_Example-project-headers.hmap (in target 'CompileDemo_Example' from project 'CompileDemo')
        cd /Users/xxx/workspace/code/CompileDemo/Example
        write-file /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/CompileDemo_Example-project-headers.hmap
        
    WriteAuxiliaryFile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example.LinkFileList (in target 'CompileDemo_Example' from project 'CompileDemo')
        cd /Users/xxx/workspace/code/CompileDemo/Example
        write-file /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example.LinkFileList
        
    WriteAuxiliaryFile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example.SwiftFileList (in target 'CompileDemo_Example' from project 'CompileDemo')
        cd /Users/xxx/workspace/code/CompileDemo/Example
        write-file /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example.SwiftFileList
    
  • CompileC
    • -x <language>: 输入文件是用什么编程语言写的
    • -arch <architecture>: 编译的架构
    • -std=<standard>: 编程语言的标准集
    • -O0: 代码生成的时候的一些优化
    • -D<macroname>=<value>: 宏定义 #define
    • -iquote <directory>: inclue 的搜索路径
    • -I<directory>: 头文件搜索文件夹
    • -F<directory>: framework搜索文件
    • -MMD -MT dependencies -MF: 依赖文件 .d
      -MMD -MT dependencies -MF /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/main.d
      
    • --serialize-diagnostics: 代码诊断结果 .dia
    • -W: 编译警告
    • -Werror: 警告转错误
    • -c : 表示编译步骤: preprocess compile assemble ,没有链接步骤
    • ...
  • Libtool :链接 .o 文件
    Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool 
           -static 
           [-] file [...] [-filelist listfile[,dirname]] 
           [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols]
    
    Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool \
           -dynamic [-] file [...] [-filelist listfile[,dirname]] 
           [-arch_only arch] 
           [-o output] 
           [-install_name name] 
           [-compatibility_version #]
           [-current_version #]
           [-seg1addr 0x#]
           [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] 
           [-seg_addr_table <filename>] [-seg_addr_table_filename <file_system_path>] 
           [-all_load] [-noall_load]
    
    Libtool /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/Pods_CompileDemo_Example.framework/Pods_CompileDemo_Example normal (in target 'Pods-CompileDemo_Example' from project 'Pods')
        cd /Users/xxx/workspace/code/CompileDemo/Example/Pods
        export IPHONEOS_DEPLOYMENT_TARGET\=10.0
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool \
            -static \
            -arch_only arm64 \
            -D \
            -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk \
            -L/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator \
            -filelist /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Pods-CompileDemo_Example.build/Objects-normal/arm64/Pods_CompileDemo_Example.LinkFileList \
            -framework Foundation \
            -dependency_info /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Pods-CompileDemo_Example.build/Objects-normal/arm64/Pods_CompileDemo_Example_libtool_dependency_info.dat \
            -o /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/Pods_CompileDemo_Example.framework/Pods_CompileDemo_Example
    
  • Ld 将库链接到 app 可执行文件
    • -L :.a
    • -F :framework
    • -Xlinker :给链接器传递参数, -Xlinker -rpath-link -Xlinker <dir> -Xlinker <dir>
    Ld /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo_Example.app/CompileDemo_Example normal (in target 'CompileDemo_Example' from project 'CompileDemo')
       cd /Users/xxx/workspace/code/CompileDemo/Example
       /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -target arm64-apple-ios9.3-simulator 
           -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk 
           -L/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator 
           -F/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator 
           -F/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo 
           -filelist /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example.LinkFileList 
           -Xlinker -rpath -Xlinker /usr/lib/swift 
           -Xlinker -rpath -Xlinker @executable_path/Frameworks 
           -Xlinker -rpath -Xlinker @loader_path/Frameworks 
           -Xlinker -rpath -Xlinker @executable_path/Frameworks -dead_strip 
           -Xlinker -object_path_lto -Xlinker /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example_lto.o 
           -Xlinker -export_dynamic 
           -Xlinker -no_deduplicate 
           -Xlinker -objc_abi_version 
           -Xlinker 2 
           -fobjc-arc -fobjc-link-runtime 
           -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator 
           -L/usr/lib/swift 
           -Xlinker -add_ast_path 
           -Xlinker /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example.swiftmodule 
           -framework CompileDemo 
           -Xlinker -sectcreate 
           -Xlinker __TEXT 
           -Xlinker __entitlements 
           -Xlinker /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/CompileDemo_Example.app-Simulated.xcent 
           -framework CoreGraphics 
           -framework UIKit 
           -framework Foundation 
           -framework Pods_CompileDemo_Example 
           -Xlinker -no_adhoc_codesign 
           -Xlinker -dependency_info 
           -Xlinker /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CompileDemo_Example_dependency_info.dat 
           -o /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo_Example.app/CompileDemo_Example
    
  • 拷贝/处理资源文件
    • CpResource : caf、json、db、bundle、txt、jpg
    • CompileStoryboard 编译 .storyboard 为 .storyboardc 文件
    • CopyPlistFile
    • CopyPNGFile :copy直接放在项目文件夹中的图片文件,不是 .xcassets 中的图片
    • CompileAssetCatalog (编译 .xcassets 文件 为 Assets.car)
      • 对 .xcassets 文件进行处理 ,生成 .car 文件,同时会对 AppIcon 和 LaunchImage 进行处理,同时会对文件名称重新格式化命名
      • 生成 assetcatalog_generated_info.plist(是必须的AppIcon和LaunchImage信息), assetcatalog_dependencies(文件内容主要是AppIcon和LaunchImage的文件名称)
       CompileAssetCatalog /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo_Example.app /Users/xxx/workspace/code/CompileDemo/Example/CompileDemo/Images.xcassets (in target 'CompileDemo_Example' from project 'CompileDemo')
          cd /Users/xxx/workspace/code/CompileDemo/Example
          /Applications/Xcode.app/Contents/Developer/usr/bin/actool 
              --output-format human-readable-text 
              --notices --warnings 
              --export-dependency-info /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/assetcatalog_dependencies 
              --output-partial-info-plist /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/assetcatalog_generated_info.plist 
              --app-icon AppIcon 
              --compress-pngs 
              --enable-on-demand-resources YES 
              --filter-for-device-model iPod9,1 
              --filter-for-device-os-version 15.5 --development-region English 
              --target-device iphone 
              --target-device ipad 
              --minimum-deployment-target 9.3 
              --platform iphonesimulator 
              --compile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo_Example.app /Users/xxx/workspace/code/CompileDemo/Example/CompileDemo/Images.xcassets
      
    • ProcessInfoPlistFile:处理 info.plist 信息,把上面的处理 .xcassets 生成的 plist 文件合并到当前的 info.plist 文件上
      ProcessInfoPlistFile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo_Example.app/Info.plist /Users/xxx/workspace/code/CompileDemo/Example/CompileDemo/CompileDemo-Info.plist (in target 'CompileDemo_Example' from project 'CompileDemo')
          cd /Users/xxx/workspace/code/CompileDemo/Example
          builtin-infoPlistUtility /Users/xxx/workspace/code/CompileDemo/Example/CompileDemo/CompileDemo-Info.plist 
              -producttype com.apple.product-type.application 
              -genpkginfo /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo_Example.app/PkgInfo 
              -expandbuildsettings 
              -format binary 
              -platform iphonesimulator 
              -additionalcontentfile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Base.lproj/Main-SBPartialInfo.plist 
              -additionalcontentfile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Base.lproj/LaunchScreen-SBPartialInfo.plist 
              -additionalcontentfile /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/assetcatalog_generated_info.plist 
              -o /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo_Example.app/Info.plist
      
  • LinkStoryboards 链接前面生成的 storyboradc
  • PhaseScriptExecution:执行脚本,build phase 中的
  • CodeSign 签名:前面生成的Entitlements变成的.xcent文件,经过处理放置到 .app 文件夹下面

如果项目是基于CocoaPods,可以在Pods/Target Support Files/Pods-项目名/Pods-项目名-resource.sh文件中来看一下编译过程中对不同资源文件进行处理的命令。如下图,此处不逐一解释。

image.png

CompileC

  • 命令 Clang’s support for modules.
    • -x <language>: 输入文件是用什么编程语言写的,确保Clang与它编译的语言完全一致

    • export LANG:配置语言环境

    • -arch <architecture>: 编译的架构

    • -std=<standard>: 编程语言的标准集

    • -O0:代码生成的时候的一些优化级别,O0是不优化,以便编译器输出更详细,使编译器输出更接近于输入的代码,减少逐行调试和逐行设置断点导致的问题。

    • -g:启用调试信息生成

    • -DDEBUG=1: 确保可以使用 #if DEBUG

    • -D<macroname>=<value>: 宏定义 #define

    • -iquote <directory>: inclue 的搜索路径,#include "header.h"将在这个目录中查找,但 #include < header.h >不会

    • -I<directory>: 头文件搜索文件夹, include的引号和尖括号样式将在此目录中查找。

    • -F<directory>: framework搜索文件, -framework Some.framework 会优先在这里搜索

    • -iquote,-I 的使用会优先指定到 hmap,而不是头文件的路径,以加速头文件路径查找

    • -MMD -MT dependencies -MF: 依赖文件 .d, 目的应该是如果这个文件发生变化,应该重建的东西都有哪些

      -MMD -MT dependencies -MF /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/main.d
      
    • --serialize-diagnostics: 代码诊断结果 .dia

    • -c : 表示编译步骤: preprocess compile assemble ,没有链接步骤

    • -o :输出结果目录

    • -fobjc-legacy-dispatch:告诉clang应该采用什么样的Objective-C消息发送分派方法。

    • -fobjc-arc :使用arc

    • -fmodules启用模块、基于模块的导入和模块相关语法,像@import

    • -gmodules打开模块调试。

    • -fmodules-cache-path:告诉编译器在哪里缓存模块查找结果。Xcode在一个名为ModuleCache的文件夹中创建缓存数据目录。

      • 注意,模块缓存不是特定于项目的,而是在共享位置。如果你看一眼你的模块缓存目录,你会看到如下内容:
        • 一个 Session.modulevalidation 文件,模块构建会话文件,在 xxx/DerivedData/ModuleCache
        • 一个 modules.timestamp 文件,时间戳文件
        • 一堆目录文件,所有目录名都是13个大写字母数字字符。
        • 在每个目录中都有名为$(MODULE_NAME)-$(THIRTEEN_ALPHANUMERICS).pcm 及 的文件。大部分成对出现。有的可能有 modules.idx 文件, $(MODULE_NAME)-$(THIRTEEN_ALPHANUMERICS).pcm.lock 也有可能有
      • 这些是预编译的模块文件和相关的跟踪信息,保证模块的安全使用。
    • -fmodules-prune-interval:为编译器删除模块缓存的时间设置了一个最小界限。Xcode将其设置为24小时,这比编译器默认的7天要激进得多。

    • -fmodules-prune-after:表示,如果一个模块缓存文件在指定的秒数内没有被访问,那么它就可以被删除。Xcode将这个时间设置为4天,而不是编译器默认的31天。

    • -fmodules-validate-once- over -build-session:避免模块在单个构建会话期间重复验证。

    • -fbuild-session-file:命名一个文件,该文件的修改时间被视为构建会话开始的时间,这对于一些与模块何时验证什么相关的决策很重要。

    • -Wnon-modular-include-in-framework-module:打开警告:“warning: include of non-modular header inside framework module…”

    • Configure warnings

      • -Wno-:禁用警告;其余的则使他们得以实现。
      • -Werror-:导致编译器将已定义的警告转化成error。
    • -isysroot:告诉clang提供的目录是文件系统的根目录,并查找与该文件夹相关的系统头文件、库和工具。这是一种一次性重写标准查找路径的快速简便方法,而不需要一堆-I、-L、-F等标记来逐个完成。虽然它为我们做了很多工作,但还是有很多路径需要 -iquote,-I, -F。

    • -mios-simulator-version-min:最小system

    • ...

CompileC /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CDViewController.o /Users/xxx/workspace/code/CompileDemo/Example/CompileDemo/CDViewController.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target 'CompileDemo_Example' from project 'CompileDemo')
    <!--进入$SRCROOT目录,所有目标文件的根目录-->
    cd /Users/xxx/workspace/code/CompileDemo/Example
    export LANG\=en_US.US-ASCII
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang 
        -x objective-c 
        -target arm64-apple-ios9.3-simulator 
        -fmessage-length\=0 
        -fdiagnostics-show-note-include-stack 
        -fmacro-backtrace-limit\=0 
        <!--使用与C99对应的版本,并使用GNU扩展-->
        -std\=gnu99 
        -fobjc-arc 
        -fmodules 
        -gmodules 
        -fmodules-cache-path\=/Users/xxx/workspace/DerivedData/ModuleCache.noindex -fmodules-prune-interval\=86400 
        -fmodules-prune-after\=345600 
        -fbuild-session-file\=/Users/xxx/workspace/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 
        -Wno-missing-field-initializers 
        -Wno-missing-prototypes 
        -Werror\=return-type 
        -Wno-implicit-atomic-properties 
        -Werror\=deprecated-objc-isa-usage 
        -Wno-objc-interface-ivars 
        -Werror\=objc-root-class 
        -Wno-arc-repeated-use-of-weak 
        -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 
        -Wno-non-literal-null-conversion 
        -Wno-objc-literal-conversion -Wshorten-64-to-32 
        -Wpointer-sign 
        -Wno-newline-eof 
        -Wno-selector 
        -Wno-strict-selector-match 
        -Wundeclared-selector 
        -Wno-deprecated-implementations 
        -DDEBUG\=1 
        -DCOCOAPODS\=1 
        -DOBJC_OLD_DISPATCH_PROTOTYPES\=1 
        -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk 
        -fstrict-aliasing 
        -Wprotocol 
        -Wdeprecated-declarations 
        -g 
        -Wno-sign-conversion 
        -Wno-infinite-recursion 
        -Wno-comma 
        -Wno-block-capture-autoreleasing 
        -Wno-strict-prototypes 
        -Wno-semicolon-before-method-body 
        -fobjc-abi-version\=2 
        <!--告诉clang应该采用什么样的Objective-C消息发送分派方法-->
        -fobjc-legacy-dispatch 
        -index-store-path /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Index/DataStore 
        -iquote /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/CompileDemo_Example-generated-files.hmap 
        -I/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/CompileDemo_Example-own-target-headers.hmap 
        -I/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/CompileDemo_Example-all-non-framework-target-headers.hmap 
        -ivfsoverlay /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/all-product-headers.yaml 
        -iquote /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/CompileDemo_Example-project-headers.hmap 
        -I/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/include 
        -I/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo/CompileDemo.framework/Headers 
        -I/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/DerivedSources-normal/arm64 
        -I/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/DerivedSources/arm64 
        -I/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/DerivedSources 
        -F/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator 
        -F/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo 
        -include /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/PrecompiledHeaders/SharedPrecompiledHeaders/2206351231756493926/CompileDemo-Prefix.pch 
        -MMD -MT dependencies -MF /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CDViewController.d 
        --serialize-diagnostics /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CDViewController.dia 
        -c /Users/xxx/workspace/code/CompileDemo/Example/CompileDemo/CDViewController.m 
        -o /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CDViewController.o 
        -index-unit-output-path /CompileDemo.build/Debug-iphonesimulator/CompileDemo_Example.build/Objects-normal/arm64/CDViewController.o


<!--确保PATH包含特定于平台的二进制文件
它将用于解析命令名的PATH,如clang,设置为实际路径,如/usr/bin/clang:, 
以冒号分隔的PATH列表中的每个目录将按从左到右的顺序搜索与命令名匹配的目录,第一个目录胜出。
如果没有找到匹配,则在shell中得到一个“未知命令”错误-->
    export PATH\=/Users/xxx/Library/Developer/Toolchains/swift-BD-2022-05-25-15-51-44-lldb_framework-tools\=R-buildbot_osx_package-no_test.xctoolchain/usr/bin:
        /Users/xxx/Library/Developer/Toolchains/swift-BD-2022-05-25-15-51-44-lldb_framework-tools\=R-buildbot_osx_package-no_test.xctoolchain/usr/local/bin:
        /Users/xxx/Library/Developer/Toolchains/swift-BD-2022-05-25-15-51-44-lldb_framework-tools\=R-buildbot_osx_package-no_test.xctoolchain/usr/libexec:
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/bin:
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/libexec:
        /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/bin:
        /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/local/bin:
        /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:
        /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/local/bin:
        /Applications/Xcode.app/Contents/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/local/bin:
        /usr/local/bin:
        /usr/bin:
        /bin:
        /usr/sbin:
        /sbin

LD:将目标文件链接到可执行文件中

Ld $(CONFIGURATION_BUILD_DIR)/$(EXECUTABLE_PATH)
   normal
   x86_64

Xcode选择让clang前端为它管理所有的细节,而不是直接调用链接器。 为了做到这一点,它需要传递在编译过程中使用的许多选项,以保持相同的“环境”进行链接,所以这一次我们将遇到许多熟悉的标志,如-arch-isysroot,用于设置目标架构、搜索路径等。

  • 命令
    • -L :.a
    • -F :framework
    • -Xlinker :给链接器传递参数,是一个clang传参通道。 -Xlinker -rpath-link -Xlinker <dir> -Xlinker <dir> (还有另一种 WL)
      • -Xlinker -rpath -Xlinker @executable_path/Frameworks:运行时搜索路径,确保动态链接器dyld在运行时能够链接到内部的framework, 实际Xcode想要传递的参数是 -rpath @executable_path/Frameworks,但每个参数前必须加 -Xlinker image.png
        • -runpath: 运行可执行文件的搜索路径
        • @executable_path:相对于可执行文件的路径,用于运行时 dyld 进行链接
      • -object_path_lto : link-time optimization (LTO),链接时间优化,这个参数告诉链接器在哪里写入LTO时需要创建的临时文件。
        • 如果没标记,会选个点执行LTO,之后删除临时文件
        • 如果有标记,会保留该文件,以供其他工具随时查看,比如读取调试信息
      • -export_dynamic: 禁用全局内联和删除。可以防止LTO内联或以其他方式删除全局函数。最终需要导出的内容是动态确定的,应该是使 Xcode 更安全
      • -no_deduplicate :禁用链接器中的重复数据删除通道
      • -objc_abi_version :Obj-C ABI版本
      • -dependency_info :链接时文件依赖信息
    • -filelist:指定 .LinkFileList 链接文件列表,避免了在命令行中使用大量的文件路径作为它们自己的参数。文件本身只是一个以换行符分隔的文件路径列表。
    • -o:指定可执行文件输出路径,在 products 目录中的 app bundle 中,也是最终运行应用的地方。
Ld /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo/CompileDemo.framework/CompileDemo normal (in target 'CompileDemo' from project 'Pods')
    cd /Users/xxx/workspace/code/CompileDemo/Example/Pods
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang 
        -target arm64-apple-ios10.0-simulator 
        -dynamiclib 
        -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk 
        -L/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo 
        -F/Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo 
        -filelist /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/CompileDemo.build/Objects-normal/arm64/CompileDemo.LinkFileList 
        -install_name @rpath/CompileDemo.framework/CompileDemo 
        -Xlinker -rpath -Xlinker @executable_path/Frameworks 
        -Xlinker -rpath -Xlinker @loader_path/Frameworks -dead_strip 
        -Xlinker -object_path_lto 
        -Xlinker /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/CompileDemo.build/Objects-normal/arm64/CompileDemo_lto.o 
        -Xlinker -export_dynamic -Xlinker -no_deduplicate 
        -Xlinker -objc_abi_version -Xlinker 2 
        -fobjc-arc 
        -fobjc-link-runtime 
        -framework Foundation 
        -Xlinker -no_adhoc_codesign 
        -compatibility_version 1 
        -current_version 1 
        -Xlinker -dependency_info 
        -Xlinker /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/CompileDemo.build/Objects-normal/arm64/CompileDemo_dependency_info.dat
        -o /Users/xxx/workspace/DerivedData/CompileDemo-fswmtdmeapiqpkexlcagflyhmyfs/Build/Products/Debug-iphonesimulator/CompileDemo/CompileDemo.framework/CompileDemo

Manual Swift: Understanding the Swift/Objective-C Build Pipeline

Big Nerd Ranch - Build Log Groveling for Fun and Profit: Manual Swift Continued

Build Log Groveling for Fun and Profit, Part 2: Even More Manual Swift

Xcode 构建过程的幕后秘密

Xcode Build Settings