在 Xcode 项目中使用包含外部静态 C 库的 xcframework 中的函数

Using functions from an xcframework containing an external static C library within an Xcode project

我有一个包含函数 my_library_function() 的 C 文件,我已使用 gcc 将其编译到静态库中,并使用 xcodebuild -create-framework 打包到名为 mylib.xcframework 的 xcframework 中。我已将此框架添加到 Mac 应用程序的 Xcode 项目中。但是在我的 Mac 应用程序中,我无法调用此函数,并且通常不确定如何调用。我已经尝试从 Swift 文件中 import mylib 并尝试直接调用函数 my_library_function() 但在这两种情况下都遇到了编译器错误 No such module mylibUse of unresolved identifier 'my_library_function'。我发现的唯一解决方法是从 xcframework 中的路径创建桥接 header 和 #include header 文件。但是,由于最终我想使用更复杂的库和交叉编译,并让 xcframework 包含用于多个目标的静态库,这似乎是一个 hacky 解决方法。有什么方法可以在没有桥接的情况下做到这一点 headers,我在这个过程中遗漏了什么吗?

下面是我所做的确切说明。 首先,我将 C 代码编译成一个静态库。该库的源代码包含一个函数:

#include <stdio.h>
void my_library_function(void) {
  printf("called from a static library");
}

mylib.c

我也有一个 header 以上:

void my_library_function(void);

mylib.h

源代码树如下:

.
├── include
│   └── mylib.h
└── mylib.c

项目源代码树

然后我使用以下方法将 C 代码编译成静态库:

> gcc -c mylib.c -o mylib.o
> ar rcs mylib.a mylib.o

然后我创建了一个 xcframework:

xcodebuild -create-xcframework -library mylib.a -headers include -output mylib.xcframework

这导致 xcframework 如下:

.
├── Info.plist
└── macos-x86_64
    ├── Headers
    │   └── mylib.h
    └── mylib.a

mylib.xcframework 源码树

然后我使用 Xcode 11.

创建了一个新的 Xcode 项目

在项目的根目录下,我创建了一个新组并将其命名为 Frameworks。然后,我将 xcframework 拖放到 XCode 框架组中,并在需要时选中复制项目复选框和创建组单选按钮。

在 Xcode 项目常规选项卡的框架、库和嵌入式内容下,我将框架设置为嵌入和签名。

在构建设置选项卡下的签名下,我将其他代码签名标志设置为 --deep 以防止代码签名错误。在同一个构建设置选项卡中,在链接下,运行路径搜索路径设置为 @executable_path/../Frameworks/。此外,在搜索路径下的构建设置选项卡中,我尝试将框架搜索路径、库搜索路径和 Header 搜索路径设置为相同的值 @executable_path/../Frameworks/,我还尝试将这些路径设置为空.

不幸的是,我无法从应用程序的任何地方使用 my_library_function(),也无法从 Swift.

使用 import mylib

我发现的唯一解决方法是创建一个 objective C 桥接 header 并使 #include 在框架文件夹中明确指向 Headers/mylib.h 以便能够调用我的函数。这似乎是一个 hacky 解决方案,但最终我想交叉编译我的代码,并且将为不同体系结构的每个单独的库提供单独的 header 文件,并且这样做可能会变得非常复杂。关于如何使用 MacOS Swift 项目在 XCFramework 中包含我的函数,我是否遗漏了什么?

下面是我的 Xcode 配置的一些图片:

我使用 clang 而不是 gcc 构建,并在 header 旁边包含了一个 clang 模块映射文件。它现在构建甚至提供 Xcode 自动完成功能。