链接到 Swift 包内的 fat 静态库

ale*_*e00 9 static-libraries ios swift swift-package-manager swift-package

我\xe2\x80\x99m 尝试构建一个 Swift 包,该包包装了一个用 C: libndi_advanced_ios.a编写的胖静态库,来自NewTek\'s Apple Advanced NDI SDK。

\n

我在将预编译库(只有头文件和 .a 二进制包可用)链接到我的 Swift 包时遇到问题。我做了很多研究并尝试了不同的解决方案,但没有一个有效。这是一个快速列表:

\n
    \n
  • 无法捆绑在 XCFramework 中,因为libndi_advanced_ios.a支持多个平台(arm_v7、i386、x86_64、arm64)并xcodebuild -create-xcframework返回错误( Swift 论坛binaries with multiple platforms are not supported上也讨论了此解决方案);

    \n
  • \n
  • 按照SPM 文档(已过时)的建议使用.linkedLibraryin会发出警告,并且我什至不记得它是否构建成功;targetssystem packages are deprecated; use system library targets instead

    \n
  • \n
  • 使用不同的标志和设置(如linkerSettings)并没有成功。也许我只是错过了正确的组合。

    \n
  • \n
\n

我可以链接数十个 Stackoverflow 的问题和其他没有帮助的帖子,但它们毫无用处(a、b、c)。

\n

目前我有这样的配置:

\n带有 module.modulemap 的项目结构\n

其中Package.swift包含以下代码:

\n
let package = Package(\n    name: "swift-ndi",\n    platforms: [.iOS(.v12)],\n    products: [\n        .library(\n            name: "swift-ndi",\n            targets: ["swift-ndi"])\n    ],\n    dependencies: [],\n    targets: [\n        .target(name: "CiOSNDI", path: "Libraries"),\n        .target(\n            name: "swift-ndi",\n            dependencies: ["CiOSNDI"]),\n        .testTarget(\n            name: "swift-ndiTests",\n            dependencies: ["swift-ndi"]),\n    ]\n    \n)\n
Run Code Online (Sandbox Code Playgroud)\n

您可以在alessionossa/swift-ndi找到整个项目。
\n目前唯一的结果是一些警告,并且 CiOSNDI 模块无法构建:

\n错误和警告\n

我也尝试.systemLibrary(name: "CiOSNDI", path: "Libraries/"),过这种配置:alessionossa/swift-ndi/tree/systemLibrary;但我收到这些错误:
\n错误和警告2

\n

笔记

\n

NDI_include实际上是指向 的别名/符号链接/Library/NDI Advanced SDK for Apple/include,而NDI_iOS_lib指向/Library/NDI Advanced SDK for Apple/lib/iOS.

\n

我总是在更改后清理构建文件夹Package.swift。

\n

更新 10/01/2022:libndi_advanced_ios.a需要libc++.tbd。这可以在应用程序中轻松链接到Build Phases -> Link Binary With Libraries,但我不\xe2\x80\x99t 知道如何在 Swift 包中链接。

\n

Pau*_*ien 5

二进制目标需要用 指定.binary_target。请参阅此处的文档和示例。

.xcframework从 file 命令来看,包装在 中的静态库的示例如下所示:

$ file GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement: Mach-O universal binary with 2 architectures: [arm_v7:current ar archive] [arm64]
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement (for architecture armv7):  current ar archive
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement (for architecture arm64):  current ar archive
Run Code Online (Sandbox Code Playgroud)

创建.xcframework文件的一种方法是使用 Firebase 的ZipBuilder.xcframework ,它从使用 CocoaPods podspec 文件指定的静态库创建文件。


Rya*_*yne 2

我还需要在我的应用程序中添加 NDI SDK 作为 Swift 包依赖项。

我发现了一些有效的方法:

您可以通过从通用库中提取精简的arm64库来创建XCFramework捆绑包:

lipo "/Library/NDI SDK for Apple/lib/iOS/libndi_ios.a" -thin arm64 -output "$STAGING_DIRECTORY/libndi.a"
Run Code Online (Sandbox Code Playgroud)

然后创建一个 XCFramework 包:

xcodebuild -create-xcframework -library "$STAGING_DIRECTORY/libndi.a" -headers "/Library/NDI SDK for Apple/include" -output "$STAGING_DIRECTORY/Clibndi.xcframework"
Run Code Online (Sandbox Code Playgroud)

我最终没有使用这种方法,因为将 XCFramework 作为可下载的二进制版本托管在 GitHub 上需要我公开我的存储库(请参阅此问题)。

相反,我在 Package.swift 中使用系统库目标:

lipo "/Library/NDI SDK for Apple/lib/iOS/libndi_ios.a" -thin arm64 -output "$STAGING_DIRECTORY/libndi.a"
Run Code Online (Sandbox Code Playgroud)

然后,我有 WrapperLibrary/Sources/Clibndi/module.modulemap ,如下所示:

module Clibndi {
  header "/Library/NDI SDK for Apple/include/Processing.NDI.Lib.h"
  link "ndi_ios"
  export *
}
Run Code Online (Sandbox Code Playgroud)

最后,我的应用程序目标(Xcode 项目的一部分,而不是 Swift 包)依赖于 WrapperLibrary,我必须将“/Library/NDI SDK for Apple/lib/iOS”(包括引号)添加到“Library Search Paths” ”在“构建设置”选项卡中。

作为修改应用程序目标构建设置的替代方法,您可以将 pkg-config 文件添加到 pkg-config 搜索路径中的目录中。例如,/usr/local/lib/pkgconfig/libndi_ios.pc:

NDI_SDK_ROOT=/Library/NDI\ SDK\ for\ Apple

Name: NDI SDK for iOS
Description: The NDI SDK for iOS
Version: 5.1.1
Cflags: -I${NDI_SDK_ROOT}/include
Libs: -L${NDI_SDK_ROOT}/lib/iOS -lndi_ios
Run Code Online (Sandbox Code Playgroud)

.systemLibrary(name: "Clibndi", pkgconfig: "libndi_ios")然后在您的包清单中使用。然而,我发现这对于用户来说比仅仅将设置添加到我的应用程序目标更不方便。

理想情况下,您也可以将 NDI SDK 的依赖库和框架添加到 pkg-config 文件中 ( Libs: -L${NDI_SDK_ROOT}/lib/iOS -lndi_ios -lc++ -framework Accelerate -framework VideoToolbox),但 Swift 的 pkg-config 参数解析中似乎存在错误-framework,因此我提交了一个错误:SR-15933。