在FASTBuild中使用分布式(distribution)編譯需要注意以下四個環節。
一、編譯器設置
某些編譯過程與分布式相矛盾,如果一個對象不能被安全的分發出去,那它將自動在本地被編譯,一個編譯過程可以安全的混合可分發對象與不可分發對象。
對於GCC/SNC/Clang編譯器,沒有任何限制。
對於MSVC編譯器:
/ZW 選項不能使用
預編譯頭文件不能被分發,他們是因機器而異的。(使用了PCH的對象可以被分發)
/clr 選項不能使用,因為微軟編譯器的預處理器有bug。
二、編譯器同步
FASTBuild會把編譯器(Compiler)同步到遠端機器的一個隔離的環境中,這避免了遠端機器也需要安裝工具鏈,並且能保證編譯器的一致性。為了實現這些,FASTBuild需要知道通過網絡要同步哪些文件。這需要通過Compiler函數來實現。下面以一個實測可用的編譯器配置,以 VS 2015 amd 64位編譯器為例:
.VSBasePath = 'C:\Program Files (x86)\Microsoft Visual Studio 14.0'
Compiler('MSVC2015') // (optional) Alias { .Executable = '$VSBasePath$\VC\bin\amd64\cl.exe' .ExtraFiles = { '$VSBasePath$\VC\bin\amd64\1033\clui.dll', '$VSBasePath$\VC\bin\amd64\c1.dll', '$VSBasePath$\VC\bin\amd64\c2.dll', '$VSBasePath$\VC\bin\amd64\c1xx.dll', '$VSBasePath$\VC\bin\amd64\mspdb140.dll', '$VSBasePath$\VC\bin\amd64\msobj140.dll', '$VSBasePath$\VC\bin\amd64\mspdbcore.dll', '$VSBasePath$\VC\bin\amd64\mspdbsrv.exe'} }
三、工作者目錄
工作者(Worker)就是除了主機之外,通過網絡參與到分布式編譯過程中的其他機器,他們的職責就是在空閑的時候,提供若干個(可設置)CPU內核出來,供主機編譯使用。工作者(Worker)需要通過一個商定的位置被找到,這個商定的位置是一個主機(host)和工作者(Worker)都能找到的網絡路徑。這個路徑要通過環境變量 FASTBUILD_BROKERAGE_PATH 來設置。工作者通過在這個位置寫一個標記來示意自己可用。客戶機通過檢查這個位置來尋找可用的工作者。這里的重點是這個FASTBUILD_BROKERAGE_PATH 指定的必須是一個共享網絡路徑,而且能被所有參與分布式編譯的機器自由地讀寫。
下面是一個簡單的啟動FASTBuildWorker的bat腳本(start_fbuild_worker.bat),如果發現該進程已存在,則不做任何操作。正常模式啟動,啟動后在桌面右下角會有圖標顯示。
echo off & color 0A
rem 在這里設置的環境變量只在bat腳本內有效 set FASTBUILD_BROKERAGE_PATH=\\192.168.22.31\.fastbuild.brokerage tasklist | find /i "FBuildWorker.exe.copy" || start /min "" FBuildWorker.exe -cpus=2 -mode=idle
下面是一個簡單的啟動FASTBuildWorker的vbs腳本(start_fbuild_worker.vbs),如果發現該進程已存在,則不做任何操作。控制台模式啟動(-console),並且隱藏了窗口,啟動后只在任務管理器中才能被看到。具體用途自己體會。(在實際應用中發現,這個腳本第一次運行不會生效,大概是剛剛設置的環境變量在腳本中沒有生效,不過Worker進程關閉之后,再次運行就會生效了)
set bag=getobject("winmgmts:\\.\root\cimv2") set pipe=bag.execquery("select * from win32_process where name='FBuildWorker.exe'") For Each id In pipe wscript.quit Next wscript.CreateObject("Wscript.Shell").Environment("user").Item("FASTBUILD_BROKERAGE_PATH")="\\192.168.22.31\.fastbuild.brokerage" wscript.CreateObject("Wscript.Shell").Run "FBuildWorker.exe -cpus=2 -mode=idle -console",0
Worker啟動后,會在剛才設置的那個網絡路徑中寫一個標記,表示自己隨時可以被調用,如下圖:
大家不要擔心這個Worker進程會占用太多資源,當你的CPU處於繁忙的狀態,他會自動地把自己的標記取消,使自己不可被調用。換句話說,Worker(s)只會在自己有余力的時候才會幫助他人工作。
四、激活分布式編譯
在上述步驟都順利完成之后,便可以開始分布式編譯了。執行fbuild.exe的時候,只需要加上 -dist 或者 -distverbose 參數,就可以調用遠端的Worker為自己工作。
下面是一個簡單的啟動fbuild的bat腳本
echo off & color 0A
rem 在這里設置額環境變量只在bat腳本內有效
set FASTBUILD_BROKERAGE_PATH=\\192.168.22.31\.fastbuild.brokerage call start_fbuild_worker.bat fbuild.exe -cache -distverbose pause
這里調用了start_fbuild_worker.bat腳本,其實使用分布式編譯不一定非要在本機打開Worker進程,但是本着互惠互利的原則,在使用別人的CPU核心的時候,最好自己也開啟Worker進程。
以上便是我學習使用FASTBuild的總結,不可否認FASTBuild作為一個免費開源的分布式編譯工具,性能相當出色,之前我們的C++項目使用VS完全編譯一次需要花費40min,在使用了FASTBuild之后,開啟Caching和Distribution,可以在5min內完全編譯一次,效率提升了近90%。感謝FASTBuild的開發人員,讓我和同事們在工作的時候心情舒暢了很多。