编译优化--使用云存储缓存编译结果方案调研

2020/06/10 blog

一、背景需求

由于XX项目编译时间太长(编译一次大概需要70分钟),出现线上问题后,无法迅速排查问题,业务组同学提出了需求,希望将排查问题时,编译时间缩短,经过讨论,就有了以下方案

二、方案

每次发版时,将编译结果保存在文件服务器上。发生线上问题时,拉去对应代码,将derivedata path 指向文件服务器driverdata 路径。利用发版时保存的编译结果,来加快编译速度。这个方案有以下几个问题:

1、DeriveData path指向文件服务器时,必须保证编译通过

2、编译结果复用的问题,否则没有意义

3、编译结果保护的问题

针对以上这几个问题,大概解决思路是,在文件服务器上开启docker ,在docker中开启samba 服务,将samba共享目录挂载到本地,然后将DeriveData path修改为挂载目录,这里可能牵涉到docker 容器内,宿主机器(文件服务器),Xcode客户端主机,三端

三、调研过程

使用docker 提供samba 服务

1、docker 搭建,参考 Docker 教程

2、安装镜像

a. 查找镜像

$ docker search samba
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
dperson/samba                                                                     385                                     [OK]
svendowideit/samba                Sharing a Docker container's volume should b…   55                                      [OK]
nowsci/samba-domain               A well documented and tested Samba Active Di…   24                                      [OK]
servercontainers/samba            samba - complied from official stable releas…   17                                      [OK]
appcontainers/samba               CentOS 6.6 Samba 4 Container - 282.2MB          13                                      [OK]
elswork/samba                     Multi-Arch container of Samba for AMD & ARM …   12                                      
jenserat/samba-publicshare        Simple Docker image for publically sharing a…   12                                      [OK]
joebiellik/samba-server           Simple Samba server running on Alpine Linux …   9                                       [OK]
sonohara/samba4-ad                Samba 4 ActiveDirectory docker                  9                                       [OK]
dreamcat4/samba                                                                   8                                       [OK]
pwntr/samba-alpine                Simple and lightweight Samba docker containe…   6                                       [OK]
gists/samba-server                Samba server based on alpine                    5                                       [OK]
rsippl/samba-ad-dc                Samba 4 Active Directory Domain Controller      4                                       [OK]
timjdfletcher/samba-timemachine   Samba configured to run as a timemachine tar…   4                                       
sixeyed/samba                     Samba server, FROM dperson/samba                3                                       [OK]
andrespp/samba-ldap               Docker image for SAMBA with LDAP authenticat…   3                                       [OK]

采用下载次数最多的镜像dperson/samba

b. 拉取镜像

$docker pull  dperson/samba

c. 在本地创建一个目录,用于与docker 的目录映射

$ mkdir /home/shared
$ chmod 0777 /home/shared  //修改shared权限,不修改的话连接进去会提示没有权限写入数据

d. 启动镜像

$ docker run -it --name haibing_samba_share01 -P \
> -v /home/test01/docker_share01:/test01 \
> -d dperson/samba \
> -u "test01;asdf" \
> -s "haibing_samba_share01;/test01;yes;no;yes;all;none"

7a53eb2cdb431abad1ebd5214f3fabb868ce8c8e1dd40bd33f4a2fa55f19be03

如果出现一串字符,docker 的标识符,表示docker 创建成功 以上参数说明参考 dperson/samba

查看docker 状态

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                        PORTS                                                                                                                                            NAMES
7a53eb2cdb43        dperson/samba       "/sbin/tini -- /usr/…"   About a minute ago   Up About a minute (healthy)   0.0.0.0:32836->131/tcp, 0.0.0.0:32801->137/udp, 0.0.0.0:32800->138/udp, 0.0.0.0:32835->139/tcp, 0.0.0.0:32834->444/tcp, 0.0.0.0:32833->445/tcp   haibing_samba_share01

$ docker inspect 6bf88c1acf30   //查看更加详细的信息

3、将共享目录挂载到xcode 主机

a. 使用图形化

b. 使用如下命令

$ mount_smbfs -f 0777 -d 0777 smb://test01:asdf@10.235.11.29:32843/test01 /Users/haibing6/docker/
$ df
Filesystem                         512-blocks      Used Available Capacity   iused      ifree %iused  Mounted on
/dev/disk1s1                        489620264  21102160  94537688    19%    483956 2447617364    0%   /
devfs                                     382       382         0   100%       662          0  100%   /dev
/dev/disk1s2                        489620264 353626696  94537688    79%   2407025 2445694295    0%   /System/Volumes/Data
/dev/disk1s5                        489620264  18874520  94537688    17%         9 2448101311    0%   /private/var/vm
map -fstab                                  0         0         0   100%         0          0  100%   /System/Volumes/Data/Network/Servers
//jungao@10.235.24.27/share         489620264 286403792 203216472    59%  35800472   25402059   58%   /Volumes/share
//test01@10.235.11.29:32843/test01  959337808 548458560 410879248    58% 274229278  205439624   57%   /Users/haibing6/docker

4、将xcode DeriverData 目录设置为 /Users/haibing6/docker

