Collecting SwiftPM plugin ideas for the server (but not only) ecosystem

Okay, after taking a closer look at your Package.swift file and the internals of sqlite2swift executable target, I see that your target simply doesn't have any dependencies that would not build for iOS. You are parsing command line arguments manually relying on the API from the Swift standard library and Foundation framework. Yet, if you were to use Swift Argument Parser, then your target would no longer build for iOS, because this package does not support iOS. Given how many popular projects already make a use of Swift Argument Parser, e.g. SwiftGen and SwiftLint, I still consider it to be quite a limitation.

That analysis sounds wrong because the tool still needs to be built as a macOS tool, not iOS. My assumption is still that Xcode is clever enough to know that the plugin and tool need to run on macOS, not as an iOS one. Regardless of the dependencies.
I'll see whether I can give that a try and repro your issue.

(BTW: I intentionally did not use the arg parser because it produces HUGE tools, just for arg parsing, IIRC).

P.S. Would be easy to add iOS support to the arg parser, if that's what is needed?

You are right that Xcode definitely needs to build the tool for the architecture matching the host machine in order for it to run, but the question is if it reasonable to also build the tool and its dependencies for iOS? Because from my experience this is exactly what happens and it doesn't seem to be the expected behavior.

I have one more lead, are you using Mac with Apple silicon or Intel chip? I will try to clone your repo with example iOS app and build it on my machine with Intel chip. We will see how it goes.

I only tried on M1, but I would be really surprised if this runs in the emulation.

Which of your example apps is showcasing the use of Enlighter build tool plugin specifically?

All of them. The most straight forward is the (Solar) Bodies one.

Okay, I installed Xcode 14 Beta as required by your project and it seems to be building just fine on Mac with Intel chip. It also appears that with the new version of Xcode the executable targets gained the possibility to be built for arm64 architecture (seems to work with both Swift 5.6 and Swift 5.7 toolchains). Also, Swift Argument Parser now builds successfully for arm64 architecture when added as a dependency. To conclude, we can consider one of the issues that I described to be fixed once the Xcode 14 gets officially released. I will update my original post to reflect that finding.

1 Like

Ah cool. Yes, Xcode is always a bit flaky with SPM. Just want to point out that Xcode 14 is only required for the build plugin. (and this was a new WWDC 2022 feature in Xcode, hence the requirement, it may work with earlier SPM builds.)
The tech itself works for anything Swift 5+ I think.

I think it is save to assume that plugins (and dependencies) are built and run for the host platform (which may very well be different to the target platform).
This is a little different to other cross compilation issues.

What other issues do you have?

1 Like

I was a little bit busy last week, but just to clarify for the future readers of this thread, the build tool plugins were introduced in Swift 5.6 toolchain as part of the SPM extensible build tools API way back in March 2022, and as such this type of plugins is supported from Xcode 13.3 onwards (see official release notes). For this reason, there is nothing to stop you from using build tool plugins with Swift 5.6 and Xcode 13.4.1 (current stable), but you should take into account the limitation described above (see my original post). If, however, the distribution with artifact bundle is not an option for you and you need to stick to the executable target approach, then it is advised to upgrade to Swift 5.7 toolchain and use Xcode 14 RC instead. Whether or not the issue was solved for good is to be seen once Xcode 14 is officially released.

1 Like

Another improvement idea I have is to supplement the SourceModuleTarget from PackagePlugin API with excludedFiles read-only property, that would return a list of all the files that have been excluded in the manifest. Currently, there is only the sourceFiles property, which returns a file list skipping the excluded files. I think that it is pretty reasonable for the build tool plugin user to explicitly exclude the configuration file in the manifest to make it clear that such a file is not bundled with the package. Such an approach follows the official SPM resources guidelines, which say:

In general, avoid placing files that aren’t resources in a target’s source folder. If that’s not feasible, avoid excluding every file individually, place all files you want to exclude in a directory, and add the directory path to the array of excluded files.

Perhaps this is not a big deal, because the limitation can be easily bypassed by using FileManager API from Foundation framework, but I still think that it would be nice to have such possibility out of the box. Also, one could argue that the configuration file can just as well be placed in the package's root directory, but then again someone could have a setup with more than one target in a single package, where each target requires its own configuration file. This could also be solved by adding support for target-specific arguments in build tool plugins (as described in earlier posts), but why not having more flexibility here?

1 Like

Still not ready for public consumption, but work in progress an a little teaser (presentation will surely change, but you get the idea):


Hope to have something in the next couple of weeks that can be shared.

The test code looks like thus:

10 Likes

Here's a link to the announcement:

4 Likes