Replies: 3 comments 4 replies
-
Thanks for surfacing this as an RFC @pepicrft
This is precisely what XCFrameworks are designed to address. We converted all our pre-compiled frameworks to XCFrameworks along with the Apple Silicon transition as fat binaries / frameworks can't support 2 arm64 slices (one for simulator and another for device, taking iOS as an example) whereas XCFrameworks are designed to support this.
Which were the issue? Are they general XCFramework issues or perhaps how caching configures or makes use of them? May be worth exploring solutions to this ahead of abandoning them and taking a step back to frameworks which doesn't seem to be the future direction in Xcode.
This approach used to work in the past when Macs were primarily on intel and simulator was x86_64 and devices were arm64, but now with Apple Silicon, both are arm64! To my knowledge it isn't possible to make a fat / universal binary with both.
It would be a shame to move away from leveraging the standard build phases and associated primitives like the new conditions. The main beauty of Tuist is how it generates projects that you would have manually crafted using Xcode UI, just ensures correctness and reproducibility at scale. If this is a must for caching, perhaps would not expose this as a public API, rather make the caching mappers leverage the build settings as they need rather than add this logic to the generator and enforce it for all projects. |
Beta Was this translation helpful? Give feedback.
-
I'm also curious to know more since I'm with @kwridan feeling that leaning more into XCFrameworks is the right path since they are designed for just this challenge. What if we make XCFrameworks the core caching mechanism and potentially include the ability to limit the caching to a specific subset of supported platforms (e.g. allowing end users to pass a flag to exclude simulator builds or a whole platform). We could potentially come up with a way to include these exclusions in hashing logic to resolved what artifacts are cached. I wonder if this is just the default way of operating with Generally the more we have to diverge from "standard" solutions in service of caching the more exposure the project has to breaking changes from SPM/Xcode direction. |
Beta Was this translation helpful? Give feedback.
-
For some reason, I thought building a .xcframework required the build setting
That's right. That option is out of the equation.
Agreed. I'm not a big fan of moving some conditional build-time logic to build settings because that makes it harder to reason about a project. I think it's very valuable being able to glance over the build phases and understand what's being linked and embedded into any target of the project. |
Beta Was this translation helpful? Give feedback.
-
Our dependency graph supports defining dependencies on pre-compiled libraries and frameworks:
When generating Xcode projects, we use standard linking build phases for them. In the case of dynamic binaries that need to be copied into a directory from which they can be dynamically linked, we use a script that can strip out the unnecessary architectures. Moreover, we recently added support for multi-platform, which brought the concept of platform conditions, allowing developers to specify linking conditions (e.g., link only
Framework.framework
if you are building for macOS).While the model works, it doesn't offer the flexibility to declare different framework versions depending on the SDK (device and simulator). This is a need for caching, where we'd like to include different versions of the binaries for the various SDKs of the platform and conditionally link and embed one or another based on the SDK. Note that there are other methods to approach this problem:
We could extend our interface to support passing a binary per SDK. Here's an idea:
We'd need to adjust the logic configuring all the links to use build settings instead of build phases because build phases can specify platform conditions but not SDK conditions. In build settings, we can define conditional settings based on the SDK:
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator] = ...
The logic would need to consider the platform conditions and flat-map them into a set of SDK conditions we'd use in the build settings.
Does this sound reasonable to you? Are there any implications in this change that you think I should be aware of?
Footnotes
https://developer.apple.com/documentation/xcode/creating-a-multi-platform-binary-framework-bundle ↩
https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary ↩
Beta Was this translation helpful? Give feedback.
All reactions