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_第1张图片

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_第2张图片

vs2019编译快捷键_(踩坑)windows 用bazel编译 CPU tensorflow2.2.0的C++dll_第3张图片
用户变量

vs2019编译快捷键_(踩坑)windows 用bazel编译 CPU tensorflow2.2.0的C++dll_第4张图片
系统变量

【打开下载好的msys2,不是终端】

vs2019编译快捷键_(踩坑)windows 用bazel编译 CPU tensorflow2.2.0的C++dll_第5张图片
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_第6张图片

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_第7张图片
这货不是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_第8张图片
这货不是cmd
conda deactivate
python --version

执行之后,【注意】要退出 tf37 环境,检查一下 python 的版本是不是 3.7.* 。

vs2019编译快捷键_(踩坑)windows 用bazel编译 CPU tensorflow2.2.0的C++dll_第9张图片
这货不是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 ??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

vs2019编译快捷键_(踩坑)windows 用bazel编译 CPU tensorflow2.2.0的C++dll_第10张图片
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_第11张图片
查看需要的 bazel 版本

vs2019编译快捷键_(踩坑)windows 用bazel编译 CPU tensorflow2.2.0的C++dll_第12张图片
查看需要的 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_第13张图片

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

Windows10 Bazel 编译 Tensorflow 2 C++ dll 和 lib 文件

【大坑之 llvm】

如图,复制其中白色部分,一定只要白色部分,否则搜索不到。复制之后打开 ./tensorflow/tensorflow/workspace.bzl 文件,Ctrl+F 搜索。或者在 workspace.bzl 文件夹中搜索LLVM。(不搜索也行,直接复制后面我给的也可以,但其他版本的TensorFlow可能不一样。)

除了llvm其他都还好,直接复制粘贴就能找到。如果 workspace.bzl 文件中实在找不到的话,看看报错信息,也可能不在 workspace.bzl 文件里,总之方法都一样。

16a395d07604a2636bbe4c0dd373b35a.png

vs2019编译快捷键_(踩坑)windows 用bazel编译 CPU tensorflow2.2.0的C++dll_第14张图片
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)。

---未完待续---

你可能感兴趣的:(vs2019编译快捷键)