Sam*_*Sam 7 c interop swift swift-package-manager
如何使用Swift包管理器包含C代码(在我的情况下,单个.c文件和头文件),而无需用户安装我的C库/usr/local/lib?
我曾想过在我的主包的子目录中创建一个包含头+ lib的子包,并使用相对路径,最后构建swift build -Xlinker ./relative/path/to/mylib,但是我没有成功解决依赖,因为它应该是一个独立的git存储库.错误信息是:
error: failed to clone; fatal: repository '/absolute/path/to/mylib' does not exist
此外,我不清楚使用-Xlinker旗帜是否正确.
我不能使用带有纯SwiftPM方法的桥接头,并且在系统范围内安装我的库似乎有点矫枉过正,也不是非常便携.
有任何想法吗?
我在github的这个项目中做到了这一点.它pthread_once_t通过将其包装在C中并将其重新暴露到swift来替换.这是一个有趣的练习,可以解决Swift试图限制你进入的问题pthread_once_t,dispatch_once直接无法使用.
这是一个精简版的Package.swift文件:
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "Once",
products: [
.library(
name: "Once",
targets: ["OnceC", "Once"]),
],
dependencies: [
],
targets: [
.target(
name: "OnceC",
dependencies: [],
path: "Sources/OnceC"),
.target(
name: "Once",
dependencies: ["OnceC"],
path: "Sources/Swift"),
.testTarget(
name: "OnceTests",
dependencies: ["Once"]),
]
)
Run Code Online (Sandbox Code Playgroud)
您可以使用可执行文件轻松替换产品库.主要部分是产品的目标需要包含构建所需的C和Swift目标.
然后在目标部分中,使swift目标将C目标列为依赖项.
您可以在此处了解有关SwiftPM Usage.md中C目标所需布局的更多信息
C语言目标类似于Swift目标,除了C语言库应该包含一个名为include保存公共头的目录.
要允许Swift目标导入C语言目标,请在清单文件中添加目标依赖项.对于这3种情况,Swift Package Manager将自动为每个C语言库目标生成一个模块映射:
如果include/Foo/Foo.h存在并且Foo是include目录下的唯一目录,则include/Foo/Foo.h成为伞标题.
如果include/Foo.h存在include且不包含其他子目录,则
include/Foo.h成为伞标题.
否则,如果include目录只包含头文件而没有其他子目录,则它将成为伞状目录.
如果include布局复杂,module.modulemap可以在里面提供自定义include.如果无法按照上述规则生成模块映射,SwiftPM将会出错.
对于可执行的目标,只有一个有效的C语言主文件是允许即是无效的必须main.c和main.cpp同一个目标.
唯一另一个重要的事情是#import,一旦将其编译为兼容模块,您实际上是如何在C代码中完成的.如果您使用import/Foo/Foo.h您需要使用的组织#include <Foo/Foo.h>,如果您使用,则import/Foo.h可以使用#import "Foo.h".