Swift 源码编译

优质
小牛编辑
127浏览
2023-12-01

Swift(5.3.2) 源码编译

编译环境

  • Big Sur 11.2(20D64)
  • Python3 3.9.1
  • CMake 3.19.3
  • Ninja 1.10.2
  • Sccache 0.2.13 (可选)
  • Xcode 12.4(12D4e)

    第一次编译失败, CMake 版本为3.17.2, 之前本地编译OCLint时安装的一个版本, 如果编译的是更新的源码, 注意版本; Xcode版本与Swift源码版本有所要求, 版本不匹配会编译失败, 比如遇到什么指令集错误, Xcode内置SDK...; 其他工具不要求版本

    Ninja 是一个 low-level 构建系统,可用于构建项目,以替代Xcode的构建系统。Ninja更快,尤其是增量构建,并且支持更多构建环境。

    Sccache 是一个可选的缓存工具, Sccache 可以大大加快新构建的速度, 如果想要重新编译, 删掉build目录即可

编译的目的

  • 直接clone下来的源码, 大约 1/3 的文件都是.swift.gyb 的后缀文件, 编译的目的是为了让代码更易读

    也有更快捷的方式, 通过特定的脚本, 它会把所有的 .gyb 文件处理完毕后放到相同的位置并去掉 .gyb 后缀。 去除 --line-directive "" 在处理完毕的文件中添加 source location 的注释(就像 Swift build 中处理的一样)


进入正题

  1. 克隆项目

     git clone --branch swift-5.3.2-RELEASE https://github.com/apple/swift.git
    
  2. update-checkout

    一个脚本,可以帮助我们减少更新全部git仓库的工作量,避免手动克隆/更新每个git存储库

    Swift 项目使用了Git SubModule, 整个项目依赖结构:

     swift-source
     ├── cmark
     ├── indexstore-db
     ├── llbuild
     ├── llvm-project
     ├── ninja
     ├── sourcekit-lsp
     ├── swift
     ├── swift-corelibs-foundation
     ├── swift-corelibs-libdispatch
     ├── swift-corelibs-xctest
     ├── swift-format
     ├── swift-integration-tests
     ├── swift-stress-tester
     ├── swift-syntax
     ├── swift-tools-support-core
     ├── swift-xcode-playground-support
     └── swiftpm
    

    每一个都是一个submodule, 通过update-checkout能减轻我们的手工工作, 避免纰漏导致最后的编译环节失败

    切换至./swift-source/swift目录下, 然后执行

     utils/update-checkout --tag swift-5.3.2-RELEASE --clone
    

    这一步尤为重要, 请架好梯子(终端)

    此处省略一千万字:

     ...
     ...
     ...
     update-checkout succeeded
     cmake                              : skip
     cmark                              : 1168665f6b36be747ffe6b7b90bc54cfc17f42b7
     icu                                : skip
     indexstore-db                      : 58b306e0274155911dd4957945fd7e630798fec5
     llbuild                            : ef2e9ba657fd0a4e6e25fff05051b328bf27aeaf
     llvm-project                       : 3093af41dd65ad466dcd5603e9289244edfee4f5
     ninja                              : e72d1d581c945c158ed68d9bc48911063022a2c6
     sourcekit-lsp                      : 22116ca7554c9db3d96a938a451181bc6a4c58e8
     swift                              : 253ea65ba72933c92850803f0c26aa768757b3ab
     swift-argument-parser              : 15351c1cd009eba0b6e438bfef55ea9847a8dc4a
     swift-corelibs-foundation          : 1ad3b0ea7d0f711b05b737a3ff8ca47e03b8bdae
     swift-corelibs-libdispatch         : 25ea083a3af4ca09eee2b6dbdf58f1b163f87008
     swift-corelibs-xctest              : 8b0eefa96c02a4cb4d3eb74e6c289eba34a744fa
     swift-driver                       : aa97a352e17738f6445b8accb9fd85c9d5c196df
     swift-format                       : a062ec84d3230f9b9055123c7bb2903780c84608
     swift-integration-tests            : 11f0f6e8b34ba9782b5841dbeaa207d0b4620152
     swift-stress-tester                : 719d5c7be7172ab8a27bf9e015cb8bab102674ef
     swift-syntax                       : 844574d683f53d0737a9c6d706c3ef31ed2955eb
     swift-tools-support-core           : 3ae103eca680199224b6ab335db6a8ae3ecb43a3
     swift-xcode-playground-support     : 88043d7d320f92598efb39408c3f4b1903a4fff6
     swiftpm                            : 2bec212061295719620c7f4cf2d2e257a95aab39
     yams                               : 81a65c4069c28011ee432f2858ba0de49b086677
    

    update-checkout执行成功

  3. 编译

    在编译前决定要用于开发的IDE。有多个选项可用,这是因为Swift编译器使用CMake作为构建系统。 CMake支持为各种IDE(包括Xcode,Eclipse等)生成项目文件

    build-script 一个自动化脚本,用于处理配置(通过CMake)、构建(通过Ninja或Xcode)、缓存(通过Sccache)、运行测试等

    如果使用Sccache, 提前执行sccache --start-server

    编译过程中即可以使用ninja, 也可以使用Xcode来进行编译, 这里使用ninja来作为编译工具

    • ninja

      utils/build-script -R --debug-swift-stdlib -l
      
    • 生成Xcode调试项目

      编译后生成一个 Xcode project, 就可以在这个 project 中使用 Xcode 阅读源码了

      utils/build-script --clean -x -R --debug-swift
      

      build-script 参数说明

      | 参数 | 完整参数 | 说明 | |:-----:|:---------------------|:-----------------------------------------------| | -d |--debug | build the Debug variant of everything (LLVM, Clang,Swift host tools, target Swift standard libraries,LLDB)| | -r |--release-debuginfo | build the RelWithDebInfo variant of everything | | -R |--release | build the Release variant of everything | | - |--debug-swift-stdlib| build the Debug variant of the Swift standard library and SDK overlay | | -l |--lldb | build LLDB | | -m |--make | use CMake's Makefile generator | | -x |--xcode | use CMake's Xcode generator | | -h |--help | help |

      此处省略一亿个字, 期间我也失败过, 提示某些C++函数找不到...

  4. 使用VSCode来调试Swift

    • 先给VSCode安装CodeLLDB插件
    • 配置launch.json文件

      • VS Code打开swift-source文件夹, 点击运行->要自定义运行和调试创建launch.json文件->LLDB
      • 默认添加后参数

          {
              // 使用 IntelliSense 了解相关属性。 
              // 悬停以查看现有属性的描述。
              // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
              "version": "0.2.0",
              "configurations": [
        
                  {
                      "type": "lldb",
                      "request": "launch",
                      "name": "Debug",
                      "program": "${workspaceFolder}/build/Ninja-ReleaseAssert+stdlib-DebugAssert/swift-macosx-x86_64/bin/swift",
                      "args": [],
                      "cwd": "${workspaceFolder}"
                  }
              ]
          }
        
      • <your program> 改成 build/Ninja-ReleaseAssert+stdlib-DebugAssert/swift-macosx-x86_64/bin/swift 保存后运行

参考链接