icarus
icarus

Reputation: 41

How to properly use Tensorflow Lite with CMake?

My goal is to use TF Lite in a fairly complex CMake C++ project, which already has various other third-party libraries (dlib, opencv, ...).

I try to make it with cmake+ninja+msvc on Windows 10, but I also tried it with the Ubuntu 20.04 cmake+ninja+gcc and I ran into the same issue.

The TF version is: 2.6.0

I tried with two approaches:

  1. Compile and link as it is and use as it's described in the TF first steps :
cmake ../tensorflow_src/tensorflow/lite -DCMAKE_BUILD_TYPE=Debug
cmake --build . -j

...

cmake_minimum_required(VERSION 3.16)
project(minimal C CXX)

set(TENSORFLOW_SOURCE_DIR "" CACHE PATH
  "Directory that contains the TensorFlow project" )
if(NOT TENSORFLOW_SOURCE_DIR)
  get_filename_component(TENSORFLOW_SOURCE_DIR
    "${CMAKE_CURRENT_LIST_DIR}/../../../../" ABSOLUTE)
endif()

add_subdirectory(
  "${TENSORFLOW_SOURCE_DIR}/tensorflow/lite"
  "${CMAKE_CURRENT_BINARY_DIR}/tensorflow-lite" EXCLUDE_FROM_ALL)

It compiles fine and I'm able to install etc, but when I insert it into the already existing CMakeList.txt like this:

target_link_libraries(myproject ... tensorflow-lite)
...
install(
    TARGETS 
    ...
    tensorflow-lite
    ...)

It requires all targets of TFLite (absl-..., etc) more than 80 of them. I tried to add them all (I know it's not nice, but wanted make sure if it works), then it throws a prefix in source directory error to all of them:

Severity    Code    Description Project File    Line    Suppression State
Error       CMake Error in tensorflow/tensorflow/lite/tools/cmake/modules/ruy/CMakeLists.txt:
  Target "ruy" INTERFACE_INCLUDE_DIRECTORIES property contains path:

    "C:/work/project/out/build/x64-Debug/ruy"

  which is prefixed in the build directory.Target "ruy"
  INTERFACE_INCLUDE_DIRECTORIES property contains path:

    "C:/work/project/out/build/x64-Debug/ruy"

  which is prefixed in the source directory.        

So I'm stuck here on this side, but then I tried to:

  1. Build it as a shared library and use it like that

For this I turned on -DBUILD_SHARED_LIBS, set the maximum PATH length to avoid issues related to that, started to build and then:

[302/970] Linking C shared library _deps\fft2d-build\fft2d_fftsg2d-debug.dll
FAILED: _deps/fft2d-build/fft2d_fftsg2d-debug.dll _deps/fft2d-build/fft2d_fftsg2d-debug.lib
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_dll --intdir=_deps\fft2d-build\CMakeFiles\fft2d_fftsg2d.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100203~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100203~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo _deps\fft2d-build\CMakeFiles\fft2d_fftsg2d.dir\__\__\fft2d\fftsg2d.c.obj  /out:_deps\fft2d-build\fft2d_fftsg2d-debug.dll /implib:_deps\fft2d-build\fft2d_fftsg2d-debug.lib /pdb:_deps\fft2d-build\fft2d_fftsg2d-debug.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL  _deps\fft2d-build\fft2d_fftsg-debug.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib  && cd ."
LINK Pass 1: command "C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\link.exe /nologo _deps\fft2d-build\CMakeFiles\fft2d_fftsg2d.dir\__\__\fft2d\fftsg2d.c.obj /out:_deps\fft2d-build\fft2d_fftsg2d-debug.dll /implib:_deps\fft2d-build\fft2d_fftsg2d-debug.lib /pdb:_deps\fft2d-build\fft2d_fftsg2d-debug.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL _deps\fft2d-build\fft2d_fftsg-debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:_deps\fft2d-build\CMakeFiles\fft2d_fftsg2d.dir/intermediate.manifest _deps\fft2d-build\CMakeFiles\fft2d_fftsg2d.dir/manifest.res" failed (exit code 1104) with the following output:
LINK : fatal error LNK1104: cannot open file '_deps\fft2d-build\fft2d_fftsg-debug.lib'
[315/970] Building CXX object CMakeFiles\tensorflow-lite.dir\kernels\gru_cell.cc.obj
ninja: build stopped: subcommand failed.

Of course since this is a shared build the folder contains a fft2d_fftsg-debug.dll So for me it seems that the fft2d is also built as shared and when the TF Lite build tries to link, it fails.

So this didn't work either and I'm pretty stucked, I know that Bazel is more commonly used with TF, but since the TF site itself says it is possible and my project is also in CMake, I really want to make this work.

Where I might think it is possible to make the next step (and would be grateful for some kickstart):

  1. Somehow automatically add all the targets and proper include libraries.
  2. Some insight on how TF Lite could find fft2d if it's built as a shared lib. (Perhaps some missing switch?)

Upvotes: 1

Views: 2653

Answers (1)

icarus
icarus

Reputation: 41

I managed to make it work. It's not the best, but it works. So since TFLite has no build interface, it cannot be installed as it was pointed out in the comment, but it can be added as a subdirectory (with the includes) to the project that needs to be installed without tensorflowlite target, if it is targeted at the top level program (where no install is needed anymore).

Upvotes: 3

Related Questions