首先,感谢各位前辈的分享。搜索到的教程、文章太多,没有全部记录下来,很抱歉不能一一感谢,一开始也没想到能写这么一篇文,以后注意…
【目前只编译出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开)发包
注意,我自己的电脑只有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 文件拖入进去,然后回车执行。
这货不是cmdconda 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 一劳永逸
[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需要的各种包,就全都安排了。
(辛苦辛苦,喝口水歇一歇)
其实还是要继续下载。下面的跳过,直接开始编译,编译成功之后在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 ??1OpDef@tensorflow@@UEAA@XZn")
def_fp.write("t ?NewSession@tensorflow@@YAPEAVSession@1@AEBUSessionOptions@1@@Zn")
def_fp.write("t ??0SessionOptions@tensorflow@@QEAA@XZn")
def_fp.write("t ??0ReadFile@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@@Zn")
def_fp.write("t ??0ExpandDims@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@1@Zn")
def_fp.write("t ??0Cast@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@W4DataType@2@@Zn")
def_fp.write("t ??0DecodeJpeg@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@AEBUAttrs@012@@Zn")
def_fp.write("t ??0Operation@tensorflow@@QEAA@PEAVNode@1@@Zn")
def_fp.write("t ?WithOpNameImpl@Scope@tensorflow@@AEBA?AV12@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Zn")
def_fp.write("t ?ToGraphDef@Scope@tensorflow@@QEBA?AVStatus@2@PEAVGraphDef@2@@Zn")
def_fp.write("t ?NewRootScope@Scope@tensorflow@@SA?AV12@XZn")
def_fp.write("t ??1Scope@tensorflow@@QEAA@XZn")
def_fp.write("t ?Run@ClientSession@tensorflow@@QEBA?AVStatus@2@AEBV?$vector@VOutput@tensorflow@@V?$allocator@VOutput@tensorflow@@@std@@@std@@PEAV?$vector@VTensor@tensorflow@@V?$allocator@VTensor@tensorflow@@@std@@@5@@Zn")
def_fp.write("t ??1ClientSession@tensorflow@@QEAA@XZn")
def_fp.write("t ??0ClientSession@tensorflow@@QEAA@AEBVScope@1@@Zn")
def_fp.write("t ?LoadSavedModel@tensorflow@@YA?AVStatus@1@AEBUSessionOptions@1@AEBVRunOptions@1@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$unordered_set@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U?$hash@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@U?$equal_to@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@6@QEAUSavedModelBundle@1@@Zn")
def_fp.write("t ??1SavedModelBundleInterface@tensorflow@@UEAA@XZn")
def_fp.write("t ??0CombinedNonMaxSuppression@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@11111AEBUAttrs@012@@Zn")
def_fp.write("t ??0CombinedNonMaxSuppression@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@11111@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
??0MetaGraphDef@tensorflow@@QEAA@XZ
??1MetaGraphDef@tensorflow@@UEAA@XZ
??0LogMessageFatal@internal@tensorflow@@QEAA@PEBDH@Z
??1LogMessageFatal@internal@tensorflow@@UEAA@XZ
?CheckDimsEqual@TensorShape@tensorflow@@AEBAXH@Z
?CheckDimsAtLeast@TensorShape@tensorflow@@AEBAXH@Z
??0Tensor@tensorflow@@QEAA@XZ
??0GraphDef@tensorflow@@QEAA@XZ
??1GraphDef@tensorflow@@UEAA@XZ
?CheckType@Tensor@tensorflow@@AEBAXW4DataType@2@@Z
?CopyFromInternal@Tensor@tensorflow@@AEAAXAEBV12@AEBVTensorShape@2@@Z
??1NodeDef@tensorflow@@UEAA@XZ
??0NodeDef@tensorflow@@QEAA@AEBV01@@Z
??0RunOptions@tensorflow@@QEAA@XZ
??1RunOptions@tensorflow@@UEAA@XZ
?IgnoreError@Status@tensorflow@@QEBAXXZ
?LoadSavedModel@tensorflow@@YA?AVStatus@1@AEBUSessionOptions@1@AEBVRunOptions@1@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$unordered_set@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U?$hash@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@U?$equal_to@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@6@QEAUSavedModelBundle@1@@Z
?NewSession@tensorflow@@YAPEAVSession@1@AEBUSessionOptions@1@@Z
cd 到 已经转换成 2.2.0 版本的 tensorflow 文件夹,执行以下指令,开始配置。
python 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.
【稍等,开始编译之前还有一件事,编译的时候会下载很多包,其中可能会有包下载不了的情况,会报以下错误。尤其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)。
---未完待续---