参考资料:在 Windows 环境中从源代码构建 | TensorFlow
错误解决参考资料:Win10下基于CPU的Tensorflow编译和c++/python调用——问题汇总_caoyin1234的博客-CSDN博客
从以上官网给出的参考资料确认构建配置的python、编译器MSVC 、构建工具bazel对应版本。
本人机器对应软件版本为:win10 + tensorflow2.5 + python3.6.0 + vs2019 + bazel-3.7.2+MSYS2。
开始:
一、下载安装必要的软件
vs2019:自然不用说,如果后期有提示版本不匹配的,在帮助——检测更新 升级即可。(可只安装除必选组件外的MSVC v142 - VS 2019 C++ x64/x86生成工具(选最新版本即可)和Windows 10 SDK(选最新版本即可))
bazel:Google 的一款可再生的代码构建工具,类似于Cmake。下载地址(注意对应的版本):Releases · bazelbuild/bazel · GitHub 在页面中找到 bazel-
,如:
bazel-3.7.2-windows-x86_64.exe
将下载的文件重命名为 bazel.exe
,并将其添加到你的计算机 %PATH%
环境变量中。打开cmd,输入bazel测试下看是否成功(注:添加环境变量记得重启计算机)。
MSYS2:用来获取构建 TensorFlow 所需的 bin 工具。下载地址:MSYS2
如果 MSYS2 已安装到 C:\msys64
下,请将 C:\msys64\usr\bin
添加到 计算机%PATH%
环境变量中。然后,使用 cmd.exe
运行以下命令:
pacman -S git patch unzip
python3.6:下载地址:Python Release Python 3.6.0 | Python.org。下载后默认安装即可。
安装 TensorFlow pip 软件包依赖项:
pip3 install six numpy wheel
pip3 install keras_applications==1.0.6 --no-deps
pip3 install keras_preprocessing==1.0.5 --no-deps
下载TensorFlow 官方源码(注意对应版本):https://github.com/tensorflow/tensorflow/releases
我的系统环境变量:Path
C:\msys64\usr\bin
D:\WorkSpace\SDK\bazel
libiomp5md.dll
二、 进行bazel源码编译
1. 配置build
cd tensorflow-master
python ./configure.py
Would you like to override eigen strong inline for some C++ compilation to reduce the compilation time? [Y/n]: Y
2. 编译修改
从2.4开始TensorFlow将MKL用到的OpenMP从直接下载二进制可执行文件变为了从LLVM项目下载开源代码并编译,带来了一系列问题。解决:安装LLVM(安装时写入系统环境变量),下载地址:LLVM Download Page 。
用现成的libiomp5md.lib和libiomp5md.dll取代编译过程,MSVC编译LLVM的OpenMP会出错。
将LLVM用到的DLL(在LLVM安装目录\bin下)复制到msys安装目录\usr\bin下,否则在后续编译步骤中使用msys里的bash时没有复制系统环境变量的Path会报错(比如编译Lite相关内容时会报找不到api-ms-win-crt-locale-l1-1-0.dll的错)。
将libiomp5md.lib放到third_party\mkl目录下,并在third_party\mkl\mkl.BUILD的第75行后插入:
cc_import(
name = "iomp5",
interface_library = "libiomp5md.lib",
system_provided = 1,
)
将下方Windows编译配置修改为:
cc_library(
name = "mkl_libs_windows",
deps = [
"iomp5"
],
visibility = ["//visibility:public"],
)
将libiomp5md.dll放到系统环境变量里。
将third_party\llvm_openmp\BUILD第74行修改为0,取消强制使用MSVC:
omp_vars_win = {
"MSVC": 0,
}
将LLVM的libiomp5md.dll放到python.exe同目录下。
修改.bazelrc的第559行:
build:release_gpu_base --repo_env=TF_CUDA_COMPUTE_CAPABILITIES="sm_35,sm_50,sm_60,sm_70,sm_75,compute_80,compute_86"
3. bazel编译生成
bazel编译生成whl:
1.编译:
bazel build --jobs 12 --config=opt --cxxopt=-std=c++11 --copt=-nvcc_options=disable-warnings --define=no_tensorflow_py_deps=true //tensorflow/tools/pip_package:build_pip_package --local_ram_resources=6144
2.生成:bazel-bin\tensorflow\tools\pip_package\build_pip_package C:/tmp/tensorflow_pkg
## --jobs:用来指定CPU工作核数
## --local_ram_resources:用来工作的内存大小
## --definen=no_tensorflow_py_deps=true,表示编译不产生debug二进制文件
以上参数都可以忽略默认
注意:编译的过程可能会很长,千万不要以为有问题就Ctrl C
了(分2个过程:下中间资源+编译),编译完成后会出现: Build completed successfully。(出现错误,提示“cannot find zipfile directory in one of ./bazel-bin/tensorflow/tools/pip_package/simple_console_for。。。。”,执行:pacman -Syu zip unzip)
bazel编译动态链接库dll命令(这一步可能会出现:“..\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\complex(672): error C2039: "copysign": 不是 "`global namespace'" 的成员”,将vs2017对应下的complex文件拷过来覆盖即可(不要试图解决命名空间问题,没用!照我说的做,考过了、覆盖——md,血的教训!);提示:"找不到"windows.h",执行:pip3 install lxml --upgrade)
bazel build --jobs 12 --config=opt --copt=-nvcc_options=disable-warnings --define=no_tensorflow_py_deps=true //tensorflow:tensorflow_cc.dll
同理编译lib:
bazel build --jobs 12 --config=opt --copt=-nvcc_options=disable-warnings //tensorflow:tensorflow_cc_dll_import_lib
bazel build --config=opt //tensorflow:install_headers
编译好的路径:
whl:C:/tmp/tensorflow_pkg
dll:\bazel-bin\tensorflow\tensorflow_cc.dll
lib:\bazel-bin\tensorflow\tensorflow_cc.lib
include:\bazel-bin\tensorflow\include
注意:1. 这里编译的是tensorflow的release版本,因此构建项目的时候把环境从debug变成release;2. 在新建项目属性表(这里无论是opencv还是tensorflow)中,要选择release版本的x64(64位)
pip3 install C:/tmp/tensorflow_pkg/tensorflow-2.5.0-cp36-cp36m-win_amd64.whl
├── tf_test// 整个项目
├── x64 // 这里是生成解决方案得到的
├── tf // 这里存放所有编译好的文件
├──bin // 存放dll动态库文件
├──tensorflow_cc.dll
├──lib // 存放静态库文件
├──tensorflow_cc.lib
├──include // 直接是tensorflow编译好的include目录
├──main.cpp
#include
#include
#include
#include"tensorflow/core/public/session.h"
#include"tensorflow/core/platform/env.h"
using namespace std;
using namespace tensorflow;
using namespace cv;
int main()
{
Session* session;
Status status = NewSession(SessionOptions(), &session);
if (!status.ok()) {
std::cout << status.ToString() << std::endl;
}
else {
std::cout << "Session created successfully" << std::endl;
}
cout << "Session successfully created.\n";
getchar();
return 0;
}
生成解决方案的时候报错Link1120:
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2001 无法解析的外部符号 "public: __cdecl tensorflow::TensorShapeBase::TensorShapeBase(class absl::lts_20210324::Span<__int64 const >)" (??NewSession@tensorflow@@YA?AVStatus@1@AEBUSessionOptions@1@PEAPEAVSession@1@@Z) tf_test D:\WorkSpace\WorkGroup\DeepLearning\DEMO\tf_test\tf_test\tf_test\tf_test.obj 1
解决办法:进入tensorflow-master\tensorflow\tools\def_file_filter,编辑def_file_filter.py.tpl文件,将错误按下格式添加:
# Header for the def file. (找到这一行代码)
if args.target:
def_fp.write("LIBRARY " + args.target + "\n")
def_fp.write("EXPORTS\n")
def_fp.write("\t ??1OpDef@tensorflow@@UEAA@XZ\n")
# 下面两个就是复制的错误信息
def_fp.write("\t ?NewSession@tensorflow@@YA?AVStatus@1@AEBUSessionOptions@1@PEAPEAVSession@1@@Z\n")
def_fp.write("\t ??0SessionOptions@tensorflow@@QEAA@XZ\n")
最后重新编译DLL,头文件!!!
有太多的错误导致IntelliSense引擎无法正常工作,其中有些错误无法在编辑器屏蔽,可:
解决方式:在项目->属性->配置属性->C/C+±>预处理器->预处理器定义中加入_XKEYCHECK_H