Swift-Syntax Prebuilts for use in iOS apps at run-time?

It seems, per [Preview] Swift-Syntax Prebuilts for Macros , that Swift-Syntax Prebuilts are expressly intended to allow uses for macros. If an iOS library depends on Swift-Syntax for doing things at run-time, then it seems the toolchain will ignore the pre-built and build Swift-Syntax from source.

In my case, the run-time use is in service of unit tests (specifically, pointfreeco/swift-macro-testing), and does not run on users' devices.

I believe this is related to Prebuilts for all host targets by dschaefer2 · Pull Request #9905 · swiftlang/swift-package-manager · GitHub , but not exactly the same thing. That PR says "Add support for prebuilts for all targets that build for host." But I think that would exclude iOS, right?[1]

  1. Am I correct that the above PR is related but not exactly the same as my issue?
  2. Is the issue I'm raising here, about including prebuilts for iOS (at least simulators, if not devices), something that…
    1. …is supposed to be supported now?
    2. …is intended to be supported in the future?

I can supply a reproducing project if anything is unclear, or if I'm missing some nuance, but I wanted to get a high-level vibe check first.

(Edit: removed a claim about which things use the prebuilts because I think I had it wrong, but the overall question still stands.)


  1. Unless you're doing this all in the context of Swift Playgrounds or a hypothetical Xcode for iPad, I guess, but I'm just talking about using Xcode on macOS to build iOS apps. ↩︎

1 Like

Hi,

Macros don’t have runtimes they are expanded during compilation (you can very well copy paste, renames $ prefixed symbols and keep it working without macro). So they run where you compile code, unless you are making a compiler hosted on iOS (which i think Apple doesn’t allow) you don’t expand macros there. Prebuilts should work without you doing anything but if it isn’t the case look at your exact version of swift and then check whether prebuilts are available for it. Sometimes they aren’t readily available or even removed when there were buggy or something. Hope I’m not answering wrong as this is pretty much accumulated by experience having them working sometimes but not always :)

Thanks for your reply. In this case, the test library in question is using Swift-Syntax at run time to parse the syntax of the test source file in order to make changes to the file itself during the test run, to capture inline textual snapshots of the subject under test.

Ha gotcha sorry for the noise then

@dschaefer2 I was told you might be the one to ping about this thread :folded_hands:

We currently don't have plans to support prebuilts for cross compilation. There are efforts underway to support build caching which is probably a better general solution.

2 Likes

@dschaefer2 I have come across a related (but not exactly the same) issue to what is brought up here while investigating Zev's inquiry (I maintain the open source libraries he is having problems with).

It seems that Xcode will bail out of using prebuilts if there is an even whiff in the air of a non-macro target depending on SwiftSyntax. The way we have run into this is by vending "macro support" libraries in some of our packages that allow external packages to expand/customize our macros. Such support targets are only ever depended on by macro targets (never regular targets), yet Xcode seems to misinterpret this fact and decides to build SwiftSyntax from scratch. Importantly, SPM does not have this problem. SPM will correctly see that the support target is only used from macro targets and use the prebuilts.

I know that this behavior being specific to Xcode may mean a Feedback should be filed, but since more and more of the build infrastructure between Xcode and SPM is being shared I wondered if maybe there is a public repo I could file an issue? I have a very simple reproducing example project. Further, enabling the new IDEEnableNewPackagePIFBuilder feature does not seem to have an affect on this problem.

Oh, yeah. SwiftPM proper will too. Most of that algorithm was to fix crashes which were happening when libraries were built with prebuilts but then linked with libraries that didn't. The current algorithm is very careful about that mixing and will turn everything off if it gets scared.

The good news is that by allowing for builds by any target built for host, that will address these issues since that mixing can't happen. That is one of the features I'm working on now for the next release and have a prototype up as I mentioned in my recent forum post. And you get the benefit of using SwiftSyntax prebuilts for build plugin tools which has also been a common complaint.

I just can't use it for cross compilation since we download the prebuilts during package resolution and don't know what build requests are going to be sent in.

But that is actually not the case. SwiftPM handles this kind of macro support target just fine:

There is a very clear difference in behavior between Xcode and SwiftPM in this situation. I have a very simple project that reproduces the problem. Is there a public repo I could file an issue?

There should be no differences. Prior to 6.4, they used different build systems which may have an impact. Again, it's very fragile and I'm working to fix that in 6.5.

Is there any interest in the reproducing project so that any changes can test against this exact use case?

Of course, but as you mentioned, if it doesn't work in Xcode but does in SwiftPM CLI, then raise it through Feedback so we can track it properly.

Ok, done FB25032548. And if anyone else wants to see the project I have put it up here:

GitHub - pointfreeco/xcode-swift-syntax-prebuilts-bug: Xcode does not use SwiftSyntax prebuilts under certain situations, whereas SwiftPM does. · GitHub.

1 Like

Thanks!