首先,感謝各位前輩的分享。搜尋到的教程、文章太多,沒有全部記錄下來,很抱歉不能一一感謝,一開始也沒想到能寫這麼一篇文,以後注意…
【目前隻編譯出dll lib,正在研究怎麼調用……應該還有一些其他的小坑,】
(有些步驟可能是多餘的,我就不去一個個排除了…總之能編譯。以下連結,第一個是tensorflow官網,不過有些按照官網的話行不通…)
編譯前的準備工作參照以下連結,或直接看本文。
最新tensorflow 2.2.0源碼編譯,支援gpu加速,附python、c++驗證
https://www.tensorflow.org/install/source_windows?hl=zh_cn
win10+vs2019+bazel+編譯tensorflow2.1-CPU-only版
Windows10 Bazel 編譯 Tensorflow 2 C++ dll 和 lib 檔案
JayKay-x:Win10 VS2019+Cuda10.2+bazel編譯tensorflow-2.1.0
TensorFlow 1.13 在 windows 上的建構
Bazel編譯Tensorflow C++ 版本CPU/GPU DLL動态庫(附tensorflow CPU/GPU開)發包
1 VS2019、 下載下傳anaconda、msys2、bazel
注意,我自己的電腦隻有C槽,是以所有東西都放在C槽裡了,bazel 編譯的時候占用C槽的空間可能比較大,是以下載下傳安裝,還有tensorflow源碼包,請各位自己找其他盤符的位置。
### VS2019去官網下載下傳就可以。SDK版本好像沒有要求,隻安裝一個,記住是哪個就好。系統變量的設定後面會說,除了VS的還有bazel、msys2的。
另外,tensorflow官網說需要VS2019 生成工具,但不用另外下載下傳安裝生成工具……但還是都安裝吧。
https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/
### 上連結是anaconda的清華鏡像源(感謝),下載下傳安裝好之後,參照說明修改C:UsersAdministrator目錄下的
.condarc
檔案 ,複制粘貼上去就好啦。
(另外求助一下,上面的 .condarc 字型後面的底色在網頁上怎麼添加,如果有人看到的話……)
Administrator是自己電腦的使用者名,比如自己的電腦叫xiaobai,那目錄就是C:Usersxiaobai。
【如果沒有
.condarc
檔案的話】,打開終端,桌面工作列點選[開始]->[Windows系統]->[指令提示符],或者使用快捷鍵win+r,win在一般鍵盤上是位于左邊Alt鍵的左側,蘋果電腦是command鍵。
(沒錯,這是windows的……算是教程吧,如果是在蘋果上雙系統的話commond就是win……我就是蘋果雙系統……至于為什麼要在蘋果雙系統windows編譯……個人原因,不啰嗦了)
conda config --set show_channel_urls yes
在終端中輸入以上指令(複制粘貼就行),回車執行。之後就可以在C:UsersAdministrator目錄下找到
.condarc
檔案啦~
之後依舊按照網址上的說明去修改。(修改成清華鏡像源,因為國外資源下載下傳比較困難,為什麼會這樣,這一切要從那一堵牆說起……額)
接下來建立一個python環境,在終端輸入以下指令
conda create -n py37 python==3.7
[py37]是自己起的環境名,改成 xiaobai 也可以,比如
conda create -n xiaobai python==3.7
建立好之後可以測試一下
conda activate py37
出現以下的話,環境就建立成功啦~
(py37) C:UsersAdministrator>
然後下載下傳幾個包。
注意,protobuf 要 3.8.0 版本。(後面會說明為什麼)
conda install protobuf==3.8.0
conda install numpy
conda install keras-preprocessing
conda install patch
### 接下來是msys2 ,下載下傳位址如下,預設安裝就可以,或者不在C槽也行。
https://www.msys2.org/MSYS2https://www.msys2.org/
安裝好之後添加系統變量。
msys2、以及前面說到的VS(還有後續bazel的)。
有兩個,一個是使用者變量,一個是系統變量。以及上面在 py37 環境裡安裝的 patch。
在Anaconda 目錄下 C:UsersAdministratorAnaconda3envstf37Librarybin 找到 patch.exe 檔案以及 patch.exe.manifest 複制粘貼到 msys2 根目錄下。
系統變量:
BAZEL_SH C:pathMSYS2usrbinbash.exe
BAZEL_VC C:Program Files (x86)Microsoft Visual Studio2019BuildToolsVC
BAZEL_VS C:Program Files (x86)Microsoft Visual Studio2019Professional
BAZEL_VC_FULL_VERSION 14.28.29333
BAZEL_WINSDK_FULL_VERSION 10.0.19041.0
BAZEL_VC_FULL_VERSION 的變量值,打開檔案夾,在以下目錄中檢視。(截圖裡的錯了)
C:Program Files (x86)Microsoft Visual Studio2019ProfessionalVCToolsMSVC
BAZEL_WINSDK_FULL_VERSION 的變量值,按照Visual Studio安裝的WindowsSDK版本。
使用者變量
系統變量
【打開下載下傳好的msys2,不是終端】
msys2 的界面
依次執行以下三個指令。
pacman -Syu
pacman -Su
pacman -S patch, unzip, grep
cd到自己想要的檔案夾,比如cd D:tf,然後下載下傳tensorflow。
cd D:tf
git clone https://github.com/tensorflow/tensorflow.git
git速度太慢的話換以下。
git clone https://gitee.com/mirrors/tensorflow.git
下載下傳好tensorflow之後依次輸入以下指令,執行完之後就可以關閉msys2啦
cd tensorflow
git checkout v2.2.0
git checkout 是切換版本的指令,v後面如果是2.4.0的話切換的就是2.4.0,這裡編譯的是2.2.0。
接下來,注意,在[開始]->[Visual Sdutio 2019] 下找到
[x64 Native Tools Command Prompt for VS 2019],如下圖。它和終端很像,【
但是編譯是要在這裡編譯的!】(感謝 @JayKay-x 的分享)。
這貨不是cmd
打開
[x64 Native Tools Command Prompt for VS 2019],輸入以下指令。
conda activate py37
python -m venv C:tftensorflow.venv
C:tftensorflow 是自己 clone 的 tensorflow 源碼位置。這之後 C:tftensorflow 目錄下就會出現一個 .venv 檔案夾,打開這個檔案夾,重新打開
[x64 Native Tools Command Prompt for VS 2019],将 .venv 檔案夾裡打開 Script檔案夾,找到 activate.bat 檔案拖入進去,然後回車執行。
這貨不是cmd
conda deactivate
python --version
執行之後,
【注意】要退出 tf37 環境,檢查一下 python 的版本是不是 3.7.* 。
這貨不是cmd
确認無誤後,開始 pip 一些東西,
注意,要在 .venv 這個編譯環境裡面 pip安裝。(其實一行 pip install 就可以,隻不過這樣看起來好看一些)
python -m pip install --upgrade pip
pip install absl-py astunparse==1.6.3 backports.weakref enum34 gast==0.3.3 google_pasta
pip install h5py==2.10.0 keras_preprocessing numpy==1.18.0 opt_einsum
pip install tensorboard==2.2.0 tensorflow_estimator==2.2.0 termcolor wrapt wheel six
pip install protobuf==3.8.0
pip install patch
如果pip速度慢的話,按以下。(以下是aliyun鏡像,也可以換成其他)
稻花香:安裝pip報錯:WARNING: Retrying (Retry(total=4,...
pip 添加trusted host 一勞永逸
- 找到系統盤下C:C:Users使用者名AppDataRoaming
- 檢視在Roaming檔案夾下有沒有一個pip檔案夾,如果沒有建立一個;
- 進入pip檔案夾,建立一個pip.ini檔案;
- 使用記事本的方式打開pip.ini檔案,寫入:
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
trusted-host = https://mirrors.aliyun.com
然後使用管理者權限打開cmd後運作指令:
pip install -i https://mirrors.aliyun.com/pypi/simple --upgrade pip --user
https://github.com/tensorflow/tensorflow/blob/r2.2/tensorflow/tools/pip_package/setup.py
可以看以上連結中 REQUIRED_PACKAGES= [……] 内寫出的東西。如果是 tensorflow 其他版本的話切換一下對應版本,本文隻是 tensorflow2.2.0。
此外需要注意最後兩個,一個是
protobuf 版本需要 3.8.0,後面步驟中執行 configure.py 檔案之後可以找到這個要求,總之下載下傳 3.8.0 就對啦,tensorflow 其他版本可能不一樣。
另一個是 patch,在上面的連結裡沒有寫,但需要(也可以不安裝試試,不行就再裝呗)。
### 下載下傳 bazel 2.0.0 版本,不需要安裝,将下載下傳好的 bazel200.exe 檔案
改名為 bazel.exe,并放入到 msys2 的安裝目錄下,因為 msys2 已經設定好系統變量了。但也可以給 bazel.exe 另外再設定一下(脫褲子放屁,額我就這麼幹了,其實放到 msys2裡面就不用再另外設定了)。
到此,vs路徑、msys2路徑、bazel路徑、編譯環境、pip需要的各種包,就全都安排了。
(辛苦辛苦,喝口水歇一歇)
2、configure.py配置,準備開始編譯
其實還是要繼續下載下傳。下面的跳過,直接開始編譯,編譯成功之後在vs中測試,如果報錯無法識别的外部符号,再按照這種方法修改。
打開 tensorflowtensorflowtoolsdef_file_filterdef_file_filter.py.tpl,定位到 以下位置,看到缺的就往上加。
# Header for the def file.
if args.target:
def_fp.write("LIBRARY " + args.target + "n")
def_fp.write("EXPORTSn")
def_fp.write("t [email protected]@@[email protected]")
def_fp.write("t [email protected]@@[email protected]@[email protected]@@Zn")
def_fp.write("t [email protected]@@[email protected]")
def_fp.write("t [email protected]@tensorflow@@[email protected]@[email protected]@2@@Zn")
def_fp.write("t [email protected]@tensorflow@@[email protected]@[email protected]@[email protected]@Zn")
def_fp.write("t [email protected]@tensorflow@@[email protected]@[email protected]@[email protected]@2@@Zn")
def_fp.write("t [email protected]@tensorflow@@[email protected]@[email protected]@[email protected]@012@@Zn")
def_fp.write("t [email protected]@@[email protected]@1@@Zn")
def_fp.write("t [email protected]@tensorflow@@[email protected][email protected][email protected]@std@@[email protected]@2@@std@@@Zn")
def_fp.write("t [email protected]@tensorflow@@[email protected]@[email protected]@@Zn")
def_fp.write("t [email protected]@tensorflow@@[email protected]")
def_fp.write("t [email protected]@@[email protected]")
def_fp.write("t [email protected]@tensorflow@@[email protected]@[email protected]@tensorflow@@[email protected]@tensorflow@@@std@@@std@@[email protected]@tensorflow@@[email protected]@tensorflow@@@std@@@5@@Zn")
def_fp.write("t [email protected]@@[email protected]")
def_fp.write("t [email protected]@@[email protected]@1@@Zn")
def_fp.write("t [email protected]@@[email protected]@[email protected]@[email protected]@[email protected][email protected]@std@@[email protected]@2@@std@@AEBV?$unordered_set@[email protected][email protected]@std@@[email protected]@2@@std@@[email protected][email protected][email protected]@std@@[email protected]@2@@std@@@[email protected][email protected][email protected][email protected]@std@@[email protected]@2@@std@@@[email protected][email protected][email protected][email protected]@std@@[email protected]@2@@std@@@2@@[email protected]@1@@Zn")
def_fp.write("t [email protected]@@[email protected]")
def_fp.write("t [email protected]@tensorflow@@[email protected]@[email protected]@[email protected]@012@@Zn")
def_fp.write("t ??0CombinedNonMaxS[email protected]@tensorflow@@[email protected]@[email protected]@[email protected]@Zn")
【不用按這個改了,上面的就可以解決報錯了。如果不行再用以下方法。】
Bazel編譯Tensorflow C++ 版本CPU/GPU DLL動态庫(附tensorflow CPU/GPU開)發包
打開 tensorflow/BUILD 檔案,添加以下内容。
tf_cc_shared_object(
name = "libtensorflow_cc.so", # 不知道要不要改成tensorflow_cc.so / tensorflow_cc.dll
linkopts = select({
"//tensorflow:darwin": [
"-Wl,-exported_symbols_list", # This line must be directly followed by the exported_symbols.lds file
"$(location //tensorflow:tf_exported_symbols.lds)",
],
"//tensorflow:windows": [
"-def:" + # This line must be directly followed by the exported_symbols_msvc.lds file
"$(location //tensorflow:tf_exported_symbols_msvc.lds)",
],
"//conditions:default": [
"-z defs",
"-Wl,--version-script", # This line must be directly followed by the version_script.lds file
"$(location //tensorflow:tf_version_script.lds)",
],
}),
visibility = ["//visibility:public"],
deps = [ # 以下cc的檔案夾有些對應不上,可能是因為tensorflow版本不同
"//tensorflow:tf_exported_symbols.lds",
"//tensorflow:tf_exported_symbols_msvc.lds",
"//tensorflow:tf_version_script.lds",
"//tensorflow/c:c_api",
"//tensorflow/c/eager:c_api",
"//tensorflow/cc:cc_ops",
"//tensorflow/cc:client_session",
"//tensorflow/cc:scope",
"//tensorflow/cc/profiler",
"//tensorflow/core:tensorflow",
] + if_ngraph(["@ngraph_tf//:ngraph_tf"]),
)
建立 tf_exported_symbols_msvc.lds 檔案,儲存到 tensorflow 根目錄,也就是BUILD檔案所在的目錄。
LIBRARY libtensorflow_cc # 不知道要不要改成 tensorflow_cc
EXPORTS
[email protected]@@[email protected]
[email protected]@@[email protected]
[email protected]@tensorflow@@[email protected]@Z
[email protected]@tensorflow@@[email protected]
[email protected]@tensorflow@@[email protected]
[email protected]@tensorflow@@[email protected]
[email protected]@@[email protected]
[email protected]@@[email protected]
[email protected]@@[email protected]
[email protected]@tensorflow@@[email protected]@@Z
[email protected]@tensorflow@@[email protected]@2@@Z
[email protected]@@[email protected]
[email protected]@@[email protected]@@Z
[email protected]@@[email protected]
[email protected]@@[email protected]
[email protected]@tensorflow@@QEBAXXZ
[email protected]@@[email protected]@[email protected]@[email protected]@[email protected][email protected]@std@@[email protected]@2@@std@@AEBV?$un[email protected][email protected][email protected]@std@@[email protected]@2@@std@@[email protected][email protected][email protected]@std@@[email protected]@2@@std@@@[email protected][email protected][email protected][email protected]@std@@[email protected]@2@@std@@@[email protected][email protected][email protected][email protected]@std@@[email protected]@2@@std@@@2@@[email protected]@1@@Z
[email protected]@@[email protected]@[email protected]@@Z
cd 到 已經轉換成 2.2.0 版本的 tensorflow 檔案夾,執行以下指令,開始配置。
python configure.py
configure.py 編譯配置
配置到這裡就ok了。接下來開始編譯,不過先說一下前面提到的 protobuf 、 bazel 的版本。
之前說的 protobuf 版本,在執行 configure.py 檔案之後,用Notepad++或者其他編譯器打開 tensorflowtensorflowworkspace.bzl 檔案,搜尋protobuf,能找到一段說明。沒試過其他版本的protobuf能不能行,3.8.0 是沒問題的。bazel 版本在 tensorflow 官網可以看到, tensorflow 2.2.0 對應的是 bazel 2.0.0 。
# 310ba5ee72661c081129eb878c1bbcec936b20f0 is based on 3.8.0 with a fix for protobuf.bzl.
檢視需要的 bazel 版本
檢視需要的 protobuf 版本
【稍等,開始編譯之前還有一件事,編譯的時候會下載下傳很多包,其中可能會有包下載下傳不了的情況,會報以下錯誤。尤其llvm建議先下載下傳好,請自行百度搭建本地伺服器,更換相應檔案中的URL設定。具體方法放在本文最後,但建議提前按照這種方法準備好,因為llvm包比較大】
no such package '@llvm//' Error downloading
connected time out
開始編譯, 執行以下指令,過程需要下載下傳,全部下載下傳完畢之後,自動開始編譯,然後會生成 dll 檔案。過程……一兩個小時?如果下載下傳斷了就重新執行下面的指令。
bazel build //tensorflow:tensorflow_cc.dll
成功之後 會提示 [INFO: Build completed successfully, **** total actions],我就不重新編譯了……
接下來執行下面指令,編譯 lib 檔案,這個比較快。
bazel build //tensorflow:tensorflow_cc_dll_import_lib
輸出頭檔案,指令如下。
bazel build //tensorflow:install_headers
長時間的等待之後,就編譯好了。
debug版本的,在下面文章最後部分,不贅述了。
Windows10 Bazel 編譯 Tensorflow 2 C++ dll 和 lib 檔案
【大坑之 llvm】
如圖,複制其中白色部分,一定隻要白色部分,否則搜尋不到。複制之後打開 ./tensorflow/tensorflow/workspace.bzl 檔案,Ctrl+F 搜尋。或者在 workspace.bzl 檔案夾中搜尋LLVM。(不搜尋也行,直接複制後面我給的也可以,但其他版本的TensorFlow可能不一樣。)
除了llvm其他都還好,直接複制粘貼就能找到。如果 workspace.bzl 檔案中實在找不到的話,看看報錯資訊,也可能不在 workspace.bzl 檔案裡,總之方法都一樣。
387c3f74fd8efdc0be464b0e1a8033cc1eeb739c
#(直接複制下面連結,打開浏覽器,粘貼自動下載下傳 -_- 其他版本tensorflow請自行檢視workspace.bzl檔案)
https://github.com/llvm/llvm-project/archive/387c3f74fd8efdc0be464b0e1a8033cc1eeb739c.tar.gz
添加搭建好的本地伺服器下載下傳位址,本地伺服器就是做個網頁騙自己的電腦,從把自己指定的檔案夾中下載下傳好的檔案,通過本地伺服器搭建的本地網址“下載下傳”到 bazel需要的地方。
# Check out LLVM and MLIR from llvm-project.
LLVM_COMMIT = "387c3f74fd8efdc0be464b0e1a8033cc1eeb739c"
LLVM_SHA256 = "5648d1bdd933f45aa6556cf104b32a0418121ce6961f5f47e8ef5bc6e428434f"
LLVM_URLS = [ 【添加到下面位置,我就不費勁去重新做一個截圖了】
【看!】"https://本地伺服器/包名+字尾", 【記得兩邊的 "" 引文雙引号 以及 最後的英文逗号 [ , ]】
"https://storage.googleapis.com/mirror.tensorflow.org/github.com/llvm/llvm-project/archive/{commit}.tar.gz".format(commit = LLVM_COMMIT),
"https://github.com/llvm/llvm-project/archive/{commit}.tar.gz".format(commit = LLVM_COMMIT),
]
tf_http_archive(
name = "llvm-project",
sha256 = LLVM_SHA256,
strip_prefix = "llvm-project-" + LLVM_COMMIT,
urls = LLVM_URLS,
additional_build_files = {
clean_dep("//third_party/llvm:llvm.autogenerated.BUILD"): "llvm/BUILD",
"//third_party/mlir:BUILD": "mlir/BUILD",
"//third_party/mlir:test.BUILD": "mlir/test/BUILD",
},
)
tensorflow/tensorflow/workspace.bzl 檔案中,除了llvm(115.9mb)以外,還有boringssl(25.9mb)建議先下載下傳好。
另外還有 tensorflow/third_party/icu/workspace.bzl , icu(48.6mb)。
---未完待續---