当前位置: 首页 > 知识库问答 >
问题:

如何将TensorFlow Lite构建为一个静态库,并从一个单独的(CMake)项目链接到它?

常睿范
2023-03-14

通过将源代码添加到tensorflow/Lite/examples中,我成功地构建了一个运行TF Lite模型的简单C++应用程序,类似于官方C++TF指南对完整TF的建议。现在,我想将它构建为一个单独的项目(共享库),静态链接到TF Lite,并使用CMake作为构建系统。

我尝试向我的cmakelists.txt添加一个自定义目标,它将使用Bazel构建TF Lite:

set(TENSORFLOW_DIR ${CMAKE_SOURCE_DIR}/thirdparty/tensorflow)
add_custom_target(TFLite
    COMMAND bazel build //tensorflow/lite:framework
    COMMAND bazel build //tensorflow/lite/kernels:builtin_ops
    WORKING_DIRECTORY ${TENSORFLOW_DIR})
set(TFLite_INCLUDES
    ${TENSORFLOW_DIR}
    ~/.cache/bazel/_bazel_azymohliad/ec8567b83922796adb8477fcbb00a36a/external/flatbuffers/include)

set(TFLite_LIBS
    ${TENSORFLOW_DIR}/bazel-bin/tensorflow/lite/libframework.pic.a)
    
target_include_directories(MyLib ... PRIVATE ... ${TFLite_INCLUDES})
target_link_libraries(MyLib ... ${TFLite_LIBS})

通过这种配置,我在链接过程中得到了许多对TFLite内容的未定义引用。我检查了nm,在libframework.pic.a中确实缺少这些符号,我在Bazel输出中的各种.o文件中找到了一些。手动选择所有这些.o文件似乎是错误的。

那么,有没有可能像我正在尝试的那样,从CMake中很好地链接到TF Lite呢?也许有什么神奇的Bazel query include_dirs(//tensorflow/lite:framework)命令可以给我提供所有必需的include dirs的路径,还有一个类似的命令可以用于库链接,以便我可以将这些信息传递给cmake?

共有1个答案

巫马越彬
2023-03-14

最后,我手动列出了cmake的target_link_libraries(在tflite_libs中)所需的所有TFLite对象文件,它可以工作了。

我使用了一个简单的shell脚本来获取必要的对象文件列表。首先,我将构建日志中所有未定义的引用收集到一个bash数组中,如下所示:

SYMBOLS=(\
    'tflite::CombineHashes('\
    'tflite::IsFlexOp('\
    'tflite::ConvertArrayToTfLiteIntArray('\
    'tflite::EqualArrayAndTfLiteIntArray('\
    ...
    'tflite::ConvertVectorToTfLiteIntArray(')

然后,对于该数组中的每个符号,我检查了bazel构建输出中的每个*.o文件:

for SYMBOL in $SYMBOLS[@]; do
    for OBJ in $(find -L /path/to/tensorflow/bazel-bin/ -name '*.o'); do
        nm -C $OBJ | grep "T $SYMBOL" > /dev/null && echo $OBJ
    done
done | sort | uniq

对于include位置,我用${TENSORFLOW_DIR}/bazel-tensorflow/external/flatbuffers/include/替换了bazel缓存中flatbuffers的硬编码路径。谢谢jdehesa的提示。

Update:
本机构建无所不包的TF Lite静态库可以非常类似于RPi、iOS或ARM64的官方构建指令,使用简单的旧make:
1。./tensorflow/lite/tools/make/download_dependencies.sh
2。make-f tensorflow/lite/tools/make/makefile

输出库将存储为 /tensorflow/lite/tools/make/gen/ /lib/libtensorflow-lite.a 。外部依赖关系及其头部将进入 /tensorflow/tensorflow/lite/tools/make/downloads (例如,flatbuffers头部位于 /tensorflow/tensorflow/lite/tools/make/downloads/flatbuffers/include )。

Guide没有提到make可以直接调用。对于不同的交叉编译目标,有包装器脚本,它们只是设置适当的变量并运行make。但默认情况下,make只进行本机构建。这个make调用可以作为自定义命令添加到cmakelists.txt中。

 类似资料:
  • 问题内容: 我有2个静态的Linux库,通过创建,和。 我想将它们合并到一个静态库中。 我怎样才能做到这一点。 我想创建一个合并的静态库,而不是将这两个库都提供给应用程序的最终链接。 问题答案: 您可以从两个文件中提取对象,然后使用提取的s 创建文件:

  • 问题内容: 我正在尝试使用在Linux上运行的CMake构建基于OpenCV的项目。到目前为止,我的文件看起来像 但这会导致动态链接的库。如何链接静态库? 问题答案: 您可以通过在CMake 中将标志设置为false来构建静态OpenCV库。然后,使用这些静态库构建自己的应用程序所需要做的就是在您的计算机中添加对OpenCV的依赖: 和CMake将照顾一切。

  • 在共享的情况下,我使用的是cmake文件 在静态情况下 我认为我只需要更改如何从 失败:cmd.exe/c“cd.&&clang++.exe-target=aarch64-none-linux-android-gcc-toolchain=c://android/android-sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/

  • 问题内容: 我有两个在android studio中制作的单独的android应用程序项目,我正在尝试将项目1合并到项目2中,以使其全部成为一个应用程序,我该怎么做呢?我知道如何在Eclipse中做到这一点,但在android studio中却不行。请注意,这两个项目都是android应用程序,都不是android库。 任何帮助都将是惊人的! 当我将项目1导入到项目模块中时,在生成成绩时出现此错误

  • 我有两个独立的android应用程序项目,它们都是在android studio中制作的。我正在尝试将项目1合并到项目2中,使其成为一个应用程序。我该怎么做呢?我知道如何在eclipse中完成,但不知道如何在android studio中完成。请注意,这两个项目都是android应用程序,没有一个是android库。 任何帮助将是惊人的! 当我将项目1导入项目模块时,我在年级生成中遇到以下错误:

  • 问题内容: 有一个以前具有JAR打包类型的Maven项目。现在,该项目已经发展起来,需要将它构建为EAR,包括JAR属性及其依赖项。 这是否一定意味着我必须引入第二种带EAR封装的POM?是否可以从单个Maven项目构建JAR + EAR?其背后的原因是,我真的不希望从根本上重组我的存储库结构。 如果不可能,我想我需要以某种方式重组项目结构以利用Maven模块。在这种情况下,您会建议什么样的(子)