【tensorflow C++】tensorflow1.8源码编译C++库包
最近用了一些时间来研究C++版本的tensorflow 当然官网没有提供现成的库包,只能自己根据原码编译。网上翻了一遍,发现资料很多但都相对较为零散,这边记录一下自己编译库包(Release和Debug版本)的流程以及自己踩的坑。
电脑环境
- win10
- VS2019
- cmake-3.20.1
- swigwin-4.0.2
- tensorflow-1.8.0
- python3.6(Anaconda)
编译时候会从git和一些国外网站在线下载一些依赖库包,所以提取要准备好高效上网的工具,否则一直处于time out状态。
CMAKE构建
在tensorflow-1.8.0\tensorflow\contrib\cmake路径下创建一个build文件夹,作为vs工程的生成目录。
修改cmakeList.txt文件:
找到 if (tensorflow_OPTIMIZE_FOR_NATIVE_ARCH) 的这一段代码,用下面的代码替换:
1 if (tensorflow_OPTIMIZE_FOR_NATIVE_ARCH) 2 include(CheckCXXCompilerFlag) 3 CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_OPT_ARCH_NATIVE_SUPPORTED) 4 if (COMPILER_OPT_ARCH_NATIVE_SUPPORTED) 5 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") 6 else() 7 CHECK_CXX_COMPILER_FLAG("/arch:AVX" COMPILER_OPT_ARCH_AVX_SUPPORTED) 8 if(COMPILER_OPT_ARCH_AVX_SUPPORTED) 9 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX") 10 endif() 11 endif() 12 endif()
设置 option(tensorflow_ENABLE_GRPC_SUPPORT "Enable gRPC support" ON) , 将其中的 $ ON $ 修改为 $ OFF $ 。否则在编译的时候会报错,很麻烦。
打开cmake GUI工具,将source code和build路径选择完成后,点击configure按钮,加载与项目相关的cmakeList.txt对应的配置。
加载后报错,是由于未设置swig executable所导致。选中已下载的swig.exe文件路径并添加。
对cmakeList.txt作如下配置,点击configure发现无报错,再点击generate生成vs项目文件。
打开生成的vs项目tensorflow.sln文件,对整个工程项目并作如下配置。
配置完成后,右键ALL_BUILD生成项目,此过程耗时比较长。在整个过程中,会出现各种问题,通常是因为网络问题,不能下载项目中需要的包,解决办法通常为启用高效上网工具,开启上网绿色通道。
在编译过程中,可能遇到的问题有:
1. 从GitHub上clone项目时候报【git early EOF】错误,导致项目生成失败。
解决办法为:找到对应项目的cmake文件,并在其中写入 git config --global core.compression 0
如在生成protobuf项目时出现了如题所述错误,则在\tensorflow-1.8.0\tensorflow\contrib\cmake\build\protobuf\tmp路径下,找到protobuf-gitclone.cmake文件,并在其中添加代码:
1 execute_process( 2 COMMAND "C:/Program Files/Git/cmd/git.exe" config --global core.compression 0 3 )
2.在编译过程中出现了OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443错误。
解决办法同1所述,在对应项目的cmake文件中写入:
1 execute_process( 2 COMMAND "C:/Program Files/Git/cmd/git.exe" config --global --unset http.proxy 3 COMMAND "C:/Program Files/Git/cmd/git.exe" config --global --unset https.proxy 4 )
3. Windows编译tensorflow时LINK : fatal error LNK1181: 无法打开输入文件“\pywrap_tensorflow_internal.lib错误。
出现这个错误是因为_beam_search_ops、 _gru_ops 、_lstm_ops、 _nearest_neighbor_ops、 _periodic_resample_op这几个工程的配置属性有问题,由于修改方法是一样的,所以这里以_beam_search_ops为例进行说明。
右键工程打开属性设置:
在链接器 -> 常规 -> 附加库目录里加入
$(SolutionDir)$(Configuration);
在链接器 -> 输入 -> 附件依赖项中将 \pywrap_tensorflow_internal.lib ,修改为 pywrap_tensorflow_internal.lib
重新编译这几个工程,然后再重新编译ALL_BUILD。
4. 若在编译过程中,遇到某些文件不能下载,或者下载路径不对的情况时,可以自行下载对应的文件放到 \tensorflow-1.8.0\tensorflow\contrib\cmake\build\downloads 路径下即可。如遇到eigen文件下载路径不存在的情况,则找到 tensorflow-1.8.0\tensorflow\contrib\cmake\build\eigen\src\eigen-stamp 路径下 download-eigen.cmake 文件,并将 "http://bitbucket.org/eigen/eigen/get/6913f0cf7d06.tar.gz" 替换为其镜像路径 "http://mirror.bazel.build/bitbucket.org/eigen/eigen/get/6913f0cf7d06.tar.gz" 即可(前提是需要高效上网的通路)。
提取安装包
编译完成之后,最后的一步是从十几个G的编译结果中提取安装包(install).在build文件夹下执行如下命令:
1 release: 2 cmake.exe -DBUILD_TYPE=Release -P cmake_install.cmake 3 4 debug: 5 cmake.exe -DBUILD_TYPE=Debug-P cmake_install.cmake
生成如下的安装文件
环境配置与常见问题
【C++环境配置】
- 右键项目属性>>配置属性>>VC++目录>>包含目录 && 库目录
- 右键项目属性>>配置属性>>C/C++>>预处理器>>预处理器定义,输入COMPILER_MSVC 和 NOMINMAX(否则会报错:“(”:“::”右边的非法标记应输入标记符)
- 右键项目属性>>配置属性>>链接器 >>附加依赖项,输入tensorflow.lib
【Question】找不到tensorflow.dll
【Solution】将已编译好的tensorflow的bin目录下 tensorflow.dll 复制到 debug/release目录下和*.exe一起
【Question】error C2143: 语法错误: 缺少“;”(在“<”的前面)
error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
error C2238: 意外的标记位于“;”之前
error C2039: "vector": 不是 "std" 的成员
【Solution】std::vector<Item> items = std::vector<Item>();宣布一个完整类型。因此编译器需要知道声明std::vector在这一点上(除其他事项外,它必须建立在编译时评估常量sizeof xxx)。
解决办法是在xxx.h的标头#include <vector>,而不是的源文件中。