编译 Swift 5.8 源码

编译预备

首要保证硬盘空间满足,自己一套流程下来文件夹有将近 60GB 大小。接下来是相关环境的装置,由于我的环境都是最新的,所以根本装置的都是最新版的包,假如你的环境不是新版的话,请找对应版别包装置。自己环境说明:

  • 芯片:Apple M2 Pro
  • macOS:Ventura 13.3
  • Xcode:14.3
  • Python:3.11.2
  • CMake:3.26.3
  • ninja:1.11.1
  • sccache:0.4.1

咱们能够通过 homebrew 统一装置环境:

$ brew install cmake ninja sccache

此文只介绍 Xcode 调试环境,假如想用 VS Code 调试的话,需求用 Ninja 编译,Ninja 的编译请移步官方文档。

项目拉取

首要咱们在文稿中新建一个文件夹,然后 cd 到咱们的目录:

$ mkdir ~/Documents/swift-project
$ cd ~/Documents/swift-project

然后找到你的 Xcode 所支持的 Swift 版别,由于自己的 Xcode 为 14.3 版别,所以直接下载 Swift 5.8 Release。查找 Xcode 对应的 Swift 的版别有两种方式:

  1. 去官网,检查 Xcode 的 Release Notes,在 Overview 中会有介绍。例如:Xcode 14.3 Release Notes

  2. 终端运行指令检查 xcrun swift -version

    本地环境输出如下:

    swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100)
    Target: arm64-apple-macosx13.0
    

咱们在刚才新建的目录中履行如下指令拉取对应的 Swift 源码,并 cd 到源码目录:

$ git clone --branch swift-5.8-RELEASE git@github.com:apple/swift.git
$ cd swift

拉取源码后还须拉取依靠

$ utils/update-checkout --tag swift-5.8-RELEASE --clone

顺便说一句,上述操作最好全程挂代理。

编译

全部预备完毕后咱们将开端第一步编译,这里咱们需求用到官方的脚本,在 utils 目录下的 build-script 脚本,以下是自己所运用的指令。

$ utils/build-script \
--release-debuginfo --debug-swift-stdlib \
--xcode --skip-ios --skip-watchos --skip-tvos \
--skip-early-swiftsyntax --swift-darwin-supported-archs="$(uname -m)"

编译指令的参数最好做一些简单了解,不要盲目复制粘贴,这里只展现苹果 M 系列芯片的 arm64 架构编译指令,假如你是 Intel 环境请自行查阅官方文档。或履行 utils/build-script --help 指令查阅。

咱们来简单的介绍一下这里众多的参数:

  • --release-debuginfo 编译出带有 RelWithDebInfo 环境变量的工程,类似于 DebugRelease 模式,RelWithDebInfo 会优化一部分,但一起保存调试信息。

  • --debug-swift-stdlib 编译带有调试信息的 Swift规范库,假如想调试 Swift编译器,能够运用 --debug-swift

  • --xcode 运用 CMake 的 Xcode 生成器,编译完结后会生成一个 Swift.xcodeproj 工程。

  • --skip-ios --skip-watchos --skip-tvos 越过相应渠道,这里只编译 macOS 渠道。

  • --swift-darwin-supported-archs="$(uname -m)" 编译相关架构,$(uname -m) 指令用于获取机器架构环境,例如本机获取的结果为 arm64

--skip-early-swiftsyntax 这个指令咱们留到后面过错修正的时分再说,这里先留个悬念。

接下来咱们回车履行指令,这里需求等待一段时刻,编译时刻长短与机器功能有关。编译结束之后,咱们会在目录 ~/Documents/swift-project 下得到一个 build 文件夹,里边便是咱们 build 的产品。

Xcode-RelWithDebInfoAssert+stdlib-DebugAssert。目录结构如下图:

编译 Swift 5.8 源码

至此第一阶段编译完结,离成功又近了一步,接下来咱们进入 Xcode 编译阶段。

