Kotlin KMP引入CocoaPod依赖导致arm64架构符号未定义问题
KMP iOS平台引入TensorFlowLiteObjC依赖编译报错问题
问题背景
我们开发了一款支持Android、iOS和JS平台的Kotlin KMP库,近期为其添加AI功能并在全平台使用TensorFlow Lite。针对iOS平台,通过CocoaPod引入TensorFlowLiteObjC依赖,配置如下:
cocoapods { summary = "..." homepage = "..." framework { baseName = "...." export(project(":module_a")) export(project(":module_b")) freeCompilerArgs += "-Xallocator=std" freeCompilerArgs += "-linker-options" freeCompilerArgs += "-application_extension" isStatic = false binaryOption("bundleShortVersionString", rootProject.extra["versionName"] as String) binaryOption("bundleVersion", (rootProject.extra["versionCode"] as Int).toString()) } ios.deploymentTarget = "14" pod( name = "TensorFlowLiteObjC", version = "2.5.0", moduleName = "TFLTensorFlowLite" ) }
编译报错信息
执行./gradlew podPublishXCFramework命令编译库时,出现如下错误:
> Task :linkPodDebugFrameworkIosArm64 FAILED w: Interop library /.../module_b-cinterop-TFLTensorFlowLite can't be exported with -Xexport-library e: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors Please try to disable compiler caches and rerun the build. To disable compiler caches, add the following line to the gradle.properties file in the project's root directory: kotlin.native.cacheKind.iosArm64=none The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1. output: ld: warning: ignoring duplicate libraries: '-ldl' Undefined symbols for architecture arm64: "_TfLiteInterpreterAllocateTensors", referenced from: -[TFLInterpreter allocateTensorsWithError:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterCreate", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterDelete", referenced from: -[TFLInterpreter dealloc] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterGetInputTensor", referenced from: -[TFLInterpreter cTensorOfType:atIndex:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterGetInputTensorCount", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterGetOutputTensor", referenced from: -[TFLInterpreter cTensorOfType:atIndex:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterGetOutputTensorCount", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterInvoke", referenced from: -[TFLInterpreter invokeWithError:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterOptionsAddDelegate", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterOptionsCreate", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterOptionsDelete", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterOptionsSetErrorReporter", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterOptionsSetNumThreads", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteInterpreterResizeInputTensor", referenced from: -[TFLInterpreter resizeInputTensorAtIndex:toShape:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteModelCreateFromFile", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteModelDelete", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorByteSize", referenced from: -[TFLInterpreter copyData:toInputTensorAtIndex:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) -[TFLInterpreter dataFromTensor:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorCopyFromBuffer", referenced from: -[TFLInterpreter copyData:toInputTensorAtIndex:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorData", referenced from: -[TFLInterpreter dataFromTensor:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorDim", referenced from: -[TFLInterpreter shapeOfTensor:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorName", referenced from: -[TFLInterpreter tensorOfType:atIndex:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorNumDims", referenced from: -[TFLInterpreter shapeOfTensor:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorQuantizationParams", referenced from: -[TFLInterpreter tensorOfType:atIndex:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteTensorType", referenced from: -[TFLInterpreter tensorOfType:atIndex:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteVersion", referenced from: __GLOBAL__sub_I_TFLInterpreter.mm in TFLTensorFlowLite[6](TFLInterpreter.o) __GLOBAL__sub_I_TFLInterpreter.mm in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteXNNPackDelegateCreate", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteXNNPackDelegateDelete", referenced from: -[TFLInterpreter dealloc] in TFLTensorFlowLite[6](TFLInterpreter.o) "_TfLiteXNNPackDelegateOptionsDefault", referenced from: -[TFLInterpreter initWithModelPath:options:delegates:error:] in TFLTensorFlowLite[6](TFLInterpreter.o) ld: symbol(s) not found for architecture arm64 FAILURE: Build failed with an exception.
已尝试的无效方案
- 在
build.gradle.kts的cocoapods.framework{}区块中添加freeCompilerArgs += listOf("-linker-option", "-framework", "-linker-option", "TensorFlowLiteObjC") - 添加
linkerOpts("-framework", "TensorFlowLiteObjC")参数 - 升级Kotlin版本至2.0.0
- 禁用编译器缓存(添加
kotlin.native.cacheKind.iosArm64=none到gradle.properties)
解决方案
方案1:切换为静态库编译
将framework配置中的isStatic = false改为isStatic = true。动态库在链接第三方依赖时易出现符号缺失问题,静态库会直接将依赖符号打包进最终产物,避免链接阶段找不到符号。
修改后的配置片段:
framework { baseName = "...." export(project(":module_a")) export(project(":module_b")) freeCompilerArgs += "-Xallocator=std" freeCompilerArgs += "-linker-options" freeCompilerArgs += "-application_extension" isStatic = true // 修改此处 binaryOption("bundleShortVersionString", rootProject.extra["versionName"] as String) binaryOption("bundleVersion", (rootProject.extra["versionCode"] as Int).toString()) }
方案2:为cinterop库添加显式链接配置
若必须使用动态库,需为生成的cinterop库添加链接参数:
- 在项目的
src/iosMain/cinterop目录下创建TFLTensorFlowLite.def文件(名称需与pod的moduleName对应),添加内容:
language = Objective-C modules = TFLTensorFlowLite linkerOpts = -framework TensorFlowLiteObjC
- 在
cocoapods配置中指定该def文件:
pod( name = "TensorFlowLiteObjC", version = "2.5.0", moduleName = "TFLTensorFlowLite", defFile = file("src/iosMain/cinterop/TFLTensorFlowLite.def") )
方案3:调整模块导出方式
错误提示提到Interop library /.../module_b-cinterop-TFLTensorFlowLite can't be exported with -Xexport-library,说明module_b间接依赖了TensorFlowLite的cinterop库且被export。将export改为api,避免将cinterop库导出到主框架:
// 替换原有的export为api api(project(":module_a")) api(project(":module_b"))
方案4:升级TensorFlowLiteObjC版本
当前使用的2.5.0版本较旧,尝试升级到最新稳定版(如2.16.1),新版本Pod包可能修复了链接相关问题:
pod( name = "TensorFlowLiteObjC", version = "2.16.1", moduleName = "TFLTensorFlowLite" )
内容的提问来源于stack exchange,提问作者Milan
相关产品推荐
相关产品推荐

