在获得libtensorflow_cc.so和libtensorflow_framework.so库后,开始进行C++api开发
-
编写源文件
源文件:test.cc
#include "/home/zhouxd/tools/tensorflow-master/tensorflow/core/public/session.h"
//tensorflow-master为tensorflow源码根目录,不喜欢include这么长的路径可以把这个路径加到cmakelist,再直接包含session.h
#include <iostream>
using namespace std;
using namespace tensorflow;
int main()
{
//仅仅为了测试Session对象能否成功建立
Session* session;
Status status = NewSession(SessionOptions(), &session);
if (!status.ok()) {
cout << status.ToString() << "\n";
return 1;
}
cout << "Session successfully created.\n";
}
该例子的任务是新建一个Session并判断是否成功创建。
- CMakeLists.txt
cmake_minimum_required (VERSION 2.8.8)
project (tf_test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++11 -W")
link_directories(./lib)
include_directories(
/home/zhouxd/tools/tensorflow-master
/home/zhouxd/tools/tensorflow-master/bazel-genfiles
/home/zhouxd/tools/Eigen3
/home/zhouxd/tools/protobuf_bin/include
/home/zhouxd/tools/nsync-1.20.0/public
)
add_executable(tf_test test.cc)
target_link_libraries(tf_test tensorflow_cc tensorflow_framework)
说明:
- link_directories(./lib) 指定好so文件的路径,这里我新建了lib文件夹把so文件放进去了
- link_directories所指路径是编译好的tensorflow动态库的路径
- tensorflow-master是tensorflow的源码路径
- Eigen3是Eigen3的目录
- nsync-1.20.0是nsync的安装目录
- protobuf_bin是protobuf的安装目录,tensorflow用到了protobuf,如果不包含这个路径,编译的时候不会提示缺少某头文件,而是会提示某某头文件的版本不对。一般来说,在安装protobuf时已经将这个路径加到环境变量中了,此时在开发环境中不加也没关系,但如果要转移到其他环境,就需要拷贝这个目录并包含。
有意思的是,通过tensorflow源码也能生成这个目录,在源码的tensorflow/contrib/makefile目录下,找到build_all_xxx.sh文件并执行(不要用sh命令,直接执行),成功后会出现一个gen文件夹,gen文件下面也有个protobuf/include文件夹,包含这个文件夹也是可以的。
- bazel-genfiles是在用bazel编译tensorflow时在源码目录下生成的文件夹指向链接,它指向了另一个目录,这个目录也是在编译tensorflow时生成的,我的机器上是
/home/zhouxd/.cache/bazel/_bazel_zhouxd/3ea11f2719d18e25c3b1b9955bf36e24/execroot/org_tensorflow/bazel-out/k8-opt/genfiles/
可以看到该路径是在用户根目录下生成的,有意思的一点是该目录下也有一个tensorflow文件夹,就像源码目录(tensorflow-master)下存在一个tensorflow文件夹放置一些头文件一样,这个文件夹下则有许多在编译动态库时生成的头文件,这些对c++ api来说必不可缺的。
在编译的时候,程序会从源码目录下的tensorflow文件夹里寻找所需头文件,同时也会从该目录下的tensorflow文件夹里寻找文件。
值得注意的是,在程序打包或迁移环境的时候很容易会忘掉这个文件夹,造成头文件缺失,往往是该文件没有拷贝走,bazel-genfiles指不到地方,打包时可以把该目录下的tensorflow目录与源码的tensorflow目录合并。这样include一个文件夹即可。同样的,其他依赖库的头文件在打包时也要注意是否存在,可以把这些目录单独拷贝出来整理。
- 编译
mkdir build
cd ./build
cmake ..
make
执行生成的tf_test,输出Session successfully created.即表示成功