Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix flutter run on Mac x64 hosts if Swift Package Manager is enabled #154645

Merged
merged 2 commits into from
Sep 11, 2024

Conversation

loic-sharma
Copy link
Member

@loic-sharma loic-sharma commented Sep 4, 2024

Problem

Enabling the Swift Package Manager feature caused post-submit tests to fail on Mac x64 hosts:

Example error...

https://ci.chromium.org/ui/p/flutter/builders/prod/Mac_ios%20rrect_blur_perf_ios__timeline_summary/575/overview

♦ ... flutter --verbose assemble ... -dIosArchs=x86_64 ... profile_unpack_ios

Target profile_unpack_ios failed:
Exception: Binary ... build/ios/Profile-iphoneos/Flutter.framework/Flutter does not contain x86_64.

Running lipo -info:
Non-fat file: ... build/ios/Profile-iphoneos/Flutter.framework/Flutter is architecture: arm64

#0      UnpackIOS._thinFramework (package:flutter_tools/src/build_system/targets/ios.dart:351:7)
<asynchronous suspension>
#1      UnpackIOS.build (package:flutter_tools/src/build_system/targets/ios.dart:298:5)
<asynchronous suspension>
...

Reproduction

On a mac x64 host:

  1. Switch to the latest master channel: flutter channel master ; flutter upgrade
  2. Disable the Swift Package Manager feature: flutter config --no-enable-swift-package-manager
  3. Create a Flutter project
  4. Edit the Xcode project manually to add the prepare pre-action
  5. Run flutter run (flutter build ios does not reproduce this issue).

Background

Previously, the Flutter framework was unpacked in the Xcode target's build. Unfortunately, this happens after Swift packages are built; this prevented Swift packages from using the Flutter framework.

To fix this, we added an Xcode pre-action that unpacks the Flutter framework before Swift Package Manager builds packages. The Xcode target still runs the Flutter framework unpack step, but this step no-ops if both unpack steps have the exact same inputs.

flowchart LR
  A[flutter run -d iphone] --> B(Build Xcode project)
  B --> C(Xcode 'prepare framework' pre-action)
  B --> G[Build Swift packages]
  B --> D(Build 'Runner' target)
  C --> E[Unpack Flutter framework #1]
  D --> F["
  Unpack Flutter framework #2
  (No-ops if inputs are same as #1)
  "]
Loading

#150052 added an optimization that made it more likely the second unpack step no-ops by fixing a case where the target architecture input could be different:

When using SwiftPM, we use flutter assemble in an Xcode Pre-action to run the debug_unpack_macos (or profile/release) target. This target is also later used in a Run Script build phase. Depending on ARCHS build setting, the Flutter/FlutterMacOS binary is thinned. In the Run Script build phase, ARCHS is filtered to the active arch. However, in the Pre-action it doesn't always filter to the active arch. As a workaround, assume arm64 if the NATIVE_ARCH is arm, otherwise assume x86_64.

This optimization is only applied if ONLY_ACTIVE_ARCH is YES.

Important

ONLY_ACTIVE_ARCH's name is misleading. It specifies whether the product includes only object code for the native architecture.

A value of YES means the product includes only code for the native architecture (NATIVE_ARCH).

A value of NO means the product includes code for the architectures specified in ARCHS (Architectures).

Problem

buildXcodeProject incorrectly always sets ONLY_ACTIVE_ARCH to YES if the Xcode built is for a single architecture:

if (activeArch != null) {
final String activeArchName = activeArch.name;
buildCommands.add('ONLY_ACTIVE_ARCH=YES');
// Setting ARCHS to $activeArchName will break the build if a watchOS companion app exists,
// as it cannot be build for the architecture of the Flutter app.
if (!hasWatchCompanion) {
buildCommands.add('ARCHS=$activeArchName');
}
}

This is incorrect! If the host architecture is x64 but the target architecture is arm64, ONLY_ACTIVE_ARCH should be NO.

This caused the prepare pre-action to incorrectly use x64 as the target architecture for arm64 devices on an x64 host, which in turn caused builds to fail if Swift Package Manager was enabled.

Solution

This change updates buildXcodeProject to set ONLY_ACTIVE_ARCH correctly.

This change also updates the prepare pre-action's to be more conservative in applying the optimization that filters the target architecture. This ensures that the build still works (but without the optimization) if ONLY_ACTIVE_ARCH is incorrectly set.

Follow-up PR: #154649

This unblocks: #151567

DeviceLab test

This problem reproduces if you flutter run to an iPhone Arm64 device from an x64 mac host with the Swift Package Manager feature enabled.

I ran an affected DeviceLab test to verify the fix works as expected:

Description CI test Result
SwiftPM enabled without this fix: #154750 Link
SwiftPM enabled with this fix: #154749 Link

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. labels Sep 4, 2024
@loic-sharma loic-sharma force-pushed the spm_only_active_archs branch 4 times, most recently from 9367fa1 to 65b4d3e Compare September 4, 2024 21:50
@loic-sharma loic-sharma force-pushed the spm_only_active_archs branch from 65b4d3e to 4f313f2 Compare September 4, 2024 22:03
@loic-sharma loic-sharma changed the title [iOS] Improve logic that sets ONLY_ACTIVE_ARCH Fix flutter run on Mac x64 hosts if Swift Package Manager is enabled Sep 4, 2024
@loic-sharma loic-sharma marked this pull request as ready for review September 4, 2024 23:13
auto-submit bot pushed a commit that referenced this pull request Sep 5, 2024
Improves the formatting and error messages of the target that unpacks the Flutter framework in Flutter iOS builds.

Follow up to: #154645
Part of #151567
final bool onlyActiveArch = activeArch == getCurrentDarwinArch();

buildCommands.add('ONLY_ACTIVE_ARCH=${onlyActiveArch? 'YES' : 'NO'}');
buildCommands.add('ARCHS=${activeArch.name}');
Copy link
Member

Choose a reason for hiding this comment

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

A value of YES means the product includes only code for the native architecture (NATIVE_ARCH).

A value of NO means the product includes code for the architectures specified in ARCHS (Architectures).

It means the native arch of the target phone or simulator, not the host Mac arch. If this is on a Mac x64 machine but targeting a physical arm64 device, I don't think this would work?

Copy link
Member Author

@loic-sharma loic-sharma Sep 6, 2024

Choose a reason for hiding this comment

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

If this is on a Mac x64 machine but targeting a physical arm64 device, I don't think this would work?

Here's a devicelab test that verifies this works on a Mac x64 machine targeting a physical arm64 device:

Description Host machine Target machine CI test Result
SwiftPM enabled without fix
#154750
Mac x64 Physical arm64 device Link
SwiftPM enabled with fix
#154749
Mac x64 Physical arm64 device Link

It means the native arch of the target phone or simulator, not the host Mac arch.

As in, NATIVE_ARCH is the native arch of the target phone or simulator? If so, I don't think that's true.

NATIVE_ARCH's docs:

Identifies the architecture on which the build is being performed (same as CURRENT_ARCH).

Also see this devicelab test of a x64 host for arm64 target: https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8737518504062464913/+/u/run_rrect_blur_perf_ios__timeline_summary/stdout

[2024-09-06 12:18:31.283585] [STDOUT] stdout:                 export ARCHS\=arm64
...
[2024-09-06 12:18:31.286058] [STDOUT] stdout:                 export NATIVE_ARCH\=x86_64
...
[2024-09-06 12:18:31.288132] [STDOUT] stdout:             ♦ /opt/s/w/ir/x/w/rc/tmpbd9z5dzh/flutter sdk/bin/flutter --verbose assemble --no-version-check --output=/opt/s/w/ir/x/w/rc/tmpbd9z5dzh/flutter sdk/dev/benchmarks/macrobenchmarks/build/ios/Profile-iphoneos/ -dTargetPlatform=ios -dTargetFile=test_driver/run_app.dart -dBuildMode=profile -dIosArchs=arm64 -dSdkRoot=/opt/flutter/xcode/15a240d/XCode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk -dSplitDebugInfo= -dTreeShakeIcons=false -dTrackWidgetCreation=true -dDartObfuscation=false -dAction=build -dFrontendServerStarterPath= --ExtraGenSnapshotOptions= --DartDefines= --ExtraFrontEndOptions= -dCodesignIdentity=6475AE66068783D9C7566E71522EA3915C7D6C9A profile_ios_bundle_flutter_assets

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for investigating! I didn't have the details paged in.

@loic-sharma loic-sharma added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 11, 2024
@auto-submit auto-submit bot merged commit ea208f8 into flutter:master Sep 11, 2024
127 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 12, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 12, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 12, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 12, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Sep 12, 2024
Roll Flutter from 2e221e7308ba to 303f222e17e3 (77 revisions)

flutter/flutter@2e221e7...303f222

2024-09-12 [email protected] Manual roll to 48ddaf578fb0c8326d5b4b680b0f49ea72e33216 (flutter/flutter#155070)
2024-09-12 [email protected] Externalize and update onboarding instructions (flutter/flutter#154730)
2024-09-12 [email protected] when setting up the log reader for a device during `flutter run`, discard any `RPCError` thrown due to the device being disconnected (flutter/flutter#155049)
2024-09-12 98614782+auto-submit[bot]@users.noreply.github.com Reverts "iOS: update provisioning profile for 2024-2025 cert (#155052)" (flutter/flutter#155059)
2024-09-12 [email protected] iOS: update provisioning profile for 2024-2025 cert (flutter/flutter#155052)
2024-09-11 [email protected] Factor out `Container` objects (flutter/flutter#153619)
2024-09-11 [email protected] Move (`dev/tools`), complete v0 of `native_driver` (Android) (flutter/flutter#154843)
2024-09-11 [email protected] Roll Flutter Engine from ade8ef293bc6 to ee5adf6d2ee1 (2 revisions) (flutter/flutter#155046)
2024-09-11 [email protected] Fix `flutter run` on Mac x64 hosts if Swift Package Manager is enabled (flutter/flutter#154645)
2024-09-11 [email protected] Roll Packages from bb53e5d to 4c18648 (1 revision) (flutter/flutter#155033)
2024-09-11 [email protected] Roll Flutter Engine from 4eb729b7a5c4 to ade8ef293bc6 (3 revisions) (flutter/flutter#155031)
2024-09-11 [email protected] fix: Dropdown menu trying to access highlight element which doesn't exist when search and filters both are enabled (flutter/flutter#151969)
2024-09-11 [email protected] Marks Linux build_tests_3_5 to be unflaky (flutter/flutter#154993)
2024-09-11 [email protected] Add 'direction' allow to 'SegmentedButton' oriented vertically (flutter/flutter#150903)
2024-09-11 [email protected] Marks Linux build_tests_5_5 to be unflaky (flutter/flutter#154995)
2024-09-11 [email protected] Update the signature of DDS launcher callback. (flutter/flutter#154949)
2024-09-11 [email protected] Migrate Color.toString() test, improves `equalsIgnoringHashCodes` (flutter/flutter#154934)
2024-09-11 [email protected] Update material and cupertino localizations (flutter/flutter#154959)
2024-09-11 [email protected] Marks Linux build_tests_1_5 to be unflaky (flutter/flutter#154991)
2024-09-11 [email protected] Marks Linux build_tests_2_5 to be unflaky (flutter/flutter#154992)
2024-09-11 [email protected] Fix `flutter create` warning regarding Java compatibility (flutter/flutter#152836)
2024-09-11 [email protected] Roll Flutter Engine from 54757dab9462 to 4eb729b7a5c4 (1 revision) (flutter/flutter#155022)
2024-09-11 [email protected] Fix java version used by `build_aar_module_test` (flutter/flutter#154967)
2024-09-11 [email protected] Roll Flutter Engine from 0a14c519ea4f to 54757dab9462 (1 revision) (flutter/flutter#155015)
2024-09-11 [email protected] Roll Flutter Engine from 35a3171b72c5 to 0a14c519ea4f (1 revision) (flutter/flutter#154984)
2024-09-11 [email protected] Roll Flutter Engine from b9c0b96c3316 to 35a3171b72c5 (1 revision) (flutter/flutter#154980)
2024-09-11 [email protected] Roll Flutter Engine from 52eeea075767 to b9c0b96c3316 (1 revision) (flutter/flutter#154976)
2024-09-11 [email protected] Roll Flutter Engine from a26075f9b1e6 to 52eeea075767 (1 revision) (flutter/flutter#154973)
2024-09-11 [email protected] Roll Flutter Engine from 60c15bc0f40e to a26075f9b1e6 (6 revisions) (flutter/flutter#154969)
2024-09-11 [email protected] Migrate `apple-mobile-web-*` to `mobile-web-*`. (flutter/flutter#154964)
2024-09-11 [email protected] Roll Flutter Engine from 8a038a6f7099 to 60c15bc0f40e (15 revisions) (flutter/flutter#154960)
2024-09-10 [email protected] Adds dart fixes for Color opacity functions (flutter/flutter#154953)
2024-09-10 [email protected] Missing benchmarks for `foundation/all_elements_bench.dart` (flutter/flutter#154954)
2024-09-10 [email protected] Update color assertions (flutter/flutter#154752)
2024-09-10 [email protected] handle EAGAIN (macOS) in ErrorHandlingProcessManager (flutter/flutter#154306)
2024-09-10 [email protected] fix unpack freezing app with animation duration zero  (flutter/flutter#153890)
2024-09-10 [email protected] Remove last `--disable-dart-dev` in `flutter/flutter`. (flutter/flutter#154948)
2024-09-10 [email protected] Remove scheduler: luci from new `build_aar_module_test` (flutter/flutter#154945)
2024-09-10 [email protected] Roll pub packages (flutter/flutter#154939)
2024-09-10 [email protected] `CupertinoSlidingSegmentedControl` update (flutter/flutter#152976)
2024-09-10 [email protected] Roll pub packages (flutter/flutter#154933)
2024-09-10 [email protected] fix test `chrome.close can recover if getTab throws a StateError` (flutter/flutter#154889)
2024-09-10 [email protected] SearchBar context menu (flutter/flutter#154833)
2024-09-10 [email protected] Fix `flutter build aar` for modules that use a plugin (flutter/flutter#154757)
2024-09-10 [email protected] Roll Packages from b4e0fc1 to bb53e5d (4 revisions) (flutter/flutter#154926)
2024-09-10 [email protected] Clean up `SnackBar` inherit theme data test (flutter/flutter#154921)
...
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants