3

我正在尝试构建一个 Swift 包,它包装了一个用 C: libndi_advanced_ios.a编写的来自NewTek 的 Apple Advanced NDI SDK的胖静态库。

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

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

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

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

我可以链接几十个 Stackoverflow 的问题和其他没有帮助的帖子,但它是无用的(abc)。

目前我有这个配置:

带有 module.modulemap 的项目结构

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

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

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

错误和警告

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

笔记

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

我总是在更改为Package.swift.

2022 年 10 月 1 日更新libndi_advanced_ios.a需要libc++.tbd。这可以在Build Phases -> Link Binary With Libraries中的应用程序中轻松链接,但我不知道如何在 Swift 包中链接。

4

2 回答 2

3

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

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

$ 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

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

于 2022-01-05T14:46:51.553 回答
1

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

我发现了几种有效的方法:

您可以通过从通用库中提取瘦 arm64 库来创建 XCFramework 包:

lipo "/Library/NDI SDK for Apple/lib/iOS/libndi_ios.a" -thin arm64 -output "$STAGING_DIRECTORY/libndi.a"

然后创建一个 XCFramework 包:

xcodebuild -create-xcframework -library "$STAGING_DIRECTORY/libndi.a" -headers "/Library/NDI SDK for Apple/include" -output "$STAGING_DIRECTORY/Clibndi.xcframework"

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

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

    targets: [
        .target(
            name: "WrapperLibrary",
            dependencies: ["Clibndi"], 
            linkerSettings: [
                .linkedFramework("Accelerate"),
                .linkedFramework("VideoToolbox"),
                .linkedLibrary("c++")
            ]),
        .systemLibrary(name: "Clibndi")
    ]

然后,我有 WrapperLibrary/Sources/Clibndi/module.modulemap 看起来像:

module Clibndi {
  header "/Library/NDI SDK for Apple/include/Processing.NDI.Lib.h"
  link "ndi_ios"
  export *
}

最后,我的应用程序目标(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

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

理想情况下,您也可以将 NDI SDK 的依赖库和框架添加到 pkg- config文件Libs: -L${NDI_SDK_ROOT}/lib/iOS -lndi_ios -lc++ -framework Accelerate -framework VideoToolbox中(-framework

于 2022-02-28T18:23:33.923 回答