Update: Unfortunately, this solution will prevent you from adding the Package as a dependency to an Xcode project, as it will bitch about “The package product 'GDAL' cannot be used as a dependency of this target because it uses unsafe build flags.”

I’m pretty irritated with Apple right now.


For the last couple days I’ve been bashing my head up against macOS, Xcode, and the Swift Package Manager. I was trying to wrap the open-source C library GDAL, typically installed via something like brew install gdal, and running into this when I'd try to run the litte test program:

TestGDAL/ (main) $ swift run
ld: warning: Could not find or use auto-linked library 'gdal'
Undefined symbols for architecture x86_64:
  "_GDALVersionInfo", referenced from:
      _main in main.swift.o
ld: symbol(s) not found for architecture x86_64
[2/3] Linking TestGDAL

After some discussion on the Swift Forums, I learned a couple things. One, this is evidently a bug in Xcode on macOS, possibly security related. Two, it can be worked around by explicitly telling SwiftPM where to find dependencies with linkerSettings: [.unsafeFlags(["-L/usr/local/lib"])]):

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

import PackageDescription

let package = Package(
    name: "TestGDAL",
    dependencies: [
        .package(path: "../CGDAL"),
    ],
    targets: [
        .target(
            name: "TestGDAL",
            dependencies: ["CGDAL"],
            linkerSettings: [.unsafeFlags(["-L/usr/local/lib"])]),
        .testTarget(
            name: "Tests",
            dependencies: ["TestGDAL"]),
    ]
)

Unfortunately, it’s the client that must specify this dependency, not the library. It’s also fragile as it must be updated for each build environment.

Now, if I could just get Xcode to recognize that a Package dependency is available. It shows it as configured, but import GDAL fails to compile. Grr.