繁体   English   中英

使用适用于 macOS/iOS 的 XCFramework 创建 Flutter Rust FFI 插件

[英]Creating Flutter Rust FFI Plugin with an XCFramework for macOS/iOS

概述

我在尝试着:

  • 使用flutter_rust_bridge为 Flutter 创建一个 FFI 插件
  • 对于 iOS/macOS,使用 XCFramework(目前似乎是比通用库更好的选择)

简而言之,我很难构建我的示例项目(使用我的 flutter ffi 插件)。

我做了什么

  1. 从生成的 rust static 库(包括 macOS、iOS 和 iOS 模拟器 static 库)创建了一个 XCFramework。 光是这一点就很头疼了。
  2. 在我的iosmacos文件夹中创建了以下flutter_mimir.podspec文件:
Pod::Spec.new do |spec|
  spec.name          = 'flutter_mimir'
  spec.version       = '0.0.1'
  spec.license       = { :file => '../LICENSE' }
  spec.homepage      = 'https://github.com/GregoryConrad/mimir'
  spec.authors       = { 'Gregory Conrad' => 'gregorysconrad@gmail.com' }
  spec.summary       = 'Embedded instance of milli'

  spec.ios.deployment_target = '9.0'
  spec.osx.deployment_target = '10.11'

  spec.source = { :path => '.' }
  spec.preserve_paths = 'EmbeddedMilli.xcframework/**/*'
  spec.vendored_frameworks = 'EmbeddedMilli.xcframework'
  spec.xcconfig = { 'OTHER_LDFLAGS' => '-framework EmbeddedMilli' }

  # TODO clean up following (not sure if these are actually needed here?)
  # Flutter.framework does not contain a i386 slice.
  spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
  spec.static_framework = true
end
  1. 将我创建的EmbeddedMilli.xcframework移动到iosmacos目录中。
  2. pod install运行良好。

问题

为 macOS 构建时:

Launching lib/main.dart on macOS in debug mode...
lib/main.dart:1
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00006000-0004695C0C06801E }
{ platform:macOS, arch:x86_64, id:00006000-0004695C0C06801E }
ld: framework not found EmbeddedMilli
clang: error: linker command failed with exit code 1 (use -v to see invocation)

如何修改我的库的 podspec/项目构建设置以允许构建示例项目?

有关的

我的问题的答案来自这个 GitHub 线程 这是我的评论的副本:

以防其他人遇到这个问题,我使用ffiPlugin: true让 FFI 与我的跨平台 XCFramework 一起工作(感谢 @leisim 与 Isar 的很好的例子。),我不敢相信我没有意识到这一点。 但是我的 XCFramework 变得摇摇欲坠,这是我修复它的方法(macOS 和 iOS 的代码完全相同,但不幸的是不能符号链接):

  • my_package.podspec
Pod::Spec.new do |spec|
  spec.name          = 'my_package'
  spec.version       = '0.0.1'
  spec.license       = { :file => '../LICENSE' }
  spec.homepage      = ''
  spec.authors       = { 'Your Name' => 'blabla@example.com' }
  spec.summary       = 'Some summary'

  spec.source              = { :path => '.' }
  spec.source_files        = 'Classes/**/*'
  spec.public_header_files = 'Classes/**/*.h'
  spec.vendored_frameworks = 'Frameworks/MyPackage.xcframework'

  spec.ios.deployment_target = '11.0'
  spec.osx.deployment_target = '10.11'
end
  • Classes/binding.h
void enforce_binding();
  • Classes/EnforceBinding.swift
public func dummyMethodToEnforceBundling() {
    enforce_binding() // disable tree shaking
}
  • Frameworks/MyPackage.xcframework需要有一个void enforce_binding() {} function。我在 Rust 中这样做了:
/// Enforce the binding for this library (to prevent tree-shaking)
#[no_mangle]
pub extern "C" fn enforce_binding() {}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM