How to Make a Local Module with the Swift Package Manager

Can I make a local module with the Swift Package manager?

You can reference a local directory in your Package.swift file, but it must be a Git repository. Also, initializing the repo, committing, and tagging is not sufficient; the repository must be pushed to a remote for swift build to function correctly.

According to the SwiftPM Usage Guide:

Packages are Git repositories, tagged with semantic versions, containing a Package.swift file at their root. Initializing the package created a Package.swift file, but to make it a usable package we need to initialize a Git repository with at least one version tag.

The Swift Package Manager Documentation also states that "you can specify a URL (or local path) to any valid Swift package" and provides an example Package.swift with a local file reference: .Package(url: "../StringExtensions", "1.0.0").

Note: I edited the answer to clarify that Swift Package Manager can reference a local path, but the path must contain a valid Git repository with a tag. My original test project pointed to a dependent local path that contained a .git directory, and so it successfully built with swift build.

How to create package from existing project with Swift Package Manager?

I think SPM is the way to go currently, cause you can easily handle versioning for the package.

You can create a new package locally in a different directory which you'll later add as a new repository.

Then move all the contents you want into that package. Don't forget to set the access to public so it will be accessible from the consumer applications. Also go to your project settings and in the tab Package Dependencies, click the plus button to add a new package, click on the add local and choose your newly created package. Also go to the target settings and add the package in Frameworks, Libraries, and Embedded Content section.

For your Package file you would get something like this where you'll need to setup the platforms you'll use it with, my example package is named SPM1.

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

import PackageDescription

let package = Package(
name: "SPM1",

platforms: [
.iOS(.v13) // set your minimal version here
],

products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "SPM1",
targets: ["SPM1"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "SPM1",
dependencies: []),
.testTarget(
name: "SPM1Tests",
dependencies: ["SPM1"]),
]
)

In your application, do the import like so:

import SPM1

And start using your new package.

Once everything is OK, you can add your package in a new git repository. Don't forget to version your package in the format X.Y.Z (like 1.0.0) by tagging your commits. Go back to the project settings and add the URL + the branch or version (tag).

You can use both locally and remotely. The advantage of having it locally is the agility to build and run quickly when developing.

I hope that helps! :)

Swift Package Manager: How to add local shared library as dependency to multiple executables?

This should do it. You don't need to add a "dependency" to a target where all the sources are on your local computer.

// swift-tools-version:5.3

import PackageDescription

let package = Package(
name: "dmx-db",
products: [
.executable(name: "DmxServer", targets: ["DmxServer"]),
.executable(name: "DmxClient", targets: ["DmxClient"]),
// This lib will be imported into both, client and server.
.library(name: "DmxLib", targets: ["DmxLib"]),
],
dependencies: [
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0-alpha.21"),
.package(url: "https://github.com/codewinsdotcom/PostgresClientKit", from: "1.0.0"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "1.0.0-alpha.5"),
],
targets: [
.target(name: "DmxServer", dependencies: [
"DmxLib",
.product(name: "GRPC", package: "grpc-swift"),
.product(name: "PostgresClientKit", package: "PostgresClientKit"),
.product(name: "Lifecycle", package: "swift-service-lifecycle"),
]),
.target(name: "DmxClient", dependencies: [
"DmxLib",
.product(name: "GRPC", package: "grpc-swift"),
]),
.target(name: "DmxLib", dependencies: []),
]
)

This does require that you have a Sources directory in the root directory of your package, and inside it you have three folders, named DmxLib, DmxClient, and DmxServer, respectively.

Note: I've actually updated the swift-tools-version to 5.3, because I copied and modified this from one of my projects, but I think it should work with a swift-tools-version of 5.2

Swift Package Manager, adding local dependencies

You also need to declare Module1 and Module2 as targets.

targets: [
Target(name: "App", dependencies: ["Module1", "Module2"]),
Target(name: "Module1"),
Target(name: "Module2")
],


Related Topics



Leave a reply



Submit