https://www.bazel.io/versions/master/docs/install.html#compiling-from-source
Compiling from source
If you would like to build Bazel from source, clone the source from GitHub and run ./compile.sh to build it:
$ git clone https://github.com/bazelbuild/bazel.git
cd bazel
$ ./compile.sh
This will create a bazel binary in bazel-bin/src/bazel. This binary is self-contained, so it can be copied to a directory on the PATH (e.g., /usr/local/bin) or used in-place.
Check our continuous integration for the current status of the build.
http://www.cnblogs.com/Jack47/p/install-bazel-on-redhat-enterprise-5.html
目前Google Bazel沒有提供各個作業系統下的二進制安裝包,隻提供源代碼,需要我們自己編譯安裝,詳情可以見我翻譯的中文版Google Bazel FAQ。Google Bazel官方安裝文檔在這裡,裡面隻介紹了在Ubuntu(14.04,14.10)和Mac OS X下的編譯安裝。而我們公司的建構機器是Redhat Linux系列,在編譯Bazel的時候遇到了很多問題,在這裡跟大家分享下解決思路和方法,為了照顧像作者這樣的小白,文章寫的稍微有點啰嗦,見諒。
編譯
我編譯Bazel的系統環境配置是:
系統環境
作業系統:Redhat Enterprise 5.7
核心版本:2.6.32-220
gcc: 4.1.2
後來發現需要JDK 1.8, 支援C++ 11的編譯器才可以順利編譯Bazel,下文會介紹如何安裝這些依賴。
下載下傳代碼
$ git clone https://github.com/google/bazel/
編譯
直接執行./compile.sh腳本來編譯Bazel
$ ./compile.sh
報錯:
Package libarchive was not found in the pkg-config search path.
Perhaps you should add the directory containing ‘libarchive.pc’ to the PKG_CONFIG_PATH environment variable
No package ‘libarchive’ found`
可以看到提示是 libarchive 包不在PKG_CONFIG_PATH下。利用Redhat Linux下的包管理工具yum檢視到底安裝了這個包沒有:
$ rpm -qa | grep libarchive
發現就沒有安裝這個包,于是進行安裝。libarchive是一個支援多種格式的檔案和壓縮的庫。
安裝libarchive
從官方網站下載下傳最新版本的 libarchive :
$ wget http://libarchive.org/downloads/libarchive-3.1.2.tar.gz
解壓縮得到源碼:
gunziplibarchive−3.1.2.tar.gz tar libarchive-3.1.2.tar
然後通過檢視libarchive-3.1.2目錄下的 INSTALL 檔案,找到編譯安裝方法:
編譯:
./configure make
安裝[需要管理者權限]:
$ sudo make install
此時再次執行Bazel的編譯腳本:
$ ./compile.sh
發現還是跟沒安裝之前報一樣的錯誤:
Package libarchive was not found in the pkg-config search path.
Perhaps you should add the directory containing ‘libarchive.pc’ to the PKG_CONFIG_PATH environment variable
No package ‘libarchive’ found
提示是說在pkg-config的搜尋路徑下找不到 libarchive 這個包,需要把libarchive.pc這個檔案的路徑添加到PKG_CONFIG_PATH這個環境變量裡。回過頭檢視 libarchive 的安裝過程中列印出的資訊,可以看到:
/usr/bin/install -c -m 644 build/pkgconfig/libarchive.pc ‘/usr/local/lib/pkgconfig
發現libarchive.pc是安裝到了 /usr/local/lib/pkgconfig 目錄下。
于是設定環境變量PKG_CONFIG_PATH:
exportPKGCONFIGPATH=/usr/local/lib/pkgconfig: PKG_CONFIG_PATH
再編譯Bazel,發現又出錯了:
JDK version is lower than 1.8, please set $JAVA_HOME.
是jdk的版本不對,看了一下目前環境下的java版本:
$ java -version
java version “1.6.0_20”
安裝jdk 1.8
從Oracle官網下載下傳jdk1.8, 由于我的機器是x86架構,64位機器,于是下載下傳這個版本。如果直接 wget 會失敗,需要在網頁裡同意License才可以下載下傳,是以從浏覽器中下載下傳jdk1.8。如果是遠端登入到伺服器,可以在本地下載下傳,然後使用scp指令上傳到伺服器:
$scp jdk-8u45-linux-x64.rpm [email protected]:~/
安裝
$ sudo rpm -ivh jdk-8u45-linux-x64.rpm
bazel需要通過環境變量$JAVA_HOME來得到jdk的安裝路徑。而jdk rpm安裝包不會自動幫助我們設定環境變量JAVA_HOME,需要我們自己設定。
設定JAVA_HOME
很奇怪,安裝後包名稱變了,使用如下rpm指令檢視安裝後jdk 1.8的包名稱:
$ rpm -qa | grep jdk
jdk1.8.0_45-1.8.0_45-fcs
檢視這個包中檔案都安裝到哪些路徑下了:
$ rpm -ql jdk1.8.0_45-1.8.0_45-fcs
發現安裝到/usr/java/jdk1.8.0_45/這個目錄下去了。
于是設定JAVA_HOME:
$ export JAVA_HOME=/usr/java/jdk1.8.0_45/
檢視JAVA_HOME是否設定正确:
echo JAVA_HOME
/usr/java/jdk1.8.0_45/
可以看到确實設定成功了。
再次編譯Bazel,終于看到編譯的輸出了:
$ ./compile.sh
Compiling Java stubs for protocol buffers…
Compiling Bazel Java code…
Extracting helper classes for Bazel Java…
Creating libblaze.jar…
Compiling SingleJar tool code…
Extracting helper classes for SingleJar tool…
Creating SingleJar_deploy.jar…
Compiling JavaBuilder tool code…
Extracting helper classes for JavaBuilder tool…
Creating JavaBuilder_deploy.jar…
Compiling client .cc files…
cc1plus: error: unrecognized command line option “-std=c++0x”
看起來是不支援這個選項: “-std=c++0x”。
如何檢視到底./compile.sh這個腳本執行了哪些語句,到底是哪條指令失敗了?編輯這個shell腳本,在開頭寫入set指令:
set -x
然後再次運作Bazel編譯,此時可以看到 ./compile.sh 腳本的每一行指令。最終出錯誤的指令是:
g++ -I. -std=c++0x -c ‘-DBLAZE_JAVA_CPU=”k8”’ -DBLAZE_OPENSOURCE=1 -o output/objs/blaze_startup_options.cc.o src/main/cpp/blaze_startup_options.cc
看起來是 g++ 不支援 c++0x标準。上網搜了一下,發現gcc 4.6以上的版本才支援 C++ 11。怎麼在Redhat Linux下安裝更高版本的gcc呢?
上網搜尋後,發現Red Hat Enterprise Linux下有開發工具套件 devtoolset,可以友善的安裝各個版本的gcc,而且是可以多個版本并存的,友善的解決了我等小白在源碼編譯、安裝gcc時可能出現的問題。但官方的那一套東西,需要付費,而公司的這個Red Hat版本不支援。後來發現Redhat Linux的社群版本–Centos下有人已經建構好了Redhat Developer Toolset的相關rpm包,參照此文來進行devtoolset的安裝。
$ sudo wget http://people.centos.org/tru/devtools-2/devtools-2.repo -O /etc/yum.repos.d/devtools-2.repo
sudoyuminstalldevtoolset−2−gccdevtoolset−2−binutilsdevtoolset−2−gcc−c++安裝完成後,使用scl指令在shell環境中啟用devltoolset−2 scl enable devtoolset-2 bash
然後驗證此時gcc的版本:
$ gcc -v
可以看到此時已經是gcc 4.8.2版本了。有興趣的同學可以檢視一下enable這個腳本的實作,非常簡潔,會讓你收獲一些東西,路徑是:/opt/rh/devtoolset-2/
再次編譯Bazel,發現又出錯了:
src/main/tools/namespace-sandbox.c: In function ‘main’:
src/main/tools/namespace-sandbox.c:140:36: error: ‘CLONE_NEWUTS’ undeclared (first use in this function) CHECK_CALL(unshare(CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER));
在網上看到unshare這個函數的CLONE_NEWUTS參數在我的這個系統版本裡2.6.32 裡面應該是已經支援了得。後來發信給bazel郵件組求助,他們說是我得系統核心版本太老了,不支援namespace,讓我把namespace-sandbox的編譯去掉,不影響正常功能。
于是注釋掉,sandbox的編譯:
if [[ $PLATFORM == “linux” ]]; then
log “Compiling sandbox…”
“${CC}” -o output/namespace-sandbox -std=c99 src/ main/tools/namespace-sandbox.c
fi`
再次編譯,編譯終于成功了!
Build successful! Binary is here: /home/jack47/bazel/output/bazel
明天如果把bug修完了,會更新一篇如何上手bazel的文章,大家周末愉快!
後記:
其實我在搞明白可以簡單的使用devltoolset來安裝高版本的gcc之前,自己源碼編譯,安裝gcc後,遇到了一些稀奇古怪的錯誤,比如系統頭檔案裡的某些宏沒有定義,libstdc++中找不到GLIBCXX_3.4.20等,還是花了好幾天時間在上面的。是以讀者朋友們,你們是幸福的啊,按照我的這篇文章,半天時間怎麼着也能編譯出Bazel來。
做個調查,C++程式員,你能厘清楚這幾個名詞之間的差別和聯系嗎?不清楚的默默給我點下文章右下角的“推薦”按鈕吧,哈哈。其實我寫這篇文章之前也不太清楚glibc和libstdc++這兩個東東的:)
GCC
glibc
libstdc++
參考資料:
Redhat Developer toolset的介紹:很有意思,解釋了這套工具解決的問題,背後的原理等
Google軟體建構工具Bazel原理及使用方法介紹