天天看點

Redhat環境下編譯安裝bazelif [[ $PLATFORM == “linux” ]]; thenlog “Compiling sandbox…”“${CC}” -o output/namespace-sandbox -std=c99 src/ main/tools/namespace-sandbox.cfi`

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原理及使用方法介紹

繼續閱讀