源码调试

进入目录 swift-macosx-arm64 双击翻开 Xcode 工程,此刻会有主动创立 schemes 的提示,如下图,咱们挑选主动创立。

编译 Swift 5.8 源码

创立自定义 target 用于调试

Swift.xcodeproj 工程里边,咱们点击 TARGETS 下面的 + 新建一个调试的 target,咱们挑选 macOS 的指令行模式。如下图:

编译 Swift 5.8 源码

Product Name 取个自定义名字就行。接下来为咱们的 target 引进依靠,如下图:

编译 Swift 5.8 源码

接下来咱们需求在设置中封闭 Hardened Runtime 选项,如下图:

编译 Swift 5.8 源码

假如想了解更多关于 Hardened Runtime 的介绍,请检查官方文档:Hardened Runtime。

咱们还须将 target schemeBuild Configuration 修改为 ReWithDebInfo

编译 Swift 5.8 源码

最后咱们在自定义 target 文件夹下的 main.swift 文件中添加相应的代码,并在 HeapObject.cpp 中设置断点就能够开端愉快的调试了。如下图:

编译 Swift 5.8 源码

问题解决

在编译源码的过程中,自己遇到了几个问题,列在这里用以记载,也方便别人。

履行脚本阶段,最开端我履行的脚本并没有添加 --skip-early-swiftsyntax 这两个参数,脚本履行不通过,报错如下:

CMake Error in lib/ASTGen/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

CMake Error in lib/ASTGen/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

CMake Error in lib/ASTGen/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

CMake Error in lib/ASTGen/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

CMake Error in lib/Parse/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

CMake Error in lib/Parse/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

CMake Error in lib/Parse/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

CMake Error in lib/Parse/CMakeLists.txt: Imported target “SwiftSyntax::SwiftBasicFormat” includes non-existent path

"/Users/jiafengwu/Documents/github/buildSwiftSource/build/Xcode-RelWithDebInfoAssert+stdlib-DebugAssert/earlyswiftsyntax-macosx-arm64/lib/swift/host"

in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:

  • The path was deleted, renamed, or moved to another location.

  • An install or uninstall procedure did not complete successfully.

  • The installation package was faulty and references files it does not provide.

从上面的报错可看出,犯错的原因是在编译 earlyswiftsyntax 的时分。要修正此问题,咱们只需添加参数 --skip-early-swiftsyntax 即可,让其在履行编译指令的时分越过 earlyswiftsyntax 的构建。由于这并不影响咱们最终的源码调试。

Xcode 编译阶段,第一次履行编译的时分呈现了如下的过错:

编译 Swift 5.8 源码

这是由于在履行 utils/build-script --xcode 的时分 cxxshim 试图创立模块目录导致。咱们只需求将 swift/stdlib/public/Cxx/cxxshim/CMakeLists.txt 此文件中的如下指令删去即可:

list(APPEND outputs ${module_dir})
if(SWIFT_BUILD_STATIC_STDLIB)
  list(APPEND outputs ${module_dir_static})
endif()

然后清空 build 目录,重新履行 utils/build-script 进行构建即可。

接下来全部完结后,继续 Xcode 编译又会呈现如下过错:

编译 Swift 5.8 源码

看报错是 llvm-macosx-arm64 中的 Debug 目录下没有相应的文件。首要咱们检查 swift-compatibility-symbols 这个 target 将其 Build Configuration 修改为 ReWithDebInfo 。然后咱们在履行编译即可。

参考文档

  • How to Set Up an Edit-Build-Test-Debug Loop
  • Bootstrapping broken for Ninja builds on Apple silicon Macs (arm64)
  • Problems with build-script building compiler with –xcode
  • Fix multiple commands produce ${SWIFTLIB_DIR}/${arch_subdir}
  • CMake error when running build-script with --xcode
  • Swift源码编译调试(M1/Xcode)
  • 超实用~运用Xcode编译Swift源码