天天看點

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

首先,感謝各位前輩的分享。搜尋到的教程、文章太多,沒有全部記錄下來,很抱歉不能一一感謝,一開始也沒想到能寫這麼一篇文,以後注意…

【目前隻編譯出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 生成工具,但不用另外下載下傳安裝生成工具……但還是都安裝吧。

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

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版本。

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll
vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

使用者變量

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

系統變量

【打開下載下傳好的msys2,不是終端】

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

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
           
vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

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 的分享)。

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

這貨不是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 檔案拖入進去,然後回車執行。

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

這貨不是cmd

conda deactivate
python --version
           

執行之後,

【注意】要退出 tf37 環境,

檢查一下 python 的版本是不是 3.7.* 。

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

這貨不是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 一勞永逸

  1. 找到系統盤下C:C:Users使用者名AppDataRoaming
  2. 檢視在Roaming檔案夾下有沒有一個pip檔案夾,如果沒有建立一個;
  3. 進入pip檔案夾,建立一個pip.ini檔案;
  4. 使用記事本的方式打開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
           
vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

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.
           
vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

檢視需要的 bazel 版本

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

檢視需要的 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
           

長時間的等待之後,就編譯好了。

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll

debug版本的,在下面文章最後部分,不贅述了。

Windows10 Bazel 編譯 Tensorflow 2 C++ dll 和 lib 檔案

【大坑之 llvm】

如圖,複制其中白色部分,一定隻要白色部分,否則搜尋不到。複制之後打開 ./tensorflow/tensorflow/workspace.bzl 檔案,Ctrl+F 搜尋。或者在 workspace.bzl 檔案夾中搜尋LLVM。(不搜尋也行,直接複制後面我給的也可以,但其他版本的TensorFlow可能不一樣。)

除了llvm其他都還好,直接複制粘貼就能找到。如果 workspace.bzl 檔案中實在找不到的話,看看報錯資訊,也可能不在 workspace.bzl 檔案裡,總之方法都一樣。

vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll
vs2019編譯快捷鍵_(踩坑)windows 用bazel編譯 CPU tensorflow2.2.0的C++dll
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)。

---未完待續---