shorebirdtech / shorebird

Code Push for Flutter and other tools for Flutter businesses.
https://shorebird.dev
Other
2.1k stars 124 forks source link

fix: `shorebird patch ios` fails with obfuscated build #1619

Open psatler opened 6 months ago

psatler commented 6 months ago

Description

Running shorebird patch ios-alpha on an app that uses flavors fails with the following message

Failed to link AOT files: Exception: Failed to link: base and patch snapshots have differing VM sections

I created a repo and manually added flavors/schemes to iOS (development and production). The repo I used to reproduce the issue can be found here. I was also able to reproduce this issue using the very good CLI which automatically sets up an app with flavors from the get-go when running very_good create flutter_app <app-name>

Android release and patch are working fine.

Steps To Reproduce

On a project that uses flavors/schemes

  1. Trigger a release for a given flavor, let's say development:
    shorebird release ios-alpha \
        --target lib/main_development.dart \
        --flavor development -- \
        --obfuscate --split-debug-info=./build/app/outputs/symbols
  2. After that release is published, trigger a patch release this time
shorebird patch ios-alpha \
        --target lib/main_development.dart \
        --flavor development -- \
        --obfuscate --split-debug-info=./build/app/outputs/symbols
  1. Verify that the patch fails

Again, a reproducible repo was created here.

Expected Behavior

To be able to publish a patch release for the respective flavor/target.

Screenshots

Additional Context

✓ Shorebird is up-to-date (0.6s) ✓ Flutter install is correct (0.5s) ✓ AndroidManifest.xml files contain INTERNET permission (35ms) ✓ Has access to storage.googleapis.com (0.2s)

No issues detected!

- `flutter doctor`
```bash
❯ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.16.5, on macOS 14.2.1 23C71 darwin-arm64, locale en-BR)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
[✓] Xcode - develop for iOS and macOS (Xcode 15.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.85.1)
[✓] Connected device (4 available)
[✓] Network resources

• No issues found!
bryanoltman commented 6 months ago

Reproduced this locally. The issue seems to be that our linker does not currently work with obfuscated builds.

eseidel commented 6 months ago

We could also just disable the linker for obfuscated builds for now?

psatler commented 6 months ago

interesting @bryanoltman , thanks for the feedback.

I am not sure if it's worth mentioning, but I believe I was able to successfully execute the patch ios-alpha command along with the obfuscation flags when I used a previous version of flutter, more precisely, version 3.10.6. See this link here, please. This is a repo I created a while ago when I was first experimenting Shorebird.

I hope this helps to figure out the issue.

eseidel commented 6 months ago

Yes, obfuscation is expected to work on Flutter 3.16.4 and before. We broke it (accidentally) in 3.16.5 (Shorebird 0.20.0, end of Dec 2023) with our new iOS runtime + linking.

eseidel commented 5 months ago

I suspect that this will have a similar fix to what @felangel is working on the dart compiler now. He's making the dart compiler (gen_snapshot) aware of the existence of the "release" build when building the patch. Making obfuscation work with our linker will probably be similar.

However the way this is failing (vm sections differing) may just suggest that obfuscation needs to be disabled for the vm section of the snapshot, since the vm section is the same for all apps compiled with the same Dart compiler, there isn't a lot of purpose in obfuscating that code.

However obfuscation will probably break our linker in other ways, since it renames methods and variables which likely will cause their heap indices to change, which will likely cause all code which references those names to fail to link (for similar reasons to what Felix is working on right now).

This will probably take us a few weeks to fix and will be after we fix https://github.com/shorebirdtech/shorebird/issues/1665

ZahidTekbas commented 3 months ago

I'm having the same issue here.

eseidel commented 2 months ago

We're aware that the --obfuscate flag is broken for iOS builds at the moment. Android works without issue. This issue tracks fixing --obfuscate on iOS.

lukemmtt commented 2 weeks ago

+1 for this!

eseidel commented 1 week ago

@felangel is finishing the last patch for https://github.com/shorebirdtech/shorebird/issues/1892 and then plans to work on this.

Work here involves trying shorebird release ios --obfuscate, shorebird patch ios --obfuscate and see what breaks. Assuming that --obfuscate is deterministic (same inputs produce same outputs) then it should already "just work" with shorebird patch and we'd need to investigate why it doesn't. If --obfuscate is not deterministic, then we probably need to change Dart's built-in obfuscate to be deterministic, which may involve having it take a "seed" value for whatever random/hashing it uses for the plain_name->obfuscated_name mappings.

It would be OK (as a v1) for --obfuscate to "work" but just cause very low link percentages (because the obfuscation might confuse how we link code between the patch and the release). We can later come back with a "v2" which teaches our linker to be aware of obfuscated selectors, etc.