5、在docker 内将目录权限设置为 0777,liunx 真机设置为 0777,xcode 主机设置为 挂载时将权限设置为 0777,如果使用图形化挂载,无法更改权限

$ ls -l /Users/haibing6/docker/
total 32
drwxrwxr-x  1 haibing6  staff  16384  6 11 20:01 Developer

虽然挂载的时候以0777 的权限挂载,但是在挂载后是0775

a. 直接编译

很快,就报没有权限的问题

b. 将在本机的编译结果拷贝到docker 共享目录中,重新编译,耗时60分钟后,报下面的错误:

error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: /Users/
haibing6/docker/Developer/Xcode/DerivedData/Weibo-aieyofptoenervabpoivclypymrr/Build/Intermediates.noindex/
Pods.build/Debug-iphonesimulator/WBCameraKit.build/Objects-normal/x86_64/CKTimelineVideoCompositionHandler.o is
not an object file (not allowed in a library)
Command Libtool failed with a nonzero exit code

使用linux 真机提供samba 服务

Couldn't create workspace arena folder '/Volumes/test01/Developer/Xcode/DerivedData/Weibo-
aieyofptoenervabpoivclypymrr': Unable to write to info file '<DVTFilePath:0x7fce04f551d0:'/
Volumes/test01/Developer/Xcode/DerivedData/Weibo-aieyofptoenervabpoivclypymrr/info.plist'>'.
error: failed writing unit data: failed to rename '/Volumes/test01/Developer/Xcode/DerivedData/
Weibo-aieyofptoenervabpoivclypymrr/Index/DataStore/v5/UIKit-1V5UHAPTOD24G.pcm-32VHFZ4YQ9L0N-
bc1ed27a' to '/Volumes/test01/Developer/Xcode/DerivedData/Weibo-aieyofptoenervabpoivclypymrr/
Index/DataStore/v5/units/UIKit-1V5UHAPTOD24G.pcm-32VHFZ4YQ9L0N': File exists
1 error generated.
In file included from /Users/haibing6/work/weibomain/WeiboMain2/WeiboMain/Weibo/
StickerExtension/WBStickerBrowserViewController.m:9:
/Users/haibing6/work/weibomain/WeiboMain2/WeiboMain/Weibo/StickerExtension/
WBStickerBrowserViewController.h:9:9: fatal error: could not build module 'UIKit'
#import <UIKit/UIKit.h>
 ~~~~~~~^
2 errors generated.

对于以上错误,将UIKit.framework 添加到 Link Binary With Libraries 中,添加 New Run Script Phase, 内容:

rm -rf /Volumes/test01/Developer/Xcode/DerivedData/Weibo-aieyofptoenervabpoivclypymrr/Ind
ex/DataStore/*

重新编译仍然报failed to rename 这个错误

In short, Cocoapods and New build system don’t work well together.

Conclusion
The new build system from Apple is designed to improve the performance, stability and 
reliability of the Swift build. It will catch the configuration errors early in the application
development. It’s been activated by default in Xcode 10 so sooner or later we have to update 
our build process to adapt to the new build system. 

尝试着将new build system 改为 legacy build system

再次编译,仍然报原来的错误

接着进行一下尝试:

在xcode主机上编译成功后,将DeriveData 拷贝到linux 主机,再次编译,仍然报原来的错误

使用Mac 机器提供samba 服务

Xcode设置 legacy build system ,使用编译缓存,再次编译,成功

耗时3个小时,编译成功(此时电脑已经卡得无法再做任何其他事情)

编译成功后,点击 run 耗时 15 分钟,电脑已卡得动不了,不得不重启

执行 update_pods 重新编译, 耗时 110 分钟

为了弄清楚哪里耗时,使用gnomon 来统计编译耗时:

$ xcodebuild  -project testRuntime.xcodeproj -scheme testRuntime | xcpretty | gnomon
2020-06-16 16:38:15.394 xcodebuild[30609:1580745] [MT] PluginLoading: Required plug-in compatibility UUID C80A9C11-3902-4885-944E-A035869BA910 for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/VVDocumenter-Xcode.xcplugin' not present in DVTPlugInCompatibilityUUIDs
   8.1562s   ▸ Compiling LLDBStatic.m
   0.0020s   ▸ Building library libLLDBStatic.a
   0.0092s   ▸ Copying /Users/haibing6/work/custom/work/testRuntime/LLDBStatic/LLDBStatic.h
   4.2453s   ▸ Compiling AppDelegate.m
   0.0003s   ▸ Compiling main.m
   0.0003s   ▸ Compiling SceneDelegate.m
   0.1031s   ▸ Compiling ViewController.m
   0.1200s   ▸ Linking testRuntime
   1.8706s   ▸ Compiling Main.storyboard
   0.0010s   ▸ Compiling LaunchScreen.storyboard
   0.1525s   ▸ Processing Info.plist
   0.0063s   ▸ Touching testRuntime.app (in target 'testRuntime' from project 'testRuntime')
   0.0139s   ▸ Build Succeeded
   0.0001s   
             
     Total   14.6822s

Search

    Post Directory