Skip to content

Comments

fix(cli): embed static XCFrameworks to support resources#9240

Merged
pepicrft merged 3 commits intomainfrom
fix/embed-static-xcframeworks-with-resources
Jan 27, 2026
Merged

fix(cli): embed static XCFrameworks to support resources#9240
pepicrft merged 3 commits intomainfrom
fix/embed-static-xcframeworks-with-resources

Conversation

@pepicrft
Copy link
Contributor

@pepicrft pepicrft commented Jan 26, 2026

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() in GraphTraverser to 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 via REMOVE_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

  • Added acceptance test that caches targets as XCFrameworks, generates with cached binaries, builds, and verifies the app runs without crashing
  • Added unit tests for embeddableFrameworks:
    • test_embeddableFrameworks_when_dependencyIsStaticXCFramework: verifies direct static XCFramework dependencies are embedded
    • test_embeddableFrameworks_when_dependencyIsTransitiveStaticXCFramework: verifies static XCFrameworks through dynamic framework targets are embedded

@dosubot dosubot bot added size:L For issues that take up to a day to implement domain:dependencies For issues and PRs related to integrating third-party dependencies p2 Should do type:bug Something isn't working labels Jan 26, 2026
@tuist
Copy link

tuist bot commented Jan 26, 2026

🛠️ Tuist Run Report 🛠️

Tests 🧪

Scheme Status Cache hit rate Tests Skipped Ran Commit
TuistAutomationAcceptanceTests 87 % 34 0 34 0859d4696
TuistCacheEEAcceptanceTests 85 % 14 0 14 0575a1f32
TuistCacheEEUnitTests 85 % 110 0 110 1e9bc013d
TuistDependenciesAcceptanceTests 0 % 18 0 18 0575a1f32
TuistGeneratorAcceptanceTests 87 % 72 0 72 0575a1f32
TuistKitAcceptanceTests 70 % 46 0 46 0575a1f32
TuistUnitTests 87 % 483 23 460 ae736bd28

Builds 🔨

Scheme Status Duration Commit
TuistAutomationAcceptanceTests 1m 16s 0575a1f32
TuistCacheEEAcceptanceTests 26.0s 0575a1f32
TuistCacheEEUnitTests 2m 8s 1e9bc013d
TuistDependenciesAcceptanceTests 1m 54s 0575a1f32
TuistGeneratorAcceptanceTests 1m 37s 0575a1f32
TuistKitAcceptanceTests 4m 11s 0575a1f32
TuistUnitTests 24.4s ae736bd28

@pepicrft pepicrft changed the title fix(cli): embed static XCFrameworks with resources from cache fix(cli): embed static XCFrameworks to support resources Jan 26, 2026
@pepicrft pepicrft requested a review from fortmarek January 26, 2026 11:03
Copy link
Member

@fortmarek fortmarek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Jan 26, 2026
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.
@pepicrft pepicrft force-pushed the fix/embed-static-xcframeworks-with-resources branch 2 times, most recently from f5a6216 to ab6326a Compare January 26, 2026 18:19
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()
@pepicrft pepicrft force-pushed the fix/embed-static-xcframeworks-with-resources branch from ab6326a to 22f0750 Compare January 26, 2026 19:18
@pepicrft pepicrft merged commit 816d7f7 into main Jan 27, 2026
18 of 19 checks passed
@pepicrft pepicrft deleted the fix/embed-static-xcframeworks-with-resources branch January 27, 2026 09:57
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain:dependencies For issues and PRs related to integrating third-party dependencies lgtm This PR has been approved by a maintainer p2 Should do size:L For issues that take up to a day to implement type:bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants