如何在 CMake 中正确使用 Tensorflow Lite?

How to properly use Tensorflow Lite with CMake?

我的目标是在相当复杂的 CMake C++ 项目中使用 TF Lite,该项目已经有各种其他第三方库(dlib、opencv 等)。

我尝试在 Windows 10 上使用 cmake+ninja+msvc 来实现,但我也尝试使用 Ubuntu 20.04 cmake+ninja+gcc 并且我 运行 进入同样的问题。

TF版本为:2.6.0

我尝试了两种方法:

  1. 按原样编译和 link 并首先按照 TF 中的描述使用 步骤 :
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)

它编译得很好,我可以安装等,但是当我将它插入到已经存在的 CMakeList.txt 中时,像这样:

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

它需要超过 80 个 TFLite 的所有目标(absl-...等)。我试图将它们全部添加(我知道这不好,但想确保它是否有效),然后它在源目录错误中向所有这些抛出前缀:

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.        

所以我被困在这边,但后来我尝试:

  1. 将其构建为共享库并像那样使用它

为此我打开了 -DBUILD_SHARED_LIBS,设置最大 PATH 长度以避免与此相关的问题,开始构建然后:

[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\bin0203~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\bin0203~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~119\COMMUN~1\VC\Tools\MSVC29~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~119\COMMUN~1\VC\Tools\MSVC29~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.

当然,因为这是一个共享版本,文件夹包含一个 fft2d_fftsg-debug.dll 所以对我来说,似乎 fft2d 也是作为共享构建的,当 TF Lite 构建尝试 link 时,它失败了。

所以这也没有用,我很困惑,我知道 Bazel 更常用于 TF,但由于 TF 网站本身说这是可能的,而且我的项目也在 CMake 中,我真的想让这个工作。

我认为可以进行下一步的地方(并感谢您的一些启动):

  1. 以某种方式自动添加所有目标和适当的包含库。
  2. 关于 TF Lite 构建为共享库时如何找到 fft2d 的一些见解。 (也许缺少开关?)

我成功了。这不是最好的,但它确实有效。 因此,由于 TFLite 没有构建界面,因此无法像评论中指出的那样进行安装,但可以将其作为子目录(带有包含)添加到需要安装的项目中,而无需 tensorflowlite 目标,如果它是有针对性的在顶级程序(不再需要安装)。