2

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

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

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

mylib.c

我也有上面的标题:

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 项目的常规选项卡中,在 Frameworks、Libraries 和 Embedded Content 下,我将框架设置为 Embed & Sign。

在 Build Settings 选项卡下的 Signing 下,我将 Other Code Signing Flags 设置为--deep以防止出现代码设计错误。在同一 Build Settings 选项卡中的 Linking 下,Runpath Search Paths 设置为@executable_path/../Frameworks/. 此外,在搜索路径下的构建设置选项卡中,我尝试将框架搜索路径、库搜索路径和标题搜索路径设置为相同的值@executable_path/../Frameworks/,并且我也尝试将这些路径设置为空。

不幸的是,我无法my_library_function()在应用程序的任何地方使用,也无法import mylib从 Swift 中使用。

我发现的唯一解决方法是创建一个目标 C 桥接头,并#include在框架文件夹中明确指出Headers/mylib.h能够调用我的函数。这似乎是一个 hacky 解决方案,尽管最终我想交叉编译我的代码,并且将为不同架构的每个单独库拥有单独的头文件,这样做可能会变得相当复杂。关于如何将我的函数包含在 XCFramework 和 MacOS Swift 项目中,我有什么遗漏吗?

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

Xcode 项目目录 添加框架 嵌入和签名 其他代码签名标志 构建阶段

4

1 回答 1

1

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

于 2020-07-06T16:05:35.160 回答