fix(cli): embed static XCFrameworks to support resources#9240
Merged
Conversation
🛠️ Tuist Run Report 🛠️Tests 🧪
Builds 🔨
|
When a static framework with resources is cached as an XCFramework, it was not being included in the "Embed Frameworks" build phase. This caused the app to crash with "Unable to find bundle named X" because the bundle accessor couldn't locate the framework's resources. The fix adds logic to detect static XCFrameworks that have bundle dependencies in the graph and includes them in the embeddable frameworks. This ensures the framework is embedded in the app bundle so the bundle accessor can find resources at runtime. Also adds an acceptance test that verifies the caching scenario works by caching targets, generating with cached binaries, building, and launching the app on a simulator to confirm it doesn't crash.
Changed the embeddableFrameworks logic to embed all static XCFrameworks instead of only those with bundle dependencies in the graph. This is necessary because when a static framework with resources is cached as an XCFramework, we cannot determine at generation time whether it contains resources. Xcode automatically strips the static binary via the build setting REMOVE_STATIC_EXECUTABLES_FROM_EMBEDDED_BUNDLES (default: YES), so only the resources remain in the embedded framework. Also added skip logic for dynamic precompiled binaries since they link static dependencies themselves.
f5a6216 to
ab6326a
Compare
The TuistAcceptanceTestCase.run method for TestCommand was being bypassed by the generic AsyncParsableCommand.Type variadic version when called with variadic arguments like run(TestCommand.self, "--platform", "ios"). This change: 1. Removes _superCommandName from TestRunCommand to allow direct parsing 2. Adds explicit variadic version for TestCommand to ensure it routes to the correct implementation that uses TestRunCommand.parse()
ab6326a to
22f0750
Compare
pepicrft
added a commit
that referenced
this pull request
Jan 29, 2026
3 tasks
pepicrft
added a commit
that referenced
this pull request
Feb 13, 2026
This reverts the static framework resource embedding feature that was introduced across multiple PRs (#9081, #9141, #9210, #9240, #9317, #9382, #9419 and related fixes). Resources for static frameworks go back to being placed in separate .bundle targets instead of being embedded inside the framework itself. The cache version is bumped to invalidate artifacts built with the old embedding approach.
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a static framework with resources is cached as an XCFramework, it was not being included in the "Embed Frameworks" build phase. This caused the app to crash at runtime because the bundle accessor couldn't locate the framework's resources.
The fix changes
embeddableFrameworks()inGraphTraverserto embed all static XCFrameworks. We cannot determine at generation time whether they contain resources, so we embed all of them. Xcode automatically strips the static binary viaREMOVE_STATIC_EXECUTABLES_FROM_EMBEDDED_BUNDLES(default: YES), so only the resources remain in the embedded framework.The change also adds skip logic for dynamic precompiled binaries since they link static dependencies themselves.
Test plan
embeddableFrameworks:test_embeddableFrameworks_when_dependencyIsStaticXCFramework: verifies direct static XCFramework dependencies are embeddedtest_embeddableFrameworks_when_dependencyIsTransitiveStaticXCFramework: verifies static XCFrameworks through dynamic framework targets are embedded