需要将tensorflow从源码编译为静态库
参考教程:
https://blog.csdn.net/carbon06/article/details/82632781【教程1】
https://www.tensorflow.org/install/source?hl=zh-cn【教程2】
https://zhuanlan.zhihu.com/p/91869397【教程3】
https://zhuanlan.zhihu.com/p/57275506【教程4,通过bazel(据说不能编译静态库)】
发现新版本的tensorflow没有教程中提到的contrib文件夹,git checkout r1.14 切换回旧版本的tensorflow
在tensorflow/contrib/makefile文件夹下运行./build_all_linux.sh
报错,通过官方的教程2发现应该使用低版本的GCC(系统上本身版本为10.0),切换为GCC4.8.5
再次尝试编译,发现之前的错误可以通过,但报出新的错误,是glibc版本的问题
通过 ldd /bin/ls可以查看当前的库的路径(https://bbs.csdn.net/topics/310067175)
通过/lib/libc.so.6可以查看其版本(https://blog.csdn.net/yaoike/article/details/4263185)
通过strings /usr/lib64/libstdc++.so.6|grep GLIBCXX可以查看其详细信息
常见修改方式:删除原来的软连接,替换为新的软连接,但考虑到会破坏系统环境,我无法直接采用这种方式
最后成功方式,推测是通过LD_LIBRARY_PATH,发现不通过~/.bashrc 修改环境变量,仅修改GCC版本为低版本时,就可以成功编译
按照教程1进行测试
【问题1】教程1中为macos,此处为linux所以教程中的拷贝路径 tensorflow/contrib/makefile/downloads/nsync/builds/default.macos.c++11/libnsync.a
替换为default.linux.c++11/libnsync.a
【问题2】继续按照教程1测试,发现路径存在问题:tf_debug/load_model.cpp:4:10: fatal error: tensorflow/include/core/public/session.h: No such file or directory
教程1中此处应该有误,core应该放在include/tensorflow下,而不是include下,修改路径后不再报此错误
# include 路径存放tensorflow主要头文件
mkdir -p ~/tensorflow_libs/tensorflow/include/tensorflow
# 拷贝tensorflow 主要头文件
cp -r tensorflow/core ~/tensorflow_libs/tensorflow/include
【问题3】之后报新错:make[2]: *** No rule to make target `../tensorflow/nsync/lib/libnsync.a', needed by `load_model'. Stop.
发现教程1中,CMakelist.txt里libnsync.a路径有误,不存在它所写的路径,TENSORFLOW_NSYNC_LIBRARY_PATH要与上面拷贝时路径一致
【问题4】链接时报大量错误:发现是链接多个静态库的顺序错误,A依赖B,则B应该在后面(教程1的顺序全部颠倒即可)
https://zhuanlan.zhihu.com/p/259893540?utm_source=wechat_session
【问题5】链接时报错:load_library.cc:(.text+0x121): undefined reference to `dlerror' 等类似错误
解决:在编译时加上选项:-ldl 即可
【问题6】链接时报错:undefined reference to `tensorflow::Status::ToString[abi:cxx11]() const'
解决:加上选项 -D_GLIBCXX_USE_CXX11_ABI=0即可
解决以上问题后教程1样例编译通过,运行时发现新的问题
【问题1】E tensorflow/core/common_runtime/session.cc:75] Not found: No session factory registered for the given session options: {target: "" config: } Registered factories are {}.
报错原因参考1:https://blog.csdn.net/gaussrieman123/article/details/106384853(动态库隐式加载的情况下一些全局静态变量没有初始化)
报错原因参考2:https://blog.csdn.net/weixin_30877493/article/details/96867587(采用这种方式解决了问题)
参考2中提到编译时需要添加参数 whole-archive
将指令修改为
TARGET_LINK_LIBRARIES(load_model -Wl,--whole-archive ${TENSORFLOW_LIBARY} -Wl,--no-whole-archive ${LOAD_MODEL_LIBRARIES} ${CMAKE_CXX_FLAGS})
此外还需要添加-lpthread选项
修改CMakelists.txt后重新编译,不再报以上错误
运行成功得到教程1中的三行输出