Shadowman
Shadowman

Reputation: 12079

Swift 4: Local Dependencies with Swift Package Manager?

I'm in the process of porting a fairly large codebase from Java to server-side Swift 4. The code itself will be developed on macOS, but eventually deployed on Linux. I have created separate module projects using the Swift Package Manager. Several of these are library projects, with the final being an executable to tie them all together to launch. I've generated Xcode project files for each module so that I can easily develop in Xcode, and I've created an Xcode Workspace to group them all together into one view.

My problem is, how do I indicate dependencies between these local modules? My executable module will obviously depend on all of the library modules. How do I represent this in my Package.swift file? I've tried something like this...

let package = Package(
    name: "MySwiftExe",
    dependencies: [
        //.package(url: "../MySwiftLib", from: "1.0.0"),

...

But that fails to build. Is there a way to specify dependencies located on the same filesystem? Or am I required to grab the dependencies from Git?

Upvotes: 4

Views: 3520

Answers (4)

Nick
Nick

Reputation: 479

Let's imagine that you have the following folder structure:

    ├──MySwiftExe/
    |  ├──Sources/
    |  |  ├──MySwiftExe.swift
    ├──Modules/
       ├──MySwiftLib/
          └──Sources/
             └──MySwiftLib.swift

The Swift Package Manager allows us to use relative paths for integrating dependencies, as shown below:

let package = Package(
    name: "MySwiftExe",
    dependencies: [
        .package(path: "../Modules/MySwiftLib"),
    ]
)

Upvotes: 0

user3099609
user3099609

Reputation: 2318

According to docs there's the package(path: String) function that can be used to define a local dependency.

One thing to mention is that in case the package provides multiple targets and your project is configured to only use some of those targets:

...
dependencies: [
    .package(name: "MyPackage", url: "[email protected]:path/to/package.git", .exact("ver.si.on")),
]
...
targets: [
    .target(
        name: "MyTarget",
        dependencies: [
            .product(name: "SpecificTargetName", package: "MyPackage"),
        ],
    ),
]

Then for that to work locally the package definition deeds to declare the name as well (the path is not enough):

.package(name: "MyPackage", path: "/local/path/to/package"),

Upvotes: 0

Sam
Sam

Reputation: 2456

Your URL can be relative, so ../MySwiftLib is perfectly valid. However, the source directory must be a git repository. It is recommended that this repo be tagged, but you can also do:

.package(url: "../MySwiftLib", .branch("master"))

if you want to use whatever code is on the master branch.

Hope this helps!

Upvotes: 4

leanne
leanne

Reputation: 8749

Set the url value to file:///path/to/swiftlib:

let package = Package(
name: "MySwiftExe",
dependencies: [
    .package(url: "file:///path/to/MySwiftLib", from: "1.0.0"),

...

Upvotes: 2

Related Questions