之前有一篇介紹到在windows下利用VS2015編譯tensorflow的C++接口,接下來這篇就介紹下在Ubuntu下編譯tensorflow的C++接口。
先說一下我的電腦配置,首先是Ubuntu16.04,anaconda用的是3.4.2,CUDA用的是9.0的,cudnn用的是7.0.5的。因為已經(jīng)在anaconda3上安裝好了tensorflow1.7的,但是這次要編譯C++的接口,所以我還是選擇編譯tensorflow1.7的源碼。最近重新編譯的時候改用了tensorflow1.12。
一、準備編譯環(huán)境
編譯這里要用到bazel來編譯,所以要安裝它,Ubuntu下安裝的指令如下:
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
然后輸入以下指令:
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
更新:
sudo apt-get update
安裝bazel:
sudo apt-get install bazel
這里不要這么做了,因為這么做會把bazel更新到最新的版本,但是編譯tensorflow的時候,不同tensorflow要與bazel的版本是對應的,如果這么做的話,后面的操作就會出錯,而且也不知道怎么解決。正確的做法應該是下載對應的版本來安裝bazel,tensorflow與bazel的版本應該在tensorflow的官網(wǎng)查找:https://tensorflow.google.cn/install/source
linux下tensorflow與python、GCC、Bazel的版本關(guān)系,GCC倒是沒有問題,應該支持C++11就可以,但bazel就真的還是要對應好版本,不然一大堆問題,折騰。
| Version | Python version | Compiler | Build tools |
| tensorflow-1.14.0 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.24.1 |
| tensorflow-1.13.1 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.19.2 |
| tensorflow-1.12.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
| tensorflow-1.11.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
| tensorflow-1.10.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
| tensorflow-1.9.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.11.0 |
| tensorflow-1.8.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 |
| tensorflow-1.7.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 |
| tensorflow-1.6.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 |
| tensorflow-1.5.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.8.0 |
| tensorflow-1.4.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.5.4 |
| tensorflow-1.3.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 |
| tensorflow-1.2.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 |
| tensorflow-1.1.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 |
| tensorflow-1.0.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 |
| Version | Python version | Compiler | Build tools | cuDNN | CUDA |
| tensorflow_gpu-1.14.0 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.24.1 | 7.4 | 10.0 |
| tensorflow_gpu-1.13.1 | 2.7, 3.3-3.7 | GCC 4.8 | Bazel 0.19.2 | 7.4 | 10.0 |
| tensorflow_gpu-1.12.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 | 7 | 9 |
| tensorflow_gpu-1.11.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 | 7 | 9 |
| tensorflow_gpu-1.10.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 | 7 | 9 |
| tensorflow_gpu-1.9.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.11.0 | 7 | 9 |
| tensorflow_gpu-1.8.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 | 7 | 9 |
| tensorflow_gpu-1.7.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | 7 | 9 |
| tensorflow_gpu-1.6.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 | 7 | 9 |
| tensorflow_gpu-1.5.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.8.0 | 7 | 9 |
| tensorflow_gpu-1.4.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.5.4 | 6 | 8 |
| tensorflow_gpu-1.3.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 | 6 | 8 |
| tensorflow_gpu-1.2.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 | 5.1 | 8 |
| tensorflow_gpu-1.1.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 | 5.1 | 8 |
| tensorflow_gpu-1.0.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 | 5.1 | 8 |
其他的應該就沒啥,就是這個bazel把我給折騰的啊
這里tensorflow1.12對應的bazel版本是0.15.0,所以去github搜bazel下載http://bazel-0.15.0-installer-linux-x86_64.sh,然后安裝。
二、下載tensorflow源碼
tensorflow的源碼是在github上就可以下載的,目前已經(jīng)更新到1.11,但是我還是下載了1.7的版本,我下載的是版本1.12的。下載之后解壓出來。
三、配置編譯環(huán)境
解壓源碼之后,進入根目錄,輸入指令:
./configure
接下來就是配置清單:
這里要說明的是如果有CUDA,那么Do you wish to build Tensorflow with CUDA?一定要選Y,然后其它的我基本都是N
配置好之后就進行編譯:
bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so
這里如果不用cuda的話(前面配置的時候就不要在CUDA那一項那里輸入Y),就輸入:
bazel build --config=opt //tensorflow:libtensorflow_cc.so
然后是等待,這個過程大概會花費30分鐘左右,而且CPU的占用量是達到100%的,所以這個時候最好就不要坐別的事情了。
編譯之后我這里會有一個問題(這個問題我在編譯tensorflow1.12的時候沒有遇到,所以看不同版本吧):
這個錯誤并不是因為文件沒有而是因為找不到,實際上,這個文件就在tensorflow-r1.7/tensorflow文件夾下,但是需要修改/tensorflow-r1.7/tensorflow/BUILD這個文件才行,打開這個文件之后修改大概在812行,注釋掉后,另起一行設(shè)置正確的路徑:
修改之后重新輸入編譯的指令編譯一次就可以了。編譯好之后在文件夾tensorflow-r1.7/bazel-bin/tensorflow下面,會有兩個so文件:libtensorflow_cc.so和libtensorflow_framework.so,這兩個就是我們需要的。
四、一些錯誤
下面這幾個錯誤都是在使用的時候發(fā)現(xiàn)的,主要是在編譯的時候有些依賴文件沒有下載到,所以需要自己去下載。
(1)、nsync_cv.h文件缺失:
這個文件一般是會在tensorflow/contrib/makefile/downloads/nsync/public這個文件夾下的,但是我這邊是編譯tensorflow的時候有些依賴文件沒有下載到導致它缺失,解決方法是存在/tensorflow/contrib/makefile/download_dependencies.sh這個文件,執(zhí)行它來下載相關(guān)的文件,相關(guān)文件會放在/tensorflow根目錄/tensorflow/contrib/makefile/downloads這個文件夾下;
(2)、提示Eigen相關(guān)的問題
這個問題跟前面的類似,如果下載了相關(guān)的依賴文件之后,在/tensorflow-r1.7/tensorflow/contrib/makefile/downloads文件夾下找到eigen文件夾,進入之后執(zhí)行以下指令進行eigen的編譯:
mkdir build
cd build
cmake ..
make
sudo make install
(3)、提示關(guān)于protobuf版本的問題
問題如下:
這個主要是protobuf版本的問題,所以要查看bazel-genfiles/tensorflow/core/framework/types.pb.h這個文件夾中關(guān)于protobuf的版本要求,然后下載相應的版本來更新即可,這里tensorflow1.12要求是protobuf要大于等于3.6:
所以就去github上下載對應的protobuf版本。要下載源碼,然后編譯安裝即可。
暫時我就遇到這幾個問題,之后如果還有遇到其它問題,我會繼續(xù)更新的。
五、參考
1、https://blog.csdn.net/zwx1995zwx/article/details/79064064
陽光
在天上一閃
又被烏云埋掩
暴雨沖洗著
我靈魂的底片-- 顧城