June 30, 2018

Compiling TensorFlow using CMake

How to compile and link TensorFlow as a static library on Windows using CMake.

Introduction

This post demonstrates how to use CMake to compile TensorFlow as a static library and link to a Windows executable.

Prerequisites

  • Windows 10
  • Visual Studio 2017 15
  • Python 3.6
  • git
  • cmake 3.9

CMake File

The following CMake.txt file automates the process of compiling and linking to the TensorFlow libraries. It contains the minimum set of libraries required to build a Windows executable to consume TensorFlow for inference.

cmake_minimum_required (VERSION 3.8.1)
project (TENSORFLOWTEST)

set(TENSORFLOW_SOURCE_DIR tensorflow)
set(TENSORFLOW_BUILD_DIR ${TENSORFLOWTEST_SOURCE_DIR}/tensorflow/tensorflow/contrib/cmake/build)

include_directories(
	${TENSORFLOW_SOURCE_DIR}
	${TENSORFLOW_SOURCE_DIR}/tensorflow/contrib/cmake/build
	${TENSORFLOW_SOURCE_DIR}/tensorflow/contrib/cmake/build/external/eigen_archive
	${TENSORFLOW_SOURCE_DIR}/third_party/eigen3
	${TENSORFLOW_SOURCE_DIR}/tensorflow/contrib/cmake/build/protobuf/src/protobuf/src
)

# Suppress compiler warnings
add_definitions(/wd4267 /wd4244 /wd4554)

set(TENSORFLOWTEST_SRCS
	main.cpp
)

set(TENSORFLOWTEST_HDRS
	main.h
	class_name.h
)

add_executable(TENSORFLOWTEST ${TENSORFLOWTEST_SRCS} ${TENSORFLOWTEST_HDRS})

link_directories(${TENSORFLOW_BUILD_DIR})

target_link_libraries(TENSORFLOWTEST 
	${TENSORFLOW_BUILD_DIR}/zlib/install/lib/zlibstatic.lib
	${TENSORFLOW_BUILD_DIR}/gif/install/lib/giflib.lib
	${TENSORFLOW_BUILD_DIR}/png/install/lib/libpng16_static.lib
	${TENSORFLOW_BUILD_DIR}/lmdb/install/lib/lmdb.lib
	${TENSORFLOW_BUILD_DIR}/jsoncpp/src/jsoncpp/src/lib_json/$(Configuration)/jsoncpp.lib
	${TENSORFLOW_BUILD_DIR}/farmhash/install/lib/farmhash.lib
	${TENSORFLOW_BUILD_DIR}/fft2d/src/lib/fft2d.lib
	${TENSORFLOW_BUILD_DIR}/highwayhash/install/lib/highwayhash.lib
	${TENSORFLOW_BUILD_DIR}/protobuf/src/protobuf/$(Configuration)/libprotobuf.lib

	${TENSORFLOW_BUILD_DIR}/$(Configuration)/tf_protos_cc.lib
	${TENSORFLOW_BUILD_DIR}/tf_cc.dir/$(Configuration)/tf_cc.lib
	${TENSORFLOW_BUILD_DIR}/tf_cc_ops.dir/$(Configuration)/tf_cc_ops.lib
	${TENSORFLOW_BUILD_DIR}/tf_cc_framework.dir/$(Configuration)/tf_cc_framework.lib
	${TENSORFLOW_BUILD_DIR}/tf_core_cpu.dir/$(Configuration)/tf_core_cpu.lib
	${TENSORFLOW_BUILD_DIR}/tf_core_direct_session.dir/$(Configuration)/tf_core_direct_session.lib
	${TENSORFLOW_BUILD_DIR}/tf_core_framework.dir/$(Configuration)/tf_core_framework.lib
	${TENSORFLOW_BUILD_DIR}/tf_core_kernels.dir/$(Configuration)/tf_core_kernels.lib
	${TENSORFLOW_BUILD_DIR}/tf_core_lib.dir/$(Configuration)/tf_core_lib.lib
	${TENSORFLOW_BUILD_DIR}/tf_core_ops.dir/$(Configuration)/tf_core_ops.lib
	${TENSORFLOW_BUILD_DIR}/jpeg/install/lib/libjpeg.lib

	${TENSORFLOW_BUILD_DIR}/re2/install/lib/re2.lib
	${TENSORFLOW_BUILD_DIR}/nsync/src/nsync/$(Configuration)/nsync.lib
	${TENSORFLOW_BUILD_DIR}/snappy/src/snappy/$(Configuration)/snappy.lib
	${TENSORFLOW_BUILD_DIR}/sqlite/src/sqlite-build/$(Configuration)/sqlite.lib
	${TENSORFLOW_BUILD_DIR}/tf_cc_while_loop.dir/$(Configuration)/tf_cc_while_loop.lib

	${TENSORFLOW_BUILD_DIR}/double_conversion/src/double_conversion/double-conversion/$(Configuration)/double-conversion.lib
)

