Swift 包管理器 C-interop:Non-system 个库

Swift Package Manager C-interop: Non-system libraries

我如何使用 Swift 包管理器来包含 C 代码(在我的例子中,一个 .c 文件和一个 header 文件)没有 要求用户将我的 C 库安装到 /usr/local/lib?

我曾想在包含 header + lib 的主包的子目录中创建一个包,并使用相对路径,最后使用 swift build -Xlinker ./relative/path/to/mylib 构建,但是我没有解决依赖关系的任何成功,因为它应该是一个独立的 git 存储库。错误信息是:

error: failed to clone; fatal: repository '/absolute/path/to/mylib' does not exist

此外,我不清楚使用 -Xlinker 标志是否是正确的方法。

我不能将桥接 header 与纯 SwiftPM 方法一起使用,安装我的库 system-wide 似乎有点过分而且不太便携。

有什么想法吗?

我已经在 github 的 this project 中做到了。它通过将 pthread_once_t 包装在 C 中并将其 re-exposing 替换为 swift 来替换它。这是一个有趣的练习,可以绕过 Swift 试图限制你的东西,因为 pthread_once_tdispatch_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"]),
        ]
)

您可以轻松地将产品库替换为可执行文件。主要部分是产品的目标需要包含构建所需的 C 和 Swift 目标。

然后在您的目标部分中,使 swift 目标将 C 目标列为依赖项。


您可以在 SwiftPM Usage.md here

中了解有关 C 目标所需布局的更多信息

C 语言目标

C 语言目标类似于 Swift 目标,除了 C 语言 库应该包含一个名为 include 的目录来保存 public headers。

要允许 Swift 目标导入 C 语言目标,请添加一个目标 清单文件中的依赖项。 Swift 包管理器将 为这些的每个 C 语言库目标自动生成模块映射 3 例:

  • 如果include/Foo/Foo.h存在且Foo是目录下的唯一目录 包含目录然后 include/Foo/Foo.h 成为保护伞 header.

  • 如果 include/Foo.h 存在且 include 不包含其他子目录,则 include/Foo.h变伞header.

  • 否则如果include目录只包含header个文件而没有其他 子目录,它成为伞目录。

如果布局复杂 include,可以自定义 module.modulemap include 内提供。 SwiftPM无法生成会报错 a modulemap w.r.t 上面的规则。

对于可执行目标,只允许一个有效的 C 语言主文件,即它 main.cmain.cpp 在同一个目标中是无效的。


唯一重要的事情是,一旦 C 代码被编译为兼容模块,您如何实际执行 #import。如果您使用 import/Foo/Foo.h 组织,则需要使用 #include <Foo/Foo.h>,如果您使用 import/Foo.h,则可以使用 #import "Foo.h".