Cmake tensorflow and protofbuf CPP

Hello everybody,
I am a newbie trying to use Tensorflow_cc to predict data from model “.pd” in ML.
My example2.cpp is quite simple

#include <tensorflow/core/platform/env.h>
#include <tensorflow/core/public/session.h>
#include <tensorflow/cc/saved_model/loader.h>
#include <tensorflow/cc/saved_model/tag_constants.h>

#include <iostream>
using namespace std;
using namespace tensorflow;
int main(){

  
    tensorflow::SessionOptions sessionOptions;
    tensorflow::RunOptions runOptions;
    SavedModelBundle model; // Lead to error 
 
}

this is my CmakeLists.txt

cmake_minimum_required(VERSION 3.9)
project(your_project_name)

# Find TensorFlow C++ package
find_package(TensorflowCC REQUIRED)
# Find Protobuf package
find_package(Protobuf REQUIRED)

# Add your source files
add_executable(example example2.cpp)

# Add the TensorFlow and Protobuf include directories
target_include_directories(example PRIVATE ${TensorflowCC_INCLUDE_DIRS})
target_include_directories(example PRIVATE ${PROTOBUF_INCLUDE_DIRS})
CXXFLAGS = -DGOOGLE_PROTOBUF_ARCH_X64 -DHAVE_THREAD
# Link against TensorFlow C++ and Protobuf libraries
target_link_libraries(example PRIVATE TensorflowCC::TensorflowCC ${PROTOBUF_LIBRARIES}) # 

But I still faces error

/usr/bin/ld: CMakeFiles/example.dir/example2.cpp.o: in function `google::protobuf::internal::MapField<tensorflow::MetaGraphDef_SignatureDefEntry_DoNotUse, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, tensorflow::SignatureDef, (google::protobuf::internal::WireFormatLite::FieldType)9, (google::protobuf::internal::WireFormatLite::FieldType)11, 0>::GetMap() const':
example2.cpp:(.text._ZNK6google8protobuf8internal8MapFieldIN10tensorflow39MetaGraphDef_SignatureDefEntry_DoNotUseENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_12SignatureDefELNS1_14WireFormatLite9FieldTypeE9ELSD_11ELi0EE6GetMapEv[_ZNK6google8protobuf8internal8MapFieldIN10tensorflow39MetaGraphDef_SignatureDefEntry_DoNotUseENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS3_12SignatureDefELNS1_14WireFormatLite9FieldTypeE9ELSD_11ELi0EE6GetMapEv]+0x18): undefined reference to `google::protobuf::internal::MapFieldBase::SyncMapWithRepeatedField() const'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/example.dir/build.make:98: example] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/example.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

It took me many days to suffer from this problem.
Any one can give me some suggestion?
Thank you so much.

Could it be that there is still some linking missing, such as perhaps ${PROTOBUF_LIBRARIES} doesn’t contain the full list of required libraries? Or something inside TensorFlow does not include map_field.h header (so it’s a bug of TensorFlow).

Sometimes the linking order might play some role too.

I have no idea really, just trying to save you some days :slight_smile:

1 Like

This is invalid CMake code. Is this supposed to be in a comment? I think you want:

target_compile_definitions(example PRIVATE GOOGLE_PROTOBUF_ARCH_X64 HAVE_THREAD)

instead.

<linking error>

Is there some mismatch between the protobuf your project is finding and the one TensorflowCC found?

You right, it should be in a comment.
Second, I do not know how to find if there is some mismatch between the protobuf and TensorflowCC

If you built TensorflowCC, check its build settings that it is using the /usr/local version (since it co-exists there, it should be the preferred one). Then make sure your project is doing the same.

1 Like

Hi Ben, thanks for your reply. Could you please guide me where I can check build settings using /usr/local ? Below is the CMakeLists.txt when I build Tensorflow_cc.

cmake_minimum_required(VERSION 3.7 FATAL_ERROR)
cmake_policy(SET CMP0048 NEW)  # Enable version parameter in project().
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/PROJECT_VERSION" version)
project(
  "tensorflow_cc"
  VERSION ${version}
)

