在 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 mylib
和 Use 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 自动完成功能。
我有一个包含函数 my_library_function()
的 C 文件,我已使用 gcc
将其编译到静态库中,并使用 xcodebuild -create-framework
打包到名为 mylib.xcframework
的 xcframework 中。我已将此框架添加到 Mac 应用程序的 Xcode 项目中。但是在我的 Mac 应用程序中,我无法调用此函数,并且通常不确定如何调用。我已经尝试从 Swift 文件中 import mylib
并尝试直接调用函数 my_library_function()
但在这两种情况下都遇到了编译器错误 No such module mylib
和 Use 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 自动完成功能。