3.1.5 使用系统库依赖与 pkg-config 的示例

原文链接: https://docs.swift.org/latest/documentation/packagemanagerdocs/examplesystemlibrarypkgconfig/

3.1.5 使用系统库依赖与 pkg-config 的示例

创建一个把 libgit2 作为系统库依赖使用的命令行可执行文件包。

概述

下面的示例完整演示了创建一个依赖 libgit2 的二进制可执行文件的过程。

设置包

创建一个名为 example 的目录,并把它初始化为构建可执行文件的包:

1
2
3
$ mkdir example
$ cd example
example$ swift package init --type executable

编辑 Sources/example/main.swift,使其内容为下面这段代码:

1
2
3
4
import Clibgit

let options = git_repository_init_options()
print(options)

添加系统库目标

在 Package.swift 中添加一个使用 pkgConfig 参数查找库位置的 systemLibrary 目标。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// swift-tools-version:6.1
import PackageDescription

let package = Package(
    name: "example",
    targets: [
        .systemLibrary(
            name: "Clibgit",
            pkgConfig: "libgit2",
            providers: [
                .brew(["libgit2"]),
                .apt(["libgit2-dev"])
            ]
        )
    ]
)

上面的例子指定了两个 providers,Swift Package Manager 在需要时可以用它们来安装该依赖。

注意:对于仅在 Windows 上使用的包,应当省略 pkgConfig,因为不指望有 pkg-config 可用。 如果你不能或不想使用 pkgConfig 参数,可以在构建包时通过命令行传入 -L 标志,指定包含该库的目录路径。

1
% swift build -Xlinker -L/usr/local/lib/

这个例子遵循的约定是:模块名以 C 为前缀,其余部分沿用库名并采用小驼峰式,这符合 Swift 模块命名约定。这样你就可以创建并使用另一个更直接以该库命名的模块,由它提供围绕底层 C 函数的惯用 Swift 包装。

创建模块映射和本地头文件

在你的 example 项目中创建目录 Sources/Clibgit,并在该目录中添加 module.modulemap:

module Clibgit [system] {
  header "git2.h"
  link "git2"
  export *
}

在同一个目录中创建上面模块映射所引用的头文件 git2.h:

1
2
3
// git2.h
#pragma once
#include <git2.h>

提示:在模块映射中,尽量避免为库提供的 git2.h 头文件指定绝对系统路径。 那样做会让你项目在使用不同文件系统布局、或把库安装到不同路径的机器之间失去兼容性。

现在 example 的目录结构应当像这样:

.
├── Package.swift
└── Sources
    ├── Clibgit
    │   ├── git2.h
    │   └── module.modulemap
    └── main.swift

把系统库依赖添加到可执行目标

系统库目标完整定义好之后,你现在就可以把它用作其他目标的依赖。

例如,在 Package.swift 中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// swift-tools-version:6.1
import PackageDescription

let package = Package(
    name: "example",
    targets: [
        .executableTarget(
            name: "example",
            dependencies: ["Clibgit"],
            path: "Sources"
        ),
        .systemLibrary(
            name: "Clibgit",
            pkgConfig: "libgit2",
            providers: [
                .brew(["libgit2"]),
                .apt(["libgit2-dev"])
            ]
        )
    ]
)

运行示例

现在在 example 目录中运行 swift run 命令来创建并运行可执行文件:

1
2
3
4
5
% example swift run
Building for debugging...
[1/1] Write swift-version-3E695E30EE234B31.txt
Build of product 'example' complete! (0.10s)
git_repository_init_options(version: 0, flags: 0, mode: 0, workdir_path: nil, description: nil, template_path: nil, initial_head: nil, origin_url: nil)