SwiftPM always rebuilds command plugins in release configuration

So, short background:

I have a command plugin that has a tool as a dependency that performs the heavy work.

I extract the tool from the command line plugin using:

        let benchmarkTool = try context.tool(named: "BenchmarkTool")
        print("\(benchmarkTool.path)")

This gives the path:

.../package-benchmark/.build/arm64-apple-macosx/debug/BenchmarkTool

Now, this is getting the tool with the same build configuration that the command plugin is built with (debug), which was running pretty slow, so I wanted to get the dependency as a release built tool.

So, I specify the release configuration:

swift package -c release benchmark export percentiles delta

and this gives

.../package-benchmark/.build/arm64-apple-macosx/release/BenchmarkTool

Great. The only problem here is that SwiftPM will rebuild basically everything each time I would use that invocation (this does not happen with debug builds).

So what would be the appropriate way to get the desired behaviour?

Only workaround I can think of right now is to replace the 'debug' from the context.tool path with 'release' - does not inspire a clean feeling unfortunately (I have programatically built the tool, so I know it will exist as a release built artifact and it works fine).

Any other ideas how to do this? (or should I just file an issue that benchmark plugins seem to be rebuilt with -c release, or is that expected behaviour ?)

Not sure if this is what you are looking for.
Packaging up the executable (built in release configuration) and integrating it as a binary target ( a .artifactbundle )works well for me.

It does introduce more complexity though.

2 Likes

Thanks, will need to check it out - it seems like a fairly common thing to want to drive the command line tools in release mode from the plugin (same for e.g. DocC I suppose), so it'd be nice with something more straightforward.

Yeah definitely agree.
In general i would like some easy way to swap out a source-code-target with a prebuilt artifact.

For other people struggling with this, I also can point out to replace 'debug' from the context.tool path doesn't work when doing this from an 'external' package depending on the package with the tool in question, so that fails. I'll need to see if using an .artifactbundle works for me (on linux too...) as the runtime of the tool becomes prohibitive.

Is there no way to say that you want command plugins (and their dependencies) to be built in release mode rather than debug mode? Seems like it would be desirable for what would usually be expected to be a stable helper functionality (similar to the compiler), why run e.g. the docc plugin in debug mode? (ping @NeoNacho any idea?)

1 Like