4

Let's say I make a project "Bar", like so:

~ $ mkdir Bar
~ $ cd Bar/
Bar $ swift package init --type library
Bar $ git init .
Bar $ git add .
Bar $ git commit -m "Initial commit"
Bar $ git tag 1.0.0
Bar $ swift build

If I then try to i) use a 3rd party dependency (let's say Alamofire/Alamofire), then try to ii) import that dependency or iii) the project module in the repl, I get a load error.

$ swift

  1> import Bar
error: repl.swift:1:8: error: no such module Bar'
import Bar
       ^

  1> import Alamofire
error: repl.swift:1:8: error: no such module 'Alamofire'
import Alamofire
       ^ 

How do I load my Swift Package Manager project + its dependencies in the Swift repl?

Nutritioustim
  • 2,686
  • 4
  • 32
  • 57
  • Maybe this helps: https://stackoverflow.com/questions/27872589/swift-repl-how-to-import-load-evaluate-or-require-a-swift-file ? – Eric Aya Feb 14 '18 at 10:17
  • Thanks @Moritz, that sheds some light. These two approaches still both give the same error though. `swift -F .build/checkouts/Alamofire.git-6801331143877184500/` and `swift -I .build/checkouts/Alamofire.git-6801331143877184500/`. – Nutritioustim Feb 14 '18 at 21:51
  • I've finally found a solution, check my answer. – Eric Aya Feb 15 '18 at 19:12

1 Answers1

6

These are the steps to follow for a solution using Swift 4.

Create a folder, let's say "TestSPMLibrary":

$ mkdir TestSPMLibrary
$ cd TestSPMLibrary

Create a library package:

$ swift package init --type library

In the "Package.swift" file, add the ".dynamic" library type.

You can also add a dependency such as Alamofire (you need to also add it to the target).

My "Package.swift" example:

// swift-tools-version:4.0

import PackageDescription

let package = Package(
    name: "TestSPMLibrary",
    products: [
        .library(
            name: "TestSPMLibrary",
            type: .dynamic,
            targets: ["TestSPMLibrary"]),
    ],
    dependencies: [
        .package(url: "https://github.com/Alamofire/Alamofire.git", from: "4.0.0"),
    ],
    targets: [
        .target(
            name: "TestSPMLibrary",
            dependencies: ["Alamofire"]),
        .testTarget(
            name: "TestSPMLibraryTests",
            dependencies: ["TestSPMLibrary"]),
    ]
)

In this library the code you want to interface with has to be declared public (and objects need a public initializer).

My "TestSPMLibrary.swift" example:

public struct Blah {
    public init() {}
    public var text = "Hello, World!"
}

Build the library:

$ swift build

Launch the REPL with swift -I .build/debug -L .build/debug -l and add the library name. In my case:

$ swift -I .build/debug -L .build/debug -lTestSPMLibrary

In the REPL you can now import your library (and its dependencies):

import TestSPMLibrary
import Alamofire

let x = Blah()
print(x.text)
Eric Aya
  • 69,473
  • 35
  • 181
  • 253