使用 Swift 包管理器和 libevent 干净地处理 /usr/local/

Cleanly handling /usr/local/ with Swift package manager and libevent

我的项目中有 2 个依赖项 libeventlibressl。两者都安装在本地(分别在/usr/local/include/usr/local/opt/libressl/include下)

我希望实现的是让 SPM 自动理解在这些目录中进行搜索。

我知道我可以将标志传递给 swift build 以实现此目的;但我的最终目标是我可以从命令行正确生成 xcode 项目,而不必不断地在 Xcode.

中添加自定义构建标志

我很确定这是可能的,因为我不必输入 PostgreSQL 的自定义设置。

Swift-工具版本为 4.0.x

Package.swift供参考:

// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "CEvent",
    providers: [
        .brew(["libevent"]),
        .apt(["libevent-dev"])
    ],
    products: [
        // Products define the executables and libraries produced by a package, and make them visible to other packages.
        .library(
            name: "CEvent",
            targets: ["CEvent"]),
        ],
    dependencies: [
    ],
    targets: [
        .target(
            name: "CEvent",
            dependencies: []
        ),
    ]
)

模块图:

module CEvent [system] {
    header "shim.h"
    link "event"
    export *
}

我当前的构建脚本(build.sh):

#!/usr/local/bin/fish
swift build -Xcc -O0 -Xcc -fblocks -Xswiftc -lbcrypt -Xswiftc -I/usr/local/include -Xswiftc -L/usr/local/lib -Xswiftc -ltls -Xswiftc -lcrypto -Xswiftc -lssl -Xswiftc -L/usr/local/opt/postgresql/lib -Xswi$

至于我想要这个的原因。如果我在 swift 中 add/update/remove 依赖项,我想生成一个新的 xcode 项目,而不必在各自的构建机器上修复它的设置;以及 apt/ubuntu /usr/lib 代替。

好吧,我在分析其他项目(特别是 IBM-Swift/CLibpq)时忽略的事情似乎正在使用工具 pkg-config,这不是我个人以前接触过的东西。

pkg-config 查看 /usr/lib/pkgconfig /usr/share/pkgconfig 和构建过程中使用的配置文件的本地变体。

在 Package.swift 中,在 name 参数之后您需要插入一些内容,例如:

let package = Package(
    name: "CEvent",
    pkgConfig: "libevent",

我发现的一些注意事项:

  • 我正在使用的 bcrypt 库在 makefile 中没有完整的安装或构建,所以我使用在 swift4 PM 中找到的新选项编译它,而不是在此处找到:BCrypt example on github and the Swift docs for more help here: SPM API Redesign
  • 在 Homebrew 中找到的 LibreSSL 不会在系统上安装它的 pkgconfig;因此,手动添加它或从源代码编译 LibreSSL-portable 是最简单的,或者在我看来最好的维护方式。

今天对我来说整体学习体验很棒。

您在回答中发现并记录的内容是一个良好的开端,但还不是全部。是的,SwiftPM 使用 pkg-config 来确定某些库的安装位置。是的,SwiftPM 使用 pkgConfig 名称,它将传递给 pkg-config。然而,搜索路径有点复杂。在 macOS 上,它使用以下列表作为 base search path:

然而 SwiftPM 不使用 pkg-config 命令,而是直接解析 .pc 文件。通过在你的包上设置 pkgConfig 参数,它知道在上面列出的路径中寻找什么文件名。而且,对于您回答中的示例,故事到此为止。如果找到 libevent.pc 文件 parses that file,返回的任何标志都会传递给编译器和链接器。

但是,如果您要定义包提供程序,例如:

providers: [
    .Brew("libsodium"),
    .Apt("libsodium-dev")
]

然后 SwiftPM 根据其构建平台的包提供者添加额外的搜索路径。继续 macOS 的例子,SwiftPM 将 运行 brew --prefix。如果这个returns一个路径,下面的路径就是added as a additional search path

  • [brewPrefix]/opt/[packageName]/lib/pkgconfig

在我的 libsodium 示例中,SwiftPM 现在能够推断库的位置,而根本不需要 brew link 或符号链接。在我详细的构建输出中,它列出了我地窖中的 libsodium 库路径:-L/usr/local/Cellar/libsodium/1.0.11/lib.