使用 Swift 包管理器和 libevent 干净地处理 /usr/local/
Cleanly handling /usr/local/ with Swift package manager and libevent
我的项目中有 2 个依赖项 libevent
和 libressl
。两者都安装在本地(分别在/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:
/usr/local/lib/pkgconfig
/usr/local/share/pkgconfig
/usr/lib/pkgconfig
/usr/share/pkgconfig
PKG_CONFIG_PATH
environment variable
然而 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
.
我的项目中有 2 个依赖项 libevent
和 libressl
。两者都安装在本地(分别在/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:
/usr/local/lib/pkgconfig
/usr/local/share/pkgconfig
/usr/lib/pkgconfig
/usr/share/pkgconfig
PKG_CONFIG_PATH
environment variable
然而 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
.