今天來介紹一個小工具ccache
,其可以提高xcode
的編譯速度。說起緣由,是因為我的蘋果電腦配置比較低,而每次開發調試或測試打包都需要編譯工程,雖然項目工程代碼量不算大,但是編譯的時間還是很長,尤其是修改了頭文件或者Archive
打包時,看着進度條像蝸牛在爬一樣,心里都有小動物在奔騰......
好在遇到了ccache
,其原理是通過把項目的源文件用ccache
編譯器編譯,然后緩存編譯生成的信息,從而在下一次編譯時,利用這個緩存加快編譯的速度,目前支持的語言有:C
、C++
、Objective-C
、Objective-C++
,但是如果找不到ccache
編譯器,那么還是會選擇clang
編譯器來編譯源文件。下面介紹一下具體的應用過程:
添加ccache腳本
下面是ccache
的編譯腳本,命名為:ccache-clang
,需要添加到工程根目錄,ccache
就是通過這個腳本來選擇編譯器的,該腳本的詳細介紹如下:
第1行:指定這是一個bash
腳本
第2行:type -p ccache
判斷是否存在ccache
命令,/dev/null
是空設備文件,2>&1
是把標准錯誤流重定向到標准輸出流,所以整行的作用是先判斷命令是否存在,如果不存在就把標准錯誤流重定向成標准輸出流后,再重定向到空文件,這樣錯誤就不會在控制台上打印出來了
第3行:設置最大的緩存
第4行:設置源文件的編譯模式,默認是true
,ccache
會先處理源文件,如果緩存沒有命中,就編譯源文件;而如果是false
,就會在緩存沒有命中時,不是直接編譯源文件,而是編譯處理后的文件,但是這可能會有問題,因為不同的編譯器,預處理后的文件內容不完全相同
第5行:設置為true
,表明ccache
直接利用緩存目錄下的文件,而不是拷貝后的文件,這樣可以加快編譯速度,默認是false
第6行:設置提高緩存命中率,忽略__FILE__、DATE、__TIME__等宏,也不檢查文件的修改和創建時間是否是最新的等等
第9行:指定日志文件的路徑
第10行:執行/usr/bin/clang
命令,"$@"
是指所有參數
第12行:執行系統默認的clang
命令,"$@"
是指所有參數
#!/bin/sh
if type -p ccache >/dev/null 2>&1; then
export CCACHE_MAXSIZE=10G
export CCACHE_CPP2=true
export CCACHE_HARDLINK=true
export CCACHE_SLOPPINESS=file_macro,time_macros,include_file_mtime,include_file_ctime,file_stat_matches
# 指定日志文件路徑到桌面,等下排查集成問題有用,集成成功后刪除,否則很占磁盤空間
export CCACHE_LOGFILE='~/Desktop/CCache.log'
exec ccache /usr/bin/clang "$@"
else
exec clang "$@"
fi
如果你的代碼或者三方庫里的代碼中有C++
文件,則需要把腳本命名為:ccache-clang++
,同時,腳本中的clang
也需要修改為clang++
,如下:
#!/bin/sh
if type -p ccache >/dev/null 2>&1; then
export CCACHE_MAXSIZE=10G
export CCACHE_CPP2=true
export CCACHE_HARDLINK=true
export CCACHE_SLOPPINESS=file_macro,time_macros,include_file_mtime,include_file_ctime,file_stat_matches
# 指定日志文件路徑到桌面,等下排查集成問題有用,集成成功后刪除,否則很占磁盤空間
export CCACHE_LOGFILE='~/Desktop/CCache.log'
exec ccache /usr/bin/clang++ "$@"
else
exec clang++ "$@"
fi
配置Xcode項目
1.添加一個CC常量
在項目的Build Settings
里,添加一個常量:CC
,值為腳本的完整路徑:$(SRCROOT)/ccache-clang
(腳本在根目錄下)
添加CC
常量
因為ccache
不支持Clang Modules
,所以需要關閉項目的Modules
選項,如果你的工程里有用的@import UIKit
等,那么現在需要替換為#import <UIKit/UIKit>
,這是因為關閉Moduels
后,Xcode
不會再自動導入模塊了,對於其他的模塊,你還需要在Linked Frameworks and Libraries
里手動導入所需模塊。
配置Pod項目
如果項目中用到了CocoaPods
,還需要設置Pod
工程,因為Pod
工程也需要關閉Modules
選項,我們可以按照修改Xcode
項目的方法來修改Pod
工程的modules
配置,但是每次pod update
會把Pod
工程重新生成,Modules
選項又被改回去了,所以我們直接在Podfile
里加入下面的代碼,讓Pod
工程在生成的時候就關閉Modules
選項,同時加入CC
常量,就可以在編譯時用緩存加速了。
但是,由於我們關閉了modules
選項,如果某個Pod
工程用到了系統的框架,則需要按照Xcode
工程的方法添加到對應的Pod
工程里,否則會提示Undefined symbols xxx for architecture arm7
等等,盡管每次更新Pod
后,都需要重新添加所需的框架,但是考慮到編譯速度的提升,而Pod
不會經常更新,所以也不是很麻煩。
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
target.build_configurations.each do |config|
#關閉 Enable Modules
config.build_settings['CLANG_ENABLE_MODULES'] = 'NO'
# 在生成的 Pods 項目文件中加入 CC 參數,路徑的值根據你自己的項目來修改
config.build_settings['CC'] = '$(PODS_ROOT)/ccache-clang'
end
end
end
應用ccache
設置完成后,就可以利用ccache
了,首次因為還沒有緩存,要添加緩存,所以編譯的時間會比沒有用ccache
要多一會兒,但是從第二次之后,會有緩存命中,就可以加快編譯速度了,多次之后,可以明顯感覺到,編譯的速度快了許多,一般至少了加快一倍以上,我們也可以用命令來查看ccache -s
的緩存的命中情況:
可以看到,現在的緩存命中率是53.01%
,以前打包需要10分鍾,現在3分鍾搞定,喝茶的時間又多了,是不是很開森,^_^。