本教程希望能提供一份面向新人编译 Swift 源码及相关组件的教程。
什么是 Swift
Swift 是一门快速、高效、安全的编译型语言。
它具有很多高级简洁的特性:
- 泛型强大且易用
- 协议扩展使得泛型代码编写变得更为容易
- 头等函数和轻量级闭包语法
- 对范围或集合进行快速、简洁的迭代
- 元组和多值返回
- 支持方法、扩展和协议的结构
- 枚举能执行有效负载并支持模式匹配
- 函数式编程模式,例如映射和过滤
- 使用 try/catch/throw 处理原生错误
编程语言的很多特性都是依赖于编译器的。比如,与 C 语言的枚举相比,Swift 的枚举就依赖编译器实现了关联值等高级特性。
为了方便了解高级特性的实现原理,掌握 Swift 及相关库的源码编译是开发者必须掌握的技能。
目标
以 Swift 官方入门文档 为基础,增加 Xcode 对 Swift、LLVM、lldb 进行编译调试的内容。
环境
本文写作时间是 2020年11月07日。
随着 Swift 的持续迭代,环境依赖可能会随时更新。请参考官方入门文档的变更进行编译。
根据 https://ci.swift.org/ 网站的提示:
当前官方推荐使用的正常编译的环境是:
- Host OS: 10.15.6
- Xcode: 12.2 Beta 3 (12B5035g)
安装依赖包
安装 Xcode 和 HomeBrew
安装 Brew
代码语言:txt复制如果安装 brew 时,存在网络问题,请使用手机热点或者参考以下方案进行解决
# 首次安装 Homebrew
# 下载 https://github.com/Homebrew/install/blob/master/install.sh 并编辑其中的:
BREW_REPO="https://github.com/Homebrew/brew"
# 变成:
BREW_REPO="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"
# 接着,运行 install.sh 以安装 Homebrew:
HOMEBREW_CORE_GIT_REMOTE=https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git bash install.sh
#替换现有上游
# brew 程序本身
git -C "$(brew --repo)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git
# 以下针对 mac OS 系统上的 Homebrew
git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git
git -C "$(brew --repo homebrew/cask)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git
git -C "$(brew --repo homebrew/cask-fonts)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask-fonts.git
git -C "$(brew --repo homebrew/cask-drivers)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask-drivers.git
# 以下针对 Linux 系统上的 Linuxbrew
git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/linuxbrew-core.git
# 更换后测试工作是否正常
brew update
安装 CMake Ninja Sccache
推荐使用 Brew 工具安装:
代码语言:txt复制brew install cmake ninja sccache
验证是否安装成功
代码语言:txt复制# 3.18.1 或者更高版本
cmake --version
python3 --version
ninja --version
sccache --version
克隆代码
1、准备项目目录
代码语言:txt复制mkdir -p ~/swift-source/swift
~/swift-source/swift 包含 Swift 主仓库的源码
2、克隆 Swift 源码
代码语言:txt复制cd ~/swift-source/swift
git clone https://github.com/apple/swift.git .
3、克隆依赖仓库的源码
代码语言:txt复制cd ~/swift-source/swift
utils/update-checkout --clone
> 执行该命令后,~/swift-source 会包含多个子文件夹:llvm-project 等等。
编译
请读者根据需要自行选择需要的脚本。
> 定制版本支持 Xcode 直接调试 lldb ,并且占用的磁盘空间会更低
> 通常情况下,Swift 全量编译需要 40G-60G 的磁盘空间才能完成。
> 对 Xcode 构建原理熟悉的同学,可以定制编译脚本,并将空间占用压缩到 20G 以内
官方版本
编译 llvm 和 Swift
代码语言:txt复制cd ~/swift-source/swift
utils/build-script --skip-build-benchmarks
--skip-ios --skip-watchos --skip-tvos --swift-darwin-supported-archs "x86_64"
--sccache --release-debuginfo --test
--xcode
编译 lldb
代码语言:txt复制根据 Swift 官方文档,lldb 必须使用 ninja 编译
cd ~/swift-source/swift
utils/build-script --skip-build-benchmarks
--skip-ios --skip-watchos --skip-tvos --swift-darwin-supported-archs "x86_64"
--sccache --release-debuginfo --test
--xcode
定制版本
代码语言:txt复制set -ex
## 注意1:本脚本的编译产物路径是 ~/swift-source/build/Xcode-1107,读者可以根据需要进行变更
## 注意2:如果希望全量编译,可以手动移除 -S 参数
## 注意3: 如果不需要编译lldb,可以手动移除 extra-cmake-options 参数
./utils/build-script -x -S
--build-subdir Xcode-1107
--sccache
--release-debuginfo
--extra-cmake-options="
-DLLDB_ENABLE:BOOL=TRUE,
-DLLDB_BUILD_DIR:STRING=~/swift-source/build/Xcode-1107/lldb-macosx-x86_64
"
ln -s -f ~/swift-source/build/Xcode-1107/llvm-macosx-x86_64/Debug/lib/clang/10.0.0/include
~/swift-source/build/Xcode-1107/llvm-macosx-x86_64/lib/clang/10.0.0/include
/usr/local/bin/cmake --build ~/swift-source/build/Xcode-1107/llvm-macosx-x86_64 --target ZERO_CHECK --config RelWithDebInfo
## 准备 clang 头文件
/usr/local/bin/cmake
--build ~/swift-source/build/Xcode-1107/llvm-macosx-x86_64 --target clang-resource-headers --config RelWithDebInfo
## 注意4:可以根据需要只编译部分 target
/usr/local/bin/cmake --build ~/swift-source/build/Xcode-1107/llvm-macosx-x86_64 --target ZERO_CHECK --config RelWithDebInfo
-- -parallelizeTargets -jobs 12 -target ALL_BUILD
## 编译 clang 和 lldb 依赖的目标
/usr/local/bin/cmake --build ~/swift-source/build/Xcode-1107/llvm-macosx-x86_64 --target clang --config RelWithDebInfo
## 编译 swiftFrontend 和 lldb 依赖的目标
/usr/local/bin/cmake
--build ~/swift-source/build/Xcode-1107/swift-macosx-x86_64
--target swiftFrontend
--target swiftASTSectionImporter
--target swiftReflection
--target swiftRemoteAST
--config RelWithDebInfo
## 如果遇到无法解决的问题,可以根据需要删除 lldb 目录
# rm -rf ~/swift-source/build/Xcode-1107/lldb-macosx-x86_64/
mkdir -p ~/swift-source/build/Xcode-1107/lldb-macosx-x86_64
mkdir -p ~/swift-source/build/Xcode-1107/lldb-macosx-x86_64/.cmake/api/v1/query
touch ~/swift-source/build/Xcode-1107/lldb-macosx-x86_64/.cmake/api/v1/query/codemodel-v2
~/swift-source/build/Xcode-1107/lldb-macosx-x86_64/.cmake/api/v1/query/cache-v2
pushd ~/swift-source/build/Xcode-1107/lldb-macosx-x86_64
## 生成 lldb.xcodeproj 工程
env /usr/local/bin/cmake -G Xcode
-DCMAKE_C_COMPILER_LAUNCHER:PATH=/usr/local/bin/sccache
-DCMAKE_CXX_COMPILER_LAUNCHER:PATH=/usr/local/bin/sccache
-DCMAKE_C_COMPILER:PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
-DCMAKE_CXX_COMPILER:PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
-DCMAKE_LIBTOOL:PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool
-DLLVM_VERSION_MAJOR:STRING=10
-DLLVM_VERSION_MINOR:STRING=0
-DLLVM_VERSION_PATCH:STRING=0
-DCMAKE_OSX_SYSROOT:PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
-DCMAKE_OSX_ARCHITECTURES=x86_64
-DLLVM_HOST_TRIPLE:STRING=x86_64-apple-macosx10.9
-C~/swift-source/llvm-project/lldb/cmake/caches/Apple-lldb-Xcode.cmake
'-DCMAKE_C_FLAGS= -Wno-unknown-warning-option -Werror=unguarded-availability-new -arch x86_64 -fno-stack-protector -g'
'-DCMAKE_CXX_FLAGS= -Wno-unknown-warning-option -Werror=unguarded-availability-new -arch x86_64 -fno-stack-protector -g'
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DLLDB_SWIFTC:PATH=~/swift-source/build/Xcode-1107/swift-macosx-x86_64/bin/swiftc
-DLLDB_SWIFT_LIBS:PATH=~/swift-source/build/Xcode-1107/swift-macosx-x86_64/lib/swift
-DCMAKE_INSTALL_PREFIX:PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/
-DLLDB_FRAMEWORK_INSTALL_DIR=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/../System/Library/PrivateFrameworks
-DLLVM_DIR:PATH=~/swift-source/build/Xcode-1107/llvm-macosx-x86_64/lib/cmake/llvm
-DClang_DIR:PATH=~/swift-source/build/Xcode-1107/llvm-macosx-x86_64/lib/cmake/clang
-DSwift_DIR:PATH=~/swift-source/build/Xcode-1107/swift-macosx-x86_64/lib/cmake/swift
-DLLDB_ENABLE_CURSES=ON
-DLLDB_ENABLE_LIBEDIT=ON
-DLLDB_ENABLE_PYTHON=ON
-DLLDB_ENABLE_LZMA=OFF
-DLLDB_ENABLE_LUA=OFF
-DLLDB_INCLUDE_TESTS:BOOL=TRUE
'-DLLDB_TEST_USER_ARGS=--build-dir;~/swift-source/build/Xcode-1107/lldb-macosx-x86_64/lldb-test-build.noindex;--skip-category=watchpoint'
'-DCMAKE_IGNORE_PATH=/usr/lib;/usr/local/lib;/lib'
-DPKG_CONFIG_EXECUTABLE=/usr/bin/false
~/swift-source/llvm-project/lldb
popd
## lldb 依赖这个路径
mkdir -p ~/swift-source/build/Xcode-1107/swift-macosx-x86_64/lib/swift
## 编译 lldb 目标
/usr/local/bin/cmake
--build ~/swift-source/build/Xcode-1107/lldb-macosx-x86_64
--target lldb
--config RelWithDebInfo
##参考链接
- https://www.cnswift.org/about-swift
- .Swift 枚举
- .homebrew 清华镜像帮助文档