關於Ditscc分布式編譯環境的搭建,網上也有不少文章,但是基本上都過時了。所以看了很多文章,走了不少彎路,最後總算梳理清楚了一條正確的環境搭建的步驟,而且可以實現zeroconf。本文不涉及負載平衡的實現。
本文所述環境的搭建是基於Ubuntu 12.04 64bit,android版本是4.1(其他版本估計也一樣)。android編譯環境的搭建就不再贅述了,請參考盡量參考官方文檔https://source.android.com/source/initializing.html
1.Distcc簡介
Distcc 是一個將 C、C++等程式的編譯任務分發到網路中多個主機的程式。 Distcc的工作原理為: GCC 編譯C/C++構建一個execualble分為四個階段: 預先處理:.c 到.i,由cc完成 彙編:.i到.s ,由cc完成 編譯:.s到.o,由as完成 連結:.o 到可執行檔,由collect2完成 其中第三階段是效率瓶頸。distcc是一個編譯器磁碟機。它在”gcc -c”階段把預先處理輸出分發到指定的伺服器陣列並收集結果。GNU Make的”-j”並行編譯可以利用distcc來加速編譯。distcc本身事實上並不參與任何編譯過程,而只是一個編譯器的前端。為編譯器加入分布式特性,並參與部分管理和簡單的負載平衡的功能。distcc在本地完成預先處理(使用gcc -E,完成標頭檔、宏的展開),把結果發給叢集中的工作主機,由工作主機完成編譯(使用gcc -c)並發回編譯結果,最後在本地做連結。 distcc分布式編譯器可以將包含兩個部分: distcc:在用戶端分發編譯任務到編譯主機 distccd:編譯主機啟動distccd守護進程接收編譯任務,並返回編譯結果。
2.安裝Distcc
如果不想走彎路,請不要
sudo apt-get install distcc
也不要在https://code.google.com/p/distcc/downloads/list這裡下載安裝包。
我通過這兩種方式安裝後都會在編譯主機上產生編譯錯誤,結果幾乎所有任務都在本地編譯了。這樣就沒意義了。
我推薦的方法是:
svn checkout http://distcc.googlecode.com/svn/trunk/ distcc-read-only
代碼checkout下來自己編譯。拿到代碼後,要仔細閱讀INSTALL檔案,裡面很詳細,勝過任何網上的其他介紹distcc環境搭建的文章,當然android涉及交叉編譯,會有所不同。
為了順利編譯處安裝包,按照INSTALL文檔所述,安裝以下依賴:
sudo apt-get install gcc make python python-dev binutils-dev alien libavahi-client-dev
為了編譯出deb安裝包,要安裝alien。
Ubuntu 12.04是支援zeroconf的,可以ps查看下,是有avahi-daemon在啟動並執行,但是為了編譯出支援zeroconf的安裝包,需要安裝libavahi-client-dev依賴。zeroconf是什麼東西我就不贅述了。萬事具備只差make了,執行以下:
./autogen.sh./configure --with-avahisudo make deb
with-avahi參數表明build出的包支援zeroconf。如果一切順利,你將在源碼的packaging目錄下得到build出來的安裝包
distcc_3.2rc1-1_amd64 distcc-server_3.2rc1-1_amd64
安裝他們:
dpkg -i distcc_3.2rc1-1_amd64 distcc-server_3.2rc1-1_amd64
注意:
為了實現zeroconf,我最初在虛擬機器和本機上做實驗,按照下文繼續配置好後,可以找到主機。相同的環境在另一台電腦上搭建,zeroconf卻找不到那台電腦。我使用avahi-discover查看Distributed Compiler下的所有主機,確實是可以看到的。這就說明zeroconf的實現程式avahi是可以找到這個主機的,distcc利用avahi尋找主機,理論上也應該可以找到的。繼續追蹤/var/log/syslog
檔案,看到類似下面這一行
(daemon_proc) Browsing for 'x86_64-unknown-linux-gnu_4.4.3_distcc._tcp'.
也就是說,distcc通過avahi尋找主機的時候,要求主機和gcc的版本都要一致,但是實際上gcc小版本不一致並不會影響編譯結果。果斷改代碼,zeroconf.c檔案中:
......# if (dcc_get_gcc_version(version, sizeof(version)) &&# dcc_get_gcc_machine(machine, sizeof(machine))) {## dcc_make_dnssd_subtype(stype, sizeof(stype), version, machine);# } else {rs_log_warning("Warning, failed to get CC version and machine type.\n");strncpy(stype, DCC_DNS_SERVICE_TYPE, sizeof(stype));stype[sizeof(stype)-1] = 0;# }......
這樣distcc找主機時,參數就是"_distcc._tcp"了。這樣修改至少在我這邊是OK的
3.配置distcc
涉及到的設定檔主要在"/etc/distcc/"檔案夾下
client.allow中內容為
#表明192.168.*的IP都能發給自己編譯任務192.168.0.0/16
拷貝android源碼包prebuilts下的編譯工具到指定目錄:/usr/local/distcc/prebuilts/
修改commands.allow.sh的內容為:
numwords=1allowed_compilers="/usr/bin/cc/usr/bin/c++/usr/bin/c89/usr/bin/c99/usr/bin/gcc/usr/bin/g++/usr/bin/*gcc-*/usr/bin/*g++-*/usr/local/distcc/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi*/usr/local/distcc/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6/bin/i686-linux*"......
注意保證新添加的那兩行的內容真是存在,否則服務端會發生編譯錯誤。
在"/etc/distcc/"檔案夾下
hosts檔案的內容為:
localhost+zeroconf
貌似zeroconf能找到的IP只能匹配一個網段,所以可以自己在檔案中繼續添加其他IP地址。
在"/etc/init.d/"檔案夾下
distcc檔案的內容為:
......OPTIONS="--zeroconf --log-file=/var/log/distccd.log --daemon --stats --job-lifetime=1200"USER=distccPROG="distccd"PIDFILE=/var/run/$PROG.pidEXEC="/usr/bin/distccd"......
"--zeroconf --log-file=/var/log/distccd.log"參數是為了支援zeroconf和log。
最後重新重啟distccd
sudo /etc/init.d/distcc reload
以上步驟完成後就基本完成了服務端的配置(用戶端也要進行那些配置),用戶端要想啟動distcc編譯,還需要繼續以下步驟:
4.android的distcc編譯配置
以下只是敘述了android要成功啟動distcc編譯任務所以要的必備條件,很多改動並不優雅。
首先確保編譯前
export PATH=/usr/bin/distcc:$PATH
不建議寫到環境變數中
在"build/core/combo"檔案夾下
TARGET_linux-arm.mk檔案:
......ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)TARGET_TOOLCHAIN_ROOT := /usr/local/distcc/prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-4.6TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/arm-linux-androideabi-endif......
select.mk檔案:
......include $(BUILD_COMBOS)/$(combo_target)$(combo_os_arch).mk$(combo_target)CC := distcc $($(combo_target)CC)$(combo_target)CXX := distcc $($(combo_target)CXX)......
最後啟動編譯
. ./build/envsetup.shlunchmake -jN
即可
5.監視distcc編譯任務
distcc內建distccmon-text,可以啟動文本化監視
#3秒重新整理一次distccmon-text 3
也可以使用distccmon-gnome啟動圖形化監視程式
sudo apt-get install distccmon-gnomedistccmon-gnome &
即可