Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 基於 Distcc 的android分布式編譯環境的搭建

基於 Distcc 的android分布式編譯環境的搭建

編輯:關於Android編程

關於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-avahi
sudo 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=1
allowed_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=distcc
PROG="distccd"
PIDFILE=/var/run/$PROG.pid
EXEC="/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.6
TARGET_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.sh
lunch
make -jN

即可

5.監視distcc編譯任務
distcc自帶distccmon-text,可以啟動文本化監視

#3秒刷新一次
distccmon-text 3

也可以使用distccmon-gnome啟動圖形化監視程序

sudo apt-get install distccmon-gnome
distccmon-gnome &

即可


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved