ccache的主頁:http://ccache.samba.org
distcc的主頁:http://distcc.samba.org
1、背景:
在處理一些規模相對較大的工程時,編譯花費的時間可能會很長。有時候我們會經常一遍一遍地編譯相同的程序,此時,有了ccache情況就好多了。它將在第一遍編譯時多花幾秒鍾,但接下來就會使編譯成倍(5-10倍)的提速。
ccache 的基本原理是通過將頭文件高速緩存到源文件之中而改進了構建性能,因而通過減少每一步編譯時添加頭文件所需要的時間而提高了構建速度。以下來了解下如何同時使用 ccache 和distcc 來使開發環境達到最佳性能。
2、引入ccache:
在標准的編譯過程中,在 UNIX 下使用 C/C++ 開發應用程序通常需要用到一個編譯器(如 gcc)以及一個編譯工具(如 make)。make 和所有的 C 編譯器的問題在於 C 預處理程序(preprocessor)和頭文件的工作方式。觀察一個典型的 C 源文件,您會發現其中有很多由 #include 所引用的各種頭文件。每一次編譯一個文件時,C 預處理程序(cpp)都會解析並引入每個頭文件以及這些頭文件引用到的任何文件。通過對內容進行解析,cpp 可以將一個相當基本的 1-KB 大小的源文件轉化為一個 8-KB 大小的源文件,在這個過程中,會合並入幾十個甚至幾百個頭文件。在典型的開發項目中,有很多與項目相關的頭文件可能會在不同的源文件中多次被引入,而且每個頭文件本身也可能引用很多其他頭文件。這就是我們使用了N年的C編譯器的基本編譯理念,從C出現到如今,它帶給人們無數編譯成果的同時,也逐漸暴露出自身固有的缺憾。
在典型的編譯過程中,make 工具只編譯自上次編譯后發生修改的文件,這樣就在很大程度上簡化了編譯過程。make 將必須被編譯的文件限制在經過修改的那些源文件范圍之內,但是即使是使用 make,仍然有相當的浪費。每一次編譯項目時,源文件在編譯為匯編語言和最終的機器代碼之前,都要通過 cpp 進行解析。對每一個文件來說,每一次可能都要重新解析頭文件,由此上面提到的問題再次出現。從編譯的全過程來看,您最后可能多次解析了相同的頭文件,浪費了處理器周期,更浪費了開發時間。
3、 ccache基本原理:
ccache(“compiler cache”的縮寫)也是一個編譯器驅動器。第一趟編譯時ccache緩存了GCC的“-E”輸出、編譯選項以及.o文件到$HOME/.ccache。第二次編譯時盡量利用緩存,必要時更新緩存。所以即使"make clean; make"也能從中獲得好處。ccache是經過仔細編寫的,確保了與直接使用GCC獲得完全相同的輸出。
ccache工具會高速緩存編譯生成的信息,並在編譯的特定部分使用高速緩存的信息,比如頭文件,這樣就節省了通常使用 cpp 解析這些信息所需要的時間。舉例編譯Example,假定 foobar.h 中包含對其他頭文件的引用,ccache 會用那個文件的 cpp-parsed 版本(已編譯過並被ccache緩存在cache中的備份)來取代 include 聲明,而不是真正去讀取、理解並解釋其內容,ccache 只是將緩存在高速緩存中最終的文本拷貝到文件中,使得它可以立即被編譯。
Example:
#include
"foobar.h"
void
main(void)
{
}
4、安裝
安裝和使用 ccache很簡單。首先說明一點,ccache它不會取代或者以任何方式影響您原來的使用編譯器的方式,而是擔當了您與您的編譯器之間的一個接口,所以您可以根據需要選擇是否使用它。要安裝 ccache,需要從 Samba 小組或者一個本地鏡像直接下載源文件。解壓出文件的內容:
1)、單機安裝方法:
首先解壓:
$ bunzip2 -c ccache-2.3.tar.bz2|tar xf -
切換到那個目錄:
$ cd ccache-3.18
配置:
$ ./configure
編譯:
$ make
最后,安裝 ccache:
$ make install
2)、若情況為多人共用服務器,自己只是服務器的一個普通用戶,除非你擁有root權限,或者root允許使用sudo,否則要安裝到用戶目錄下,這時步驟如下:
$ cd ccache-3.18
配置:
$ ./configure –prefix=~/My_Software/ccache/
【若提示configure: error: expected an absolute directory name for --prefix: ~/My_Software/ccache,則需要指定絕對路徑,即改成/home/用戶名/My_Software/ccache/】
編譯:
$ make
最后,安裝 ccache:
$ make install
3)、也可以使用Linux的yum安裝:
A、切換到root用戶安裝ccache
yum install ccache
B、查看已安裝的rpm -qa | grep ccache
ccache-2.4-1.2.el4.rf
C、rpm -ql ccache
至此,安裝完成,接下來就准備好開始使用了!
5、使用ccache:
前面提到,ccache 是充當您與您的普通編譯器之間一個借口來優化編譯的。有兩種方式使用ccache:
1)、選擇性使用ccache:
使用"ccache gcc"或"ccache g++"代替"gcc"或"g++" ,以 gcc 為第一個參數調用 ccache,而不是調用 gcc。例如,要在命令行中編譯一個文件,您通常會使用:
$ gcc foo.c
要使用 ccache,您應該輸入:
$ ccache gcc foo.c
像這樣對一個文件進行單獨的編譯,尤其是第一次使用 ccache 編譯那個文件時,您將不會看到有任何的幫助,因為編譯信息還沒有被高速緩存。
2)、ccache加入環境變量,取代C編譯器:
設置 CC 環境變量的值,配置makepkg,進入到你的/etc/makepkg.conf中加入下面幾行:
export CC="ccache gcc"
export CPP="ccache cpp"
export CXX="ccache g++"
或者直接在命令行輸入:
$ export set CC='ccache gcc'
makepkg.conf里還有不少東西可以修改,詳情參見原文:
http://wiki.archlinux.org/index.php/Makepkg.conf
3)、配置 ccache 永久地取代主要編譯器:
vi ~/.bash_profile
把/usr/lib/ccache/bin路徑加到PATH下
PATH=/usr/lib/ccache/bin:$PATH
這只是對ccache所自帶的gcc起作用,有時候我們需要使用交叉編譯工具,這時,僅僅通過以上操作是無法執行ccache編譯的,通常會提示xxx路徑沒有這個編譯工具,這時需要這樣做:
A、$ which ccache
查看安裝路徑, /home/用戶名/ccache
B、$ mkdir ~/.bin
C、$ cd ~/.bin/
$ ln -s /usr/bin/ccache gcc
$ ln -s /usr/bin/ccache g++
$ ln -s /usr/bin/ccache arm-linux-gcc
$ ln -s /usr/bin/ccache arm-linux-g++
同理,其他編譯工具類似方式指定。
D、PATH設置,將~/.bin/放在 arm-linux-gcc等的PATH的前面。
如:原:PATH=$PATH:$HOME/bin
現:PATH=/home/用戶名/.bin:$PATH:/home/用戶名/ccache/bin
然后重啟即可
E、$ which arm-linux-gcc
/home/<user>/.bin/arm-linux-gcc 確認
這樣每次啟動g++的時候都會啟動/usr/lib/ccache/bin/g++,而不會啟動/usr/bin/g++,效果跟使用命令行ccache g++效果一樣。每次用戶登錄時,使用g++編譯器時會自動啟動ccache。
如果您只是想為一個項目啟用 ccache,比如說編譯 Perl 等第三方工具時,那么您或者可以使用第二種方式,或者可以告知配置腳本或 make 命令使用哪個 C 編譯器。
6、控制高速緩存
默認情況下,ccache 使用當前用戶主目錄中的一個目錄($HOME/.ccache)來保持高速緩存信息。在團隊環境中,您應該使用一個集中的位置來進行高速緩存,這樣在編譯過程中每個人都可以使用高速緩存的信息。另一個環境變量 CCACHE_DIR 指定了高速緩存目錄的位置。在單機環境中,將這個環境變量設置為一個每一個需要它的人都可以訪問的目錄。使用通過 tmpfs 掛載的目錄可以獲得更高的速度,前提是您得有支持這一功能的存儲器。您的速度可能會再提高 10% 到 25%。
如果您是在網絡中多台機器上使用 ccache(分布式編譯),那么要確保您共享的目錄要通過 NFS 導出(export)並掛載到每一個客戶機上。如果您希望獲得額外的加速,同樣可以使用 tmpfs 文件系統。
另外的一些選項讓您可以更深入地控制高速緩存設置:
CCACHE_LOGFILE :定義了使用高速緩存時生成的日志文件所處的位置。
在 ccache 中使用 -s 命令行選項來獲得關於高速緩存性能的統計數據。
使用 -M 命令行選項來設置高速緩存的最大大小。默認是 1GB。高速緩存的設置會寫入到高速緩存目錄,所以您可以讓不同的用戶和組在不同的位置擁有不同大小的高速緩存。
-F 選項設置高速緩存目錄的最大文件數目,按 16 進制舍入。和 -M 相同,只是當您希望改變配置的時候才需要使用它。
-c 選項清空緩存。您通常不需要使用這個選項,因為 ccache 在執行過程中會更新信息,但是,如果您要重用一個沒有為某個文件所使用的高速緩存目錄,那么就應該嘗試使用這個選項。
-C 選項完全清空高速緩存。
一旦設置了初始化選項並配置了期望的目錄和高速緩存大小,就不需要再做任何改動。沒有必要執行任何日常的維護。
7、組合 ccache 和 distcc
您可能已經想到了 distcc 這一來自 Samba 小組的另一個工具,它讓您可以將編譯過程分布到多台機器上。只需要為 make 添加多任務選項(使用 -j 命令行選項),它就可以有效地提高同步編譯的數目。distcc 系統的工作方式是,每台主機上有一個后台進程,接收最終預解析格式的源文件,然后在本地進行編譯,返回生成的對象文件。
如果使用得當,在每加入一個新的同樣節點時,編譯時間通常應該會以稍微低於線性的比率下降,不過您將只會在那些遠不只一個源文件的項目上看到這樣的影響,因為 distcc 只是分布全部源文件。
由於 distcc 所分布的是解析過的文件,所以您可以組合 ccache,它可以加速 C 預處理過程部分,同時 distcc 可以完成到對象代碼的實際編譯。要以這種方式來使用 distcc 和 ccache,需要在主機上配置 distcc,在主要的開發機器上配置 distcc 和 ccache。
現在在希望要編譯項目的機器上設置環境變量,如下所示。
使用 ccache 和 distcc 所需要的環境變量:
export set DISTCC_HOSTS='localhost atuin nautilus pteppic kernel'
export set CCACHE_DIR=/Data/Cache/CCache
export set CCACHE_PREFIX=distcc
export set CCACHE_LOGFILE=/Data/Cache/CCache.log
export set CC='ccache gcc'
環境變量定義如下:
DISTCC_HOSTS 指定了將工作分布到哪些主機。
CCACHE_DIR 指定了高速緩存目錄的位置。
CCACHE_PREFIX 定義了當 ccache 調用真實的編譯器來編譯源文件(預處理之后)時所使用的前綴。
CC 設置首先使用的 C 編譯器的名稱(ccache)。
現在,當運行 make 時,如果使用了 -j 選項來指定要執行的同步編譯的數目,則首先使用 ccache 解析文件(如果需要,使用高速緩存),然后將其分布到某個 distcc 主機。
盡管 distcc 加速了編譯過程,但是它沒有改變環境的基本限制。例如,您不應該將 make 執行的同步作業的數目設置得大於可用 CPU 數目的兩倍。例如,如果您有四台兩路機器,那么將作業值設置為超過 16 的值時將不再會觀察到有多大改善。
好了,強大的ccache至此已經基本了解了,想要更深入的理解還是在使用實踐中獲得吧。以上這些都是借鑒網上眾前人帖子而總結出的一點經驗,實際操作使用時沒必要這么深入,就當他是一個小工具就可以了,會用即可。貼出來梳理下思路,以便對后來人有些幫助!