Thanks for the detailed explanation! I have a few more questions if you don't mind
You don't really know what package Bar is going to resolve at for your clients
Why is that? Once the dependency graph is resolved, this question is answered.
and since SemVer means API stability but not ABI stability, it's not safe to cache build products of Bar at a particular version in that range.
Can you elaborate on this? I think it's perfectly fine to cache build product per toolchain version in case the binary is not ABI stable. In case it is, then no issue there.
In this case, we have different problems to solve. We need a manifest API to declare how binary artifacts are laid out and where to fetch them from.
Why not use the same format to describe the cache? I would not assume the cache is system global or even lives on the same system where swiftPM is running. I would have a 2 level cache system, remote & local (system global). This is particularly important to achieve what in my opinion is the most important goal, never build a binary again if it has been built somewhere in the world.
Another problem is if these packages vendor or declare dependency on another package, this effectively means SwiftPM can only resolve to a single version if the other package appear multiple times in the graph
To my understanding this is the case already even for source.
Or, you could be in a worse situation if the prebuilt binary statically links a package that you're also using in your app.
I see the problem here. Wouldn't it work to just distribute as relocatable object file without linking performed?
Sure, you could use this for build caching but it'll be much better to have a separate feature for that.
I would rather prefer to use the same building blocks and all information made explicit and accessible. Any piece of information that is not in the manifest but is private knowledge of swiftPM will effectively prevent others from building tools that supplement swiftPM.