基于TensorFlow Lite构建库时CMake静态与共享库内容差异求助
解决方案
问题根因
静态库与共享库的链接逻辑存在本质差异:
- 共享库(.so)编译时,链接器会将所有依赖的静态库代码完整打包到最终生成的.so文件中,因此你的动态库自带完整TFLite逻辑,可独立运行
- 静态库(.a)本质是自身代码目标文件的归档包,默认不会合并依赖的其他静态库内容,仅会记录未解析的外部符号。你之前生成的500KB静态库仅包含你自己写的业务代码,没有整合TFLite的实现,因此使用时会提示符号缺失。
具体修改方案
方案一:合并静态库(无外部依赖,推荐)
通过CMake添加自定义指令,将你的业务静态库与TFLite静态库合并为单个独立静态库,修改后的CMakeLists.txt调整如下:
- 首先在
add_subdirectory编译TFLite之前,强制指定编译静态版本的TFLite:
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
- 保留你原本编译静态MY_LIB的配置,在
target_include_directories之后添加合并静态库的自定义目标:
# 合并MY_LIB和tensorflow-lite静态库 add_custom_target(merged_my_lib ALL # 解压TFLite静态库的目标文件 COMMAND ar -x $<TARGET_FILE:tensorflow-lite> # 解压你的业务静态库的目标文件 COMMAND ar -x $<TARGET_FILE:MY_LIB> # 合并所有目标文件为新的静态库,覆盖原有MY_LIB.a COMMAND ar -qc $<TARGET_FILE:MY_LIB> *.o # 清理临时目标文件 COMMAND rm -f *.o # 依赖两个静态库的生成结果 DEPENDS MY_LIB tensorflow-lite WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )
编译后生成的MY_LIB.a就包含了全部业务代码+TFLite实现,无外部依赖。
方案二:保留依赖声明(适合允许用户自行提供TFLite的场景)
如果可以接受使用方需要自行链接TFLite依赖,不需要完全无依赖,不需要修改现有静态库编译逻辑,仅需要在发布你的静态库时,告知使用方链接时需要额外链接tensorflow-lite以及dl库即可。
注意事项
- 上述合并静态库的
ar命令仅适用于Linux、macOS平台,如果是Windows平台需要替换为lib.exe的对应合并指令 - 保留
CMAKE_POSITION_INDEPENDENT_CODE ON配置,避免后续你的静态库被用于链接生成共享库时出现地址相关错误 - 若需裁剪最终静态库体积,可在编译时添加
-Os优化选项,同时开启TFLite的编译裁剪开关,移除不需要的算子实现。
内容的提问来源于stack exchange,提问作者amw
相关产品推荐
相关产品推荐

