前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Swift 入门:编译 Swift 源码(2)

Swift 入门:编译 Swift 源码(2)

原创
作者头像
酷酷的哀殿
修改2020-11-18 14:31:12
1.9K0
修改2020-11-18 14:31:12
举报
文章被收录于专栏:酷酷的哀殿

我们曾经在上一篇文章中 https://cloud.tencent.com/developer/article/1744552 提到 Swift 及相关组件的编译会耗费大量的磁盘空间。

本文希望能够进一步分享降低磁盘空间的一些技巧。

Tip1:压缩源码仓库

git 仓库的压缩方案比较简单,只需要通过 git gc 命令进行压缩即可。

git gc 文档:https://git-scm.com/docs/git-gc

压缩前

在 Swift 及相关组件中,只有 swift 和 llvm-project 两个仓库笔记体积较大,所以我们以这两个仓库为例进行讲解。

在笔者的电脑上,两个仓库的体积合计 9G 左右:

image.png
image.png

压缩后

压缩后体积在 4G 左右:

image.png
image.png

Tip2、编译中间文件

通常情况下,编译中间文件 会占用20G以上的空间。

scheme-clang 为例,如果读者按照上一篇文章提供的脚本进行编译,就会发现下面的目录包含21个中间文件。

scheme 定义: https://help.apple.com/xcode/mac/11.4/#/dev6fd4476d7

代码语言:txt
复制
➜  RelWithDebInfo git:(master) ✗ pwd
~/swift-source/build/Xcode-1107/llvm-macosx-x86_64/tools/clang/tools/driver/LLVM.build/RelWithDebInfo
➜  RelWithDebInfo git:(master) ✗ tree
.
└── clang.build
    ├── Objects-normal
    │   └── x86_64
    │       ├── cc1_main.d
    │       ├── cc1_main.dia
    │       ├── cc1_main.o
    │       ├── cc1as_main.d
    │       ├── cc1as_main.dia
    │       ├── cc1as_main.o
    │       ├── cc1gen_reproducer_main.d
    │       ├── cc1gen_reproducer_main.dia
    │       ├── cc1gen_reproducer_main.o
    │       ├── clang.LinkFileList
    │       ├── clang_dependency_info.dat
    │       ├── driver.d
    │       ├── driver.dia
    │       ├── driver.o
    │       ├── dummy.d
    │       ├── dummy.dia
    │       └── dummy.o
    ├── Script-FEC9C3C23E8E4148A8447162.sh
    ├── clang.xcent
    ├── dgph
    └── dgph~

3 directories, 21 files

上面的21个文件,是通过 cmake 生成 clang 可执行文件时产生的。

当我们开始使用 Xcode 进行编译或者调试时,这些文件都可以被删除。

批量清理方案

考虑到 Swift LLVM lldb 3个工程加起来有几百个临时文件夹,一个个手动删除的效率较低。所以,我们我们可以通过一下脚本进行批量清理。

代码语言:txt
复制
cd ~/swift-source/build/Xcode-1107
find . -name LLVM.build | xargs rm -rf
find . -name swift.build | xargs rm -rf
find . -name lldb.build | xargs rm -rf

Tip3、构建依赖

构建依赖是指:编译A项目时,必须先编译BC项目才能进行。

此时,A 项目的构建依赖就是 BC

构建依赖分两种:显示依赖 & 隐式依赖

显示依赖

显示依赖可以通过 build phasesDependencies 查看。

liblldb 为例,它共计包含 73显示依赖。每个 显示依赖 又包含多个的构建依赖,最后,liblldb 共计包含400构建依赖

image.png
image.png

参考文章: What are build phases?

隐私依赖

隐式依赖 是指没有通过 显示依赖 指明,但是又确实存在的依赖项。

target PetKit 的构建产物是 PetKit.framework

如果 target host 存在下面的配置:

image.png
image.png

则,target host隐式依赖 target PetKit

优化方案

因为每个target都会产出多个中间文件,为了避免产生这些中间文件,以及加快编译速度。

我们可以只保留强依赖target

如下所示,笔者整理一份缩减版的 lldb构建依赖图

弱依赖
弱依赖

但是,大部分情况下,这些依赖都属于弱依赖

如果读者熟悉 预处理-编译-链接 三步曲很熟悉,我们很容易发现,上面的依赖并不是必须的。

我们真正依赖的是每个target的构建产物。

所以,我们将上图重新整理成下图所示的 强构建依赖图

强依赖项
强依赖项

我们下面以一个具体的场景进行说明什么是强依赖target

  • 假设,我们需要在 CommandInterpreter.cpp 文件的 CommandInterpreter::HandleCommand 函数内增删代码。
  • 此时, liblldbInterpreter.a 需要被重新编译,target lldbInterpreter 就是lldb强依赖项
  • 因为 LLDB.framework 强依赖 liblldbInterpreter.a,所以,liblldb 同样是lldb强依赖项

如下所示,我们可以只保留两个强依赖项,移除其它的弱依赖项

image.png
image.png
image.png
image.png

经过一番操作后,Xcode 就可以从原来的几十G中间文件,变为只需要几十M中间文件。

总结

本文通过讲解 Swift 及 Xcode 依赖关系,提供了多个有效降低磁盘空间占用的方案。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Tip1:压缩源码仓库
    • 压缩前
      • 压缩后
      • Tip2、编译中间文件
        • 批量清理方案
        • Tip3、构建依赖
          • 显示依赖
            • 隐私依赖
              • 优化方案
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档