I have 2 dependencies in my project libevent
and libressl
. Both of which are installed locally ( respectively under /usr/local/include
and /usr/local/opt/libressl/include
)
What I am looking for to achieve is for SPM to automatically understand to search in those directories.
I know I can pass flags to swift build to achieve this; but my ultimate goal is that I can properly generate xcode projects from the command line without having to constantly add custom build flags in Xcode.
I'm pretty sure it is possible, since I do not have to enter the custom settings for PostgreSQL.
Swift-tools version is at 4.0.x
Package.swift for reference:
// 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 map:
module CEvent [system] {
header "shim.h"
link "event"
export *
}
And my current build script ( 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$
As for the reason that I want this. If I add/update/remove dependencies in swift I want to generate a new xcode project, and not have to fix its settings on respective build machines; as well as apt/ubuntu /usr/lib instead.
Alright so the thing I ignored from analysing other projects ( IBM-Swift/CLibpq in particular ) seems to be making use of the tool
pkg-config
which is not something I personally ever touched before.pkg-config looks in
/usr/lib/pkgconfig
/usr/share/pkgconfig
and the local variants for config files used in during the build process.Inside Package.swift, after the
name
parameter you need to insert something for example:Some caveats I discovered with this:
Overall great learning experience for me today.
What you've found out, and documented in your answer, is a good start but not the full story. Yes, SwiftPM uses
pkg-config
to determine where certain libraries are installed. Yes, SwiftPM uses thepkgConfig
name which it'll pass on topkg-config
. However the search paths are a bit more involved. On macOS it uses the following list as a base search path:/usr/local/lib/pkgconfig
/usr/local/share/pkgconfig
/usr/lib/pkgconfig
/usr/share/pkgconfig
PKG_CONFIG_PATH
environment variableHowever SwiftPM doesn't use the
pkg-config
command, but instead parses.pc
files directly. By setting thepkgConfig
parameter on your package, it knows what filename to look for in the paths listed above. And, for the example in your answer, the story stops here. If there's alibevent.pc
file found it parses that file, and any flags returned are passed on to the compiler and linker.However if you were to define package providers, e.g.:
Then SwiftPM adds additional search paths depending on the package provider for the platform it is building for. Continuing the example of macOS, SwiftPM will run
brew --prefix
. If this returns a path, the following path is added as a additional search path:[brewPrefix]/opt/[packageName]/lib/pkgconfig
In my example of
libsodium
, SwiftPM is now able to infer the location of the library without requiringbrew link
or symlinks at all. In my verbose build output it lists thelibsodium
library path in my cellar:-L/usr/local/Cellar/libsodium/1.0.11/lib
.