https://github.com/cjweeks/tensorflow-cmake
update cmake:
wget http://www.cmake.org/files/v3.4/cmake-3.4.1.tar.gz
tar -xvf cmake-3.4.1.tar.gz
./configure
make && make install
export CMAKE_ROOT=$HOME/local/share/cmake-3.4
tensorflow-cmake
Integrate TensorFlow with CMake projects effortlessly.
TensorFlow
TensorFlow is an amazing tool for machine learning and intelligence using computational graphs.TensorFlow includes APIs for both Python and C++, although the C++ API is slightly less documented. However, the most standardway to integrate C++ projects with TensorFlow is to build the projectinside the TensorFlow repository, yielding a massive binary.Additionally,Bazel is the only certified way to build such projects. This document and the code in thisrepository will allow one to integrate TensorFlow with CMake projects without producing a large binary.
Note: The instructions here correspond to an Ubuntu Linux environment; although some commands may differ for other operating systems and distributions, the general ideas are identical.
Step 1: Install TensorFlow
Follow the instructions for installing Bazel. Install dependencies and cloneTensorFlow from its git repository:
sudo apt-get install autoconf automake libtool curl make g++ unzip # Protobuf Dependencies
sudo apt-get install python-numpy swig python-dev python-wheel # TensorFlow Dependencies
git clone https://github.com/tensorflow/tensorflow # TensorFlow
Enter the cloned repository, and append the following to the tensorflow/BUILD
file:
# Added build rule
cc_binary(
name = "libtensorflow_all.so",
linkshared = 1,
linkopts = ["-Wl,--version-script=tensorflow/tf_version_script.lds"],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core:framework_internal",
"//tensorflow/core:tensorflow",
],
)
This specifies a new build rule, producing libtensorflow_all.so
, that includes all the required dependencies for integrationwith a C++ project. Build the shared library and copy it to/usr/local/lib
as follows:
./configure # Note that this requires user input
bazel build tensorflow:libtensorflow_all.so
sudo cp bazel-bin/tensorflow/libtensorflow_all.so /usr/local/lib
Copy the source to /usr/local/include/google
and remove unneeded items:
sudo mkdir -p /usr/local/include/google/tensorflow
sudo cp -r tensorflow /usr/local/include/google/tensorflow/
sudo find /usr/local/include/google/tensorflow/tensorflow -type f ! -name "*.h" -delete
Copy all generated files from bazel-genfiles:
sudo cp bazel-genfiles/tensorflow/core/framework/*.h /usr/local/include/google/tensorflow/tensorflow/core/framework
sudo cp bazel-genfiles/tensorflow/core/kernels/*.h /usr/local/include/google/tensorflow/tensorflow/core/kernels
sudo cp bazel-genfiles/tensorflow/core/lib/core/*.h /usr/local/include/google/tensorflow/tensorflow/core/lib/core
sudo cp bazel-genfiles/tensorflow/core/protobuf/*.h /usr/local/include/google/tensorflow/tensorflow/core/protobuf
sudo cp bazel-genfiles/tensorflow/core/util/*.h /usr/local/include/google/tensorflow/tensorflow/core/util
sudo cp bazel-genfiles/tensorflow/cc/ops/*.h /usr/local/include/google/tensorflow/tensorflow/cc/ops
Copy the third party directory:
sudo cp -r third_party /usr/local/include/google/tensorflow/
sudo rm -r /usr/local/include/google/tensorflow/third_party/py
sudo rm -r /usr/local/include/google/tensorflow/third_party/avro
Step 2: Install Eigen and Protobuf
The TensorFlow runtime library requires both Protobuf and Eigen.However, specific versions are required, and these may clash with currently installed versions of either software. Therefore, two options areprovided:
- Install the packages to a directory on your computer, which will overwrite / clash with any previous versions installed in that directory (but allow multiple projects to reference them).The default directory is
/usr/local
, but any may be specified to avoid clashing. This is the recommended option. - Add the packages as external dependencies, allowing CMake to download and build them inside the project directory, not affecting any current versions. This will never result in clashing,but the build process of your project may be lengthened.
Choose the option that best fits your needs; you may mix these options as well, installing one to/usr/local
, while keeping the other confined in the current project. In the following instructions, be sure to replace<EXECUTABLE_NAME>
with the name of your executable. Additionally, all generated CMake files should generally be placed in your CMake modules directory, which is commonly<PROJECT_ROOT>/cmake/Modules
.
Eigen: Installing Locally
Execute the eigen.sh
script as follows: sudo eigen.sh install <tensorflow-root> [<install-dir> <download-dir>]
. Theinstall
command specifies that Eigen is to be installed to a directory. The<tensorflow-root>
argument should be the root of the TensorFlow repository. The optional<install-dir>
argument allows you to specify the installation directory;this defaults to/usr/local
but may be changed to avoid other versions. The<download-dir
argument specifies the directory where Eigen will be download and extracted; this defaultsto the current directory.
To generate the needed CMake files for your project, execute the script as follows:eigen.sh generate installed [<cmake-dir> <install-dir>]
. Thegenerate
command specifies that the required CMake files are to be generated and placed in<cmake-dir>
(this defaults to the current directory, but generally should your CMake modules directory). The optional<install-dir>
argument specifies the directory Protobuf is installed to. This defaults to/usr/local
and should directly correspond to the install directory specified when installing above. Two fileswill be copied to the specified directory:FindEigen.cmake
andEigen_VERSION.cmake
. Add the following to yourCMakeLists.txt
:
# Eigen
find_package(Eigen REQUIRED)
include_directories(${Eigen_INCLUDE_DIRS})
Eigen: Adding as External Dependency
Execute the eigen.sh
script as follows: eigen.sh generate external <tensorflow-root> [<cmake-dir>]
. Theexternal
command specifies that Eigen is notinstalled, but rather should be treated as an external CMake dependency. The<tensorflow-root>
argument again should be the root directory of the TensorFlow repository,and the optional<cmake-dir>
argument is the location to copy the required CMake modules to (defaults to the current directory). Two files will be copiedto the specified directory:Eigen.cmake
and Eigen_VERSION.cmake
. Add the following to yourCMakeLists.txt
:
# Eigen
include(Eigen)
add_dependencies(<EXECUTABLE_NAME> Eigen)
Protobuf: Installing Locally
Execute the protobuf.sh
script as follows: sudo protobuf.sh install <tensorflow-root> [<cmake-dir>]
. The arguments are identical to those described in the Eigensection above.
Generate the required files as follows: protobuf.sh generate installed [<cmake-dir> <install-dir>]
; the arguments are also identical to those above. Two files will be copied to the specified directory:FindProtobuf.cmake
andProtobuf_VERSION.cmake
. CMake provides us with aFindProtobuf.cmake
module, but we will use our own, since we must specify the directory Protobuf was installed to. Add the following to yourCMakeLists.txt
:
# Protobuf
find_package(Protobuf REQUIRED)
include_directories(${Protobuf_INCLUDE_DIRS})
target_link_libraries(<EXECUTABLE_NAME> ${Protobuf_LIBRARIES})
Protobuf: Adding as External Dependency
Execute the protobuf.sh
script as follows: protobuf.sh generate external <tensorflow-root> [<cmake-dir>]
. The arguments are also identical to those described in the Eigensection above. Two files will be copied to the specified directory:Protobuf.cmake
and Protobuf_VERSION.cmake
. Add the following to yourCMakeLists.txt
:
# Protobuf
include(Protobuf)
add_dependencies(<EXECUTABLE_NAME> Protobuf)
Step 3: Configure the CMake Project
Edit your CMakeLists.txt
to append your custom modules directory to the list of CMake modules (this is a common step in most CMake programs):
list(APPEND CMAKE_MODULE_PATH <CMAKE_MODULE_DIR>)
# Replace <CMAKE_MODULE_DIR> with your path
# The most common path is ${PROJECT_SOURCE_DIR}/cmake/Modules
If either Protobuf or Eigen was added as an external dependency, add the following to yourCMakeLists.txt
:
# Specify download location
set (DOWNLOAD_LOCATION "${PROJECT_SOURCE_DIR}/external/src"
CACHE PATH "Location where external projects will be downloaded")
mark_as_advanced(DOWNLOAD_LOCATION)
The projects in the examples/
directory demonstrate the correct usage of these instructions.
Troubleshooting
Compiler Path Build Error
If Bazel fails to build the TensorFlow library, stating error: Could not find compiler "gcc" in PATH
, you may have to execute the following:
bazel clean # Clean project
export CC="/usr/bin/gcc" # Set location of C compiler
export CXX="/usr/bin/g++" # Set location of C++ compiler
bazel build tensorflow:libtensorflow_all.so # Rebuild project
Makefile with contrib/Makefile
1 tensorflow/core/platform/env.cc:304:9: error: conflicting return type specified for ‘virtual tensorflow::int64 tensorflow::{anonymous}::FileStream::ByteCount() const’
由于protobuf版本问题引起,需要尝试其它branch
eigen problem
download eigen from https://bitbucket.org/eigen/eigen/
tar -xvf and cpy to contrib/cmake_build/eigen/src/eigen