Swift Package Manager build tool plugins are a powerful mechanism to introduce code generators into SwiftPM builds. Currently, however, developers are running into limitations that have been put in place, in particular around the generation of C/C++ header files, module maps and API notes that allow for a code generator to fill out the definition of a C module from the generated code.
An example of this is the Swan library that provides a Swift interface to the Dawn WebGPU library. Dawn has a JSON file that describes its API and Swan generates the API notes that allows this API to be easily consumed from Swift. The API notes needs to be in the same directory as the modulemap which then refers to a generated C header file that brings in the Dawn headers. Ideally these are all generated at build time and incorporated into the SwiftPM build to ensure they line up with the desired version of Dawn. However due to the restrictions, Swan has a command plugin to generate the code which is then checked in. Not ideal.
This pitch is to relax those restrictions and ensure the generated files are properly incorporated into the build. In order to publish the module to downstream targets, they would need to be placed in a public header directory, just as regular source does for a C module. For this next release, weāll hard code that as the include directory in the plugin output directory. Future work will allow this directory to be named in a build setting associated with the plugin.
Itās not fully clear to me why this restriction was put in place, except for the awkwardness over the public header files. But this short term solution should remove this blocker for those who need to generate these files.
Iām preparing a PR, #9252, and will produce an Evolution proposal based on feedback to this pitch. Your thoughts on this would be greatly appreciated.
Ah, so this is a more general-purpose diagnostic re unexpected files thatās not doing a useful thing when it comes to certain C artifacts? (My impression from the original write-up was that there was some sort of deliberate ruleset drawn up about C artifacts.)
Chestertonās fence, as I understand it, is the notion that before removing an apparently not useful barrier one ought to identify the use it was intended for. In this case, it would be a matter of figuring out if there could be a reason for the restriction in the first place that is still applicable, which we might worry about unwittingly disturbing if weāre not sure we understand the rationale.
That said, if I understand your description correctly of what the specific ārestrictionā is, youāre speaking of a limitation of the current design rather than a deliberate barrier?
As I stated in the pitch, Iām not sure why the restriction was put in. I canāt think of an important reason why it would be needed given Swift code generation does not have the same restriction. And we have a clear use case of where the restriction is preventing good architecture with Swan.
For 6.3, all features we add need to be for both to help ensure swiftbuild achieves parity in this release. Itās actually easier in swiftbuild thanks to imparted build settings which will propagate the public header path to all consuming targets.
Not sure if this is the right place or time to do it, but I'd really like to be able to generate .o and/or .a files (eg. by running a compiler for a non-C language) and have them included in the build.
I was involved in supporting a few projects which were facing similar awkwardness as you describe in the OP, so yeah this is definitely showing up here and there. This is a great restriction to lift, thank you for looking into it
The include/ directory also sounds good, I think thatās a reasonable start.
Funnily enough, swift-java (which generates java sources) wasnāt affected by this because swiftpm just completely ignores them ā so we were āluckyā in that sense to not hit this issue in that project
That has come up. Itās at a different level of the build graph though so is a bit more complicated. Youāre essentially adding outputs to a target as opposed to inputs. But itās something Iām looking at longer term.