Reputation: 29320
I have a swift package manager library with multiple targets and one product.
Its Package.swift
looks something like this:
let package = Package(
name: "FooPackage",
products: [
.library(
name: "FooLibrary",
targets: ["FooLibrary"]),
],
dependencies: [],
targets: [
.target(name: "FooHeaders"),
.target(
name: "FooLibrary",
dependencies: [
"FooHeaders"
],
path: nil,
exclude: [],
sources: nil,
resources: nil,
publicHeadersPath: "include",
cSettings: nil,
cxxSettings: nil,
swiftSettings: nil,
linkerSettings: [
.linkedLibrary("/path/to/libfoo.a")
]
),
.testTarget(
name: "FooTests",
dependencies: [
"FooHeaders",
"FooLibrary"
],
path: nil,
exclude: [],
sources: nil,
cSettings: nil, cxxSettings: nil, swiftSettings: nil,
linkerSettings: nil)
]
)
I also have a directory structure that looks like this:
Now my issue is that whenever I run swift test
, I get the following error message on Mac:
Building for debugging...
ld: library not found for -l/path/to/libfoo.a
[0/1] Linking FooTests
error: fatalError
Note that I specify the path to libfoo.a from root. Oddly enough, running swift build
does work on Mac, though it seems that that is merely a compilation step, and does not do any linking.
However, when I compile the shared library on a Linux machine, be it physical or inside Docker, with everything else being exactly equal, there, swift test
does work. That seems to be the case on both Debian and Ubuntu; I haven't tried testing other operating systems yet.
What could be going wrong, and what am I doing wrong? I have looked at a bunch of similar posts on StackOverflow, though nobody appears to have their project in a state where the compilation and running actually does work – just not on Mac. I would also like to stress that I am not using Xcode; instead, all of this is compiled straight from the command line.
Also, if that's any help, the shared library is compiled from a Rust project. I simply run cargo build
and copy the library inside target/debug
into the Libraries
folder in my project, whereto the path is specified in Package.swift
.
Some things I tried doing was using the same linker settings in both the standard target, as well as the test target. I also tried using the .dylib extension on Mac instead of .a (cargo build
generates both), as well as removing the file extension altogether, and I have also tried various experiments with specifying the path relative to the root folder of the project, and various folders within it. So far, all to no avail.
Upvotes: 1
Views: 631
Reputation: 29320
I believe I have figured it out, and the solution is as follows.
In Package.swift
, add this snippet in the beginning:
var linkerSettings: [PackageDescription.LinkerSetting] = [.linkedLibrary("/path/to/libfoo.a")]
#if os(macOS)
linkerSettings = [
.unsafeFlags(["-L/path/to/"]),
.linkedLibrary("foo")
]
#endif
And then, where it used to say
linkerSettings: [
.linkedLibrary("/path/to/libfoo.a")
]
replace that code with
linkerSettings: linkerSettings
instead.
Upvotes: 1