option(ALLOW_CUDA "Try to find and use CUDA." ON)
option(REQUIRE_CUDA "Make sure to find and use CUDA (implies ALLOW_CUDA)." OFF)
set(LOCAL_RAM_RESOURCES 4096 CACHE STRING "The amount of local RAM resources passed to bazel scheduler (e.g., 4096).")
set(LOCAL_CPU_RESOURCES HOST_CPUS CACHE STRING "The amount of local CPU cores passed to bazel scheduler (e.g., 2).")
set(TENSORFLOW_TAG "v${version}" CACHE STRING "The tensorflow release tag to be checked out (default v${version}).")
option(INSTALL_PROTOBUF "Install protobuf compatible with tensorflow version." OFF)
set(CMAKE_CXX_STANDARD 14 CACHE STRING "The C++ standard for building and linking the library (e.g., 14).")

# -------------
# CMake Options
# -------------

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
include(CMakePackageConfigHelpers)
set(CMAKECFG_INSTALL_DIR lib/cmake/TensorflowCC)

# Configure the build_tensorflow script.
configure_file("cmake/build_tensorflow.sh.in" "build_tensorflow.sh" @ONLY)

# ----------------------------------------------
# Include External Projects for Tensorflow Build
# ----------------------------------------------

include(TensorflowBase)
if(INSTALL_PROTOBUF)
  include(ProtobufExternal)
endif()

# ------------------------------
# Define Tensorflow_CC Interface
# ------------------------------

add_library(tensorflow_cc INTERFACE)
target_compile_features(tensorflow_cc INTERFACE "cxx_std_${CMAKE_CXX_STANDARD}")

if(INSTALL_PROTOBUF)
    add_dependencies(tensorflow_cc protobuf-external)
endif()

# The include folders are sometimes contained under bazel-bin/bin/ and sometimes just bazel-bin.
target_include_directories(
  tensorflow_cc INTERFACE
  $<INSTALL_INTERFACE:include/tensorflow/bazel-bin/tensorflow/include>
  $<INSTALL_INTERFACE:include/tensorflow/bazel-bin/tensorflow/include/src>
  $<INSTALL_INTERFACE:include/tensorflow/bazel-bin/bin/tensorflow/include>
  $<INSTALL_INTERFACE:include/tensorflow/bazel-bin/bin/tensorflow/include/src>
)
target_link_libraries(
  tensorflow_cc INTERFACE
  "${CMAKE_INSTALL_PREFIX}/lib/libtensorflow_cc.so.${PROJECT_VERSION_MAJOR}"
  dl pthread
)

# ----------------------------------------
# Configure CMake Config and Version Files
# ----------------------------------------

write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/TensorflowCCConfigVersion.cmake"
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY SameMajorVersion
)
configure_package_config_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/TensorflowCCConfig.cmake.in"
  "${CMAKE_CURRENT_BINARY_DIR}/TensorflowCCConfig.cmake"
  INSTALL_DESTINATION "${CMAKECFG_INSTALL_DIR}"
  NO_SET_AND_CHECK_MACRO # TensorflowCC only uses interface libraries
  NO_CHECK_REQUIRED_COMPONENTS_MACRO # TensorflowCC does not have components
)

# -------
# Install
# -------

# install all header files
install(
  DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tensorflow/bazel-bin/"
  DESTINATION include/tensorflow/bazel-bin
  FILES_MATCHING PATTERN "*.h"
                 PATTERN "*.inc"
                 REGEX ".*Eigen.*"
)
install(
  DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tensorflow/bazel-bin/tensorflow/"
  DESTINATION lib
  FILES_MATCHING PATTERN "libtensorflow_cc.so*"
)
install(
  DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/tensorflow/bazel-bin/bin/tensorflow/"
  DESTINATION lib
  FILES_MATCHING PATTERN "libtensorflow_cc.so*"
)

# --------------------------
# Install CMake targets file
# --------------------------

set_target_properties(
  tensorflow_cc PROPERTIES EXPORT_NAME TensorflowCC
)
install(
  TARGETS tensorflow_cc
  EXPORT TensorflowCCTargets
)
install(
  EXPORT TensorflowCCTargets
  FILE TensorflowCCTargets.cmake
  NAMESPACE TensorflowCC::
  DESTINATION "${CMAKECFG_INSTALL_DIR}"
)

# install config and version files
install(
  FILES
    "${CMAKE_CURRENT_BINARY_DIR}/TensorflowCCConfig.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/TensorflowCCConfigVersion.cmake"
  DESTINATION "${CMAKECFG_INSTALL_DIR}"
)```
Thank you so much.

Their CMake isn’t really useful here. The CMakeCache.txt used to build it would be more useful (basically, any Protobuf paths there should match your build’s Protobuf paths).

Hey, do you manage to run your tensorflow project with cmake? I’ve been struggling with it for weeks. Can you send me your actual cmake files for help?