set_target_properties(TENSORFLOWTEST PROPERTIES LINK_FLAGS 
	"/ignore:4217 /ignore:4049
	/WHOLEARCHIVE:tf_cc.lib 
	/WHOLEARCHIVE:tf_core_cpu.lib
	/WHOLEARCHIVE:tf_core_framework.lib
	/WHOLEARCHIVE:tf_core_kernels.lib
	/WHOLEARCHIVE:tf_cc_framework.lib
	/WHOLEARCHIVE:tf_cc_ops.lib 	
	/WHOLEARCHIVE:tf_core_ops.lib 
	/WHOLEARCHIVE:tf_core_direct_session.lib
	/WHOLEARCHIVE:tf_core_lib.lib
	/WHOLEARCHIVE:libjpeg.lib"
)

Windows Batch File

The following Windows batch file automates the process of generating the Visual Studio project files and building the executable. It performs the following tasks:

  1. Updates the TensorFlow submodule
  2. Open an x64 Native Tools Command Prompt for VS2017
  3. Builds the tensorflow static libraries optimized for Intel AVX2
  4. Builds and links the example c++ application

Note: The initial build will take a long time. For example on an i7-6900k (8 core) CPU @3.2GHz and 64Gb RAM the above process takes around 40 minutes.

@echo off
setlocal
set PROJECT_ROOT=%CD%

set VISUAL_STUDIO_VERSION="Visual Studio 15 2017 Win64"
set CONFIGURATION="Release"

REM Update tensorflow submodule
chdir /d %PROJECT_ROOT% 
git submodule update --init

REM Set compiler environment
cd "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build"
call vcvarsall.bat amd64

REM Build tensorflow static libraries
echo Building tensorflow static libraries...
cd %PROJECT_ROOT%\tensorflow\tensorflow\contrib\cmake
IF EXIST build rd /S /Q build
mkdir build
cd build
cmake -Dtensorflow_BUILD_PYTHON_BINDINGS=OFF -Dtensorflow_ENABLE_GRPC_SUPPORT==OFF -Dtensorflow_BUILD_CC_EXAMPLE=OFF -Dtensorflow_WIN_CPU_SIMD_OPTIONS=/arch:AVX2 -Dtensorflow_DISABLE_EIGEN_FORCEINLINE=ON -G%VISUAL_STUDIO_VERSION% ..
msbuild.exe tensorflow.sln /t:Build /p:Configuration=%CONFIGURATION%;Platform=x64 /m

REM Build sample application
echo Building sample application...
cd %PROJECT_ROOT%
IF EXIST build rd /S /Q build
mkdir build
cd build
cmake -G%VISUAL_STUDIO_VERSION% ..
msbuild.exe TENSORFLOWTEST.sln /t:Build /p:Configuration=%CONFIGURATION%;Platform=x64 /m

echo All done

References

The following resources were used in developing this project: