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 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 34871572+gmackall@users.noreply.github.com Manual roll to 48ddaf578fb0c8326d5b4b680b0f49ea72e33216 (flutter/flutter#155070)
2024-09-12 reidbaker@google.com Externalize and update onboarding instructions (flutter/flutter#154730)
2024-09-12 andrewrkolos@gmail.com 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 chris@bracken.jp iOS: update provisioning profile for 2024-2025 cert (flutter/flutter#155052)
2024-09-11 nate.w5687@gmail.com Factor out `Container` objects (flutter/flutter#153619)
2024-09-11 matanlurey@users.noreply.github.com Move (`dev/tools`), complete v0 of `native_driver` (Android) (flutter/flutter#154843)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from ade8ef293bc6 to ee5adf6d2ee1 (2 revisions) (flutter/flutter#155046)
2024-09-11 737941+loic-sharma@users.noreply.github.com Fix `flutter run` on Mac x64 hosts if Swift Package Manager is enabled (flutter/flutter#154645)
2024-09-11 engine-flutter-autoroll@skia.org Roll Packages from bb53e5d to 4c18648 (1 revision) (flutter/flutter#155033)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from 4eb729b7a5c4 to ade8ef293bc6 (3 revisions) (flutter/flutter#155031)
2024-09-11 34465683+rkishan516@users.noreply.github.com 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 fluttergithubbot@gmail.com Marks Linux build_tests_3_5 to be unflaky (flutter/flutter#154993)
2024-09-11 abnhamoda@gmail.com Add 'direction' allow to 'SegmentedButton' oriented vertically (flutter/flutter#150903)
2024-09-11 fluttergithubbot@gmail.com Marks Linux build_tests_5_5 to be unflaky (flutter/flutter#154995)
2024-09-11 chingjun@google.com Update the signature of DDS launcher callback. (flutter/flutter#154949)
2024-09-11 30870216+gaaclarke@users.noreply.github.com Migrate Color.toString() test, improves `equalsIgnoringHashCodes` (flutter/flutter#154934)
2024-09-11 36861262+QuncCccccc@users.noreply.github.com Update material and cupertino localizations (flutter/flutter#154959)
2024-09-11 fluttergithubbot@gmail.com Marks Linux build_tests_1_5 to be unflaky (flutter/flutter#154991)
2024-09-11 fluttergithubbot@gmail.com Marks Linux build_tests_2_5 to be unflaky (flutter/flutter#154992)
2024-09-11 111122076+shashwatpathak98@users.noreply.github.com Fix `flutter create` warning regarding Java compatibility (flutter/flutter#152836)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from 54757dab9462 to 4eb729b7a5c4 (1 revision) (flutter/flutter#155022)
2024-09-11 34871572+gmackall@users.noreply.github.com Fix java version used by `build_aar_module_test` (flutter/flutter#154967)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from 0a14c519ea4f to 54757dab9462 (1 revision) (flutter/flutter#155015)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from 35a3171b72c5 to 0a14c519ea4f (1 revision) (flutter/flutter#154984)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from b9c0b96c3316 to 35a3171b72c5 (1 revision) (flutter/flutter#154980)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from 52eeea075767 to b9c0b96c3316 (1 revision) (flutter/flutter#154976)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from a26075f9b1e6 to 52eeea075767 (1 revision) (flutter/flutter#154973)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from 60c15bc0f40e to a26075f9b1e6 (6 revisions) (flutter/flutter#154969)
2024-09-11 matanlurey@users.noreply.github.com Migrate `apple-mobile-web-*` to `mobile-web-*`. (flutter/flutter#154964)
2024-09-11 engine-flutter-autoroll@skia.org Roll Flutter Engine from 8a038a6f7099 to 60c15bc0f40e (15 revisions) (flutter/flutter#154960)
2024-09-10 30870216+gaaclarke@users.noreply.github.com Adds dart fixes for Color opacity functions (flutter/flutter#154953)
2024-09-10 codefu@google.com Missing benchmarks for `foundation/all_elements_bench.dart` (flutter/flutter#154954)
2024-09-10 30870216+gaaclarke@users.noreply.github.com Update color assertions (flutter/flutter#154752)
2024-09-10 andrewrkolos@gmail.com handle EAGAIN (macOS) in ErrorHandlingProcessManager (flutter/flutter#154306)
2024-09-10 50643541+Mairramer@users.noreply.github.com fix unpack freezing app with animation duration zero  (flutter/flutter#153890)
2024-09-10 matanlurey@users.noreply.github.com Remove last `--disable-dart-dev` in `flutter/flutter`. (flutter/flutter#154948)
2024-09-10 34871572+gmackall@users.noreply.github.com Remove scheduler: luci from new `build_aar_module_test` (flutter/flutter#154945)
2024-09-10 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#154939)
2024-09-10 36861262+QuncCccccc@users.noreply.github.com `CupertinoSlidingSegmentedControl` update (flutter/flutter#152976)
2024-09-10 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#154933)
2024-09-10 andrewrkolos@gmail.com fix test `chrome.close can recover if getTab throws a StateError` (flutter/flutter#154889)
2024-09-10 jmccandless@google.com SearchBar context menu (flutter/flutter#154833)
2024-09-10 34871572+gmackall@users.noreply.github.com Fix `flutter build aar` for modules that use a plugin (flutter/flutter#154757)
2024-09-10 engine-flutter-autoroll@skia.org Roll Packages from b4e0fc1 to bb53e5d (4 revisions) (flutter/flutter#154926)
2024-09-10 tessertaha@gmail.com Clean up `SnackBar` inherit theme data test (flutter/flutter#154921)
...
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