Running SPM from source

I'd like to fix a small bug in SPM and would like to run it from source.

So I've opened the swift-package-manager package in Xcode and ran the swift-run target.

This throws an error in SwiftTool.swift, error: Could not find Package.swift in this directory or any of its parent directories.

I guess this is because I haven't passed a manifest file for the tool to build? If so, how can I actually pass something to it? I've tried to pass a path to a local directory that has a valid swift package but I got the same error.

You should set Working Directory in Schemes > Run > Options to the package you’d like to test with. Alternatively, set the arguments --package-path /path/to/your/package in Schemes > Run > Arguments.

1 Like

@stevapple Thanks for your response!

I'm trying to implement your second suggestion:

image

This produces the following error when I run:

'my-package': e[31me[1merror: e[0minvalidManifestFormat("/path/to/Package.swift:2:8: error: no such module 'PackageDescription'\nimport PackageDescription\n ^", diagnosticFile: nil)

What am I doing wrong?

Hmmm have you tried to build the entire SwiftPM (most notably the PackageDescription target) before running swift-build?

Yes.

This seems to be the case.

In addition to @stevapple's solution, maybe running it from the command line could work?

If you built the target using Xcode, then the executable can be found under DerivedData/, and if you built it using SwiftPM directly (in command line), then it can be found under .build/.

That won't work for me as I'm trying to run it with the Xcode debugger attached.

Could someone please clarify what are the steps needed to run swift-package-manager's swift-run target with a local package?

Primarily, the dynamic libraries need to be up‐to‐date and locatable by swift-run without the real toolchain cutting in.

My workflow usually consists of this:

# Make sure all build products are present.
swift build

# “swift run swift-run” often does not work because they eat one another’s flags in weird ways.
.build/x86_64-apple-macosx/debug/swift-run --package-path /some/package/to/experiment/with

If I find myself doing it over and over again, I usually create an alias.

I haven’t tried it with Xcode’s debugger, but I assume it should work if you convert the first line to a script build phase and the second line to the working directory, executable, and flags of a custom configuration.


Alternatively, you can add your target package alongside the other ones in the Fixtures directory and look in Tests/FunctionalTests/MiscellaneousTests.swift for examples of how to interact with it inside a unit test.

2 Likes

+1

This happens to me relatively often when working on complex, unfamiliar projects, and personally I find that starting with tests is the simplest way to get started.

As a bonus - tests are typically written in such a way that they control all the inputs and start from a neutral state every time, so it's a really nice, repeatable environment to experiment in. And once you're ready to send a PR, the tests are already done :sunglasses:

2 Likes

Thanks for the suggestions. I'll give that a go and will keep you posted.