From b19be3c2718dfa5c40a176e9228362ed6e1baefc Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Thu, 23 Jan 2025 16:50:30 -0500 Subject: [PATCH 1/8] feat: support intel macs --- common/config.gni | 8 ++ runtime/dart_snapshot.cc | 4 +- shell/common/shorebird/shorebird.cc | 6 +- shell/platform/darwin/macos/BUILD.gn | 1 + .../macos/framework/Source/FlutterEngine.mm | 125 +++++++++++++++--- shell/platform/embedder/embedder.cc | 6 +- 6 files changed, 128 insertions(+), 22 deletions(-) diff --git a/common/config.gni b/common/config.gni index 66d300d99670d..2eccb84a57a61 100644 --- a/common/config.gni +++ b/common/config.gni @@ -77,6 +77,14 @@ if (is_ios || is_mac || is_android || is_win) { feature_defines_list += [ "SHOREBIRD_PLATFORM_SUPPORTED=1" ] } +if (is_ios) { + feature_defines_list += [ "SHOREBIRD_USE_LINKER=1" ] +} + +if (is_mac && (target_cpu == "arm" || target_cpu == "arm64")) { + feature_defines_list += [ "SHOREBIRD_USE_LINKER=1" ] +} + if (is_ios || is_mac) { flutter_cflags_objc = [ "-Werror=overriding-method-mismatch", diff --git a/runtime/dart_snapshot.cc b/runtime/dart_snapshot.cc index 1a62b3406ef3e..0990df96462f5 100644 --- a/runtime/dart_snapshot.cc +++ b/runtime/dart_snapshot.cc @@ -57,7 +57,7 @@ static std::shared_ptr SearchMapping( const std::vector& native_library_path, const char* native_library_symbol_name, bool is_executable) { -#if FML_OS_IOS || FML_OS_MACOSX +#if SHOREBIRD_USE_LINKER // Detect when we're trying to load a Shorebird patch. auto patch_path = native_library_path.front(); bool is_patch = patch_path.find(".vmcode") != std::string::npos; @@ -141,7 +141,7 @@ static std::shared_ptr SearchMapping( } } -#if FML_OS_IOS || FML_OS_MACOSX +#if SHOREBIRD_USE_LINKER } // !is_patch #endif diff --git a/shell/common/shorebird/shorebird.cc b/shell/common/shorebird/shorebird.cc index 77608a0e29563..fbfcd156a5764 100644 --- a/shell/common/shorebird/shorebird.cc +++ b/shell/common/shorebird/shorebird.cc @@ -83,7 +83,7 @@ FileCallbacks ShorebirdFileCallbacks() { // FIXME: consolidate this with the other ConfigureShorebird bool ConfigureShorebird(const ShorebirdConfigArgs& args, std::string& patch_path) { - patch_path = args.release_app_library_path; + patch_path = ""; // args.release_app_library_path; auto shorebird_updater_dir_name = "shorebird_updater"; auto code_cache_dir = fml::paths::JoinPaths( @@ -239,7 +239,7 @@ void ConfigureShorebird(std::string code_cache_path, // https://github.com/shorebirdtech/shorebird/issues/950 // We only set the base snapshot on iOS for now. -#if FML_OS_IOS || FML_OS_MACOSX +#if SHOREBIRD_USE_LINKER SetBaseSnapshot(settings); #endif @@ -249,7 +249,7 @@ void ConfigureShorebird(std::string code_cache_path, shorebird_free_string(c_active_path); FML_LOG(INFO) << "Shorebird updater: active path: " << active_path; -#if FML_OS_IOS || FML_OS_MACOSX +#if SHOREBIRD_USE_LINKER // On iOS we add the patch to the front of the list instead of clearing // the list, to allow dart_shapshot.cc to still find the base snapshot // for the vm isolate. diff --git a/shell/platform/darwin/macos/BUILD.gn b/shell/platform/darwin/macos/BUILD.gn index 2975a38fb8d08..b7ce1ca36ffe2 100644 --- a/shell/platform/darwin/macos/BUILD.gn +++ b/shell/platform/darwin/macos/BUILD.gn @@ -123,6 +123,7 @@ source_set("flutter_framework_source") { ":macos_gpu_configuration", "//flutter/flow:flow", "//flutter/fml", + "//flutter/shell/common/shorebird", "//flutter/shell/platform/common:common_cpp_accessibility", "//flutter/shell/platform/common:common_cpp_enums", "//flutter/shell/platform/common:common_cpp_input", diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index c870f0d3f55ea..fbce3ffbd9b66 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -11,6 +11,7 @@ #include "flutter/common/constants.h" #include "flutter/fml/paths.h" +#include "flutter/shell/common/shorebird/shorebird.h" #include "flutter/shell/platform/common/app_lifecycle_state.h" #include "flutter/shell/platform/common/engine_switches.h" #include "flutter/shell/platform/embedder/embedder.h" @@ -585,6 +586,48 @@ - (void)dealloc { } } +- (BOOL)setUpNonLinkerShorebird:(NSString**) patchPath { + NSLog(@"[shorebird] setting up non-linker shorebird"); + NSString* bundlePath = + [[NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL + URLByAppendingPathComponent:@"App.framework"]] bundlePath]; + bundlePath = [bundlePath stringByAppendingString:@"/App"]; + // flutterArguments.shorebird_args.app_path = bundlePath.UTF8String; + NSString* assetsPath = _project.assetsPath; + NSURL* shorebirdYamlPath = [NSURL URLWithString:@"shorebird.yaml" + relativeToURL:[NSURL fileURLWithPath:assetsPath]]; + NSString* shorebirdYamlContents = [NSString stringWithContentsOfURL:shorebirdYamlPath + encoding:NSUTF8StringEncoding + error:nil]; + NSString* appVersion = + [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; + NSString* appBuildNumber = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"]; + // flutterArguments.shorebird_args.app_version = appVersion.UTF8String; + // flutterArguments.shorebird_args.app_build_number = appBuildNumber.UTF8String; + + std::string cache_path = + fml::paths::JoinPaths({getenv("HOME"), "Library", "Application Support", "shorebird"}); + // flutterArguments.shorebird_args.cache_path = cache_path.c_str(); + // flutterArguments.shorebird_args.shorebird_yaml_contents = shorebirdYamlContents.UTF8String; + + flutter::ReleaseVersion release_version = {appVersion.UTF8String, appBuildNumber.UTF8String}; + flutter::ShorebirdConfigArgs shorebird_args( + cache_path, cache_path, bundlePath.UTF8String, + shorebirdYamlContents.UTF8String, release_version); + NSLog(@"[shorebird] calling ConfigureShorebird"); + std::string patch_path; + auto res = flutter::ConfigureShorebird(shorebird_args, patch_path); + if (!res) { + NSLog(@"[shorebird] ConfigureShorebird failed"); + return NO; + } + + NSLog(@"[shorebird] ConfigureShorebird success!"); + *patchPath = [NSString stringWithUTF8String:patch_path.c_str()]; + NSLog(@"[shorebird] patchPath: %@", *patchPath); + return YES; +} + - (BOOL)runWithEntrypoint:(NSString*)entrypoint { if (self.running) { return NO; @@ -663,22 +706,6 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { .thread_priority_setter = SetThreadPriority}; flutterArguments.custom_task_runners = &custom_task_runners; - [self loadAOTData:_project.assetsPath]; - if (_aotData) { - flutterArguments.aot_data = _aotData; - } - - flutterArguments.compositor = [self createFlutterCompositor]; - - flutterArguments.on_pre_engine_restart_callback = [](void* user_data) { - FlutterEngine* engine = (__bridge FlutterEngine*)user_data; - [engine engineCallbackOnPreEngineRestart]; - }; - - flutterArguments.vsync_callback = [](void* user_data, intptr_t baton) { - FlutterEngine* engine = (__bridge FlutterEngine*)user_data; - [engine onVSync:baton]; - }; NSString* bundlePath = [[NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL @@ -702,6 +729,40 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { flutterArguments.shorebird_args.cache_path = cache_path.c_str(); flutterArguments.shorebird_args.shorebird_yaml_contents = shorebirdYamlContents.UTF8String; + #if SHOREBIRD_USE_LINKER + NSLog(@"[shorebird] Using Shorebird linker"); + FML_LOG(INFO) << "[shorebird][fml] Using shorebird linker"; + [self loadAOTData:_project.assetsPath]; + #else + NSLog(@"[shorebird] Not using shorebird linker"); + FML_LOG(INFO) << "[shorebird][fml] Not using shorebird linker"; + NSString* patchPath; + auto configureShorebirdRes = [self setUpNonLinkerShorebird:&patchPath]; + if (configureShorebirdRes && ![patchPath isEqualToString:@""]) { + NSLog(@"[shorebird] successfully configured shorebird, loading aot data from %@", patchPath); + [self loadAOTDataFromPatch:patchPath]; + } else { + NSLog(@"[shorebird] failed to configure shorebird"); + [self loadAOTData:_project.assetsPath]; + } + #endif + + if (_aotData) { + flutterArguments.aot_data = _aotData; + } + + flutterArguments.compositor = [self createFlutterCompositor]; + + flutterArguments.on_pre_engine_restart_callback = [](void* user_data) { + FlutterEngine* engine = (__bridge FlutterEngine*)user_data; + [engine engineCallbackOnPreEngineRestart]; + }; + + flutterArguments.vsync_callback = [](void* user_data, intptr_t baton) { + FlutterEngine* engine = (__bridge FlutterEngine*)user_data; + [engine onVSync:baton]; + }; + FlutterRendererConfig rendererConfig = [_renderer createRendererConfig]; FlutterEngineResult result = _embedderAPI.Initialize( FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine); @@ -733,6 +794,8 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { } - (void)loadAOTData:(NSString*)assetsDir { + NSLog(@"[shorebird] loading AOT data from assetsDir: %@", assetsDir); + FML_LOG(INFO) << "[shorebird][fml] Loading AOT data from assetsDir: " << assetsDir.UTF8String; if (!_embedderAPI.RunsAOTCompiledDartCode()) { return; } @@ -743,8 +806,10 @@ - (void)loadAOTData:(NSString*)assetsDir { // This is the location where the test fixture places the snapshot file. // For applications built by Flutter tool, this is in "App.framework". NSString* elfPath = [NSString pathWithComponents:@[ assetsDir, @"app_elf_snapshot.so" ]]; + FML_LOG(INFO) << "elf path is " << elfPath.UTF8String; if (![fileManager fileExistsAtPath:elfPath isDirectory:&isDirOut]) { + FML_LOG(INFO) << "[shorebird][fml] elfPath does not exist: " << elfPath.UTF8String; return; } @@ -758,6 +823,34 @@ - (void)loadAOTData:(NSString*)assetsDir { } } +- (void)loadAOTDataFromPatch:(NSString *)patchPath { + NSLog(@"[shorebird] loading AOT data from patchPath: %@", patchPath); + FML_LOG(INFO) << "[shorebird][fml] Loading AOT data from patchPath: " << patchPath.UTF8String; + BOOL isDirOut = false; // required for NSFileManager fileExistsAtPath. + NSFileManager* fileManager = [NSFileManager defaultManager]; + + if (![fileManager fileExistsAtPath:patchPath isDirectory:&isDirOut]) { + NSLog(@"[shorebird] returning early from loadAOTDataFromPatch because patchPath does not exist"); + return; + } + + FlutterEngineAOTDataSource source = {}; + source.type = kFlutterEngineAOTDataSourceTypeElfPath; + source.elf_path = [patchPath cStringUsingEncoding:NSUTF8StringEncoding]; + + NSLog(@"!!!"); + NSLog(@"!!!"); + NSLog(@"Creating AOT data from patchPath: %@", patchPath); + NSLog(@"!!!"); + NSLog(@"!!!"); + auto result = _embedderAPI.CreateAOTData(&source, &_aotData); + if (result != kSuccess) { + NSLog(@"Failed to load AOT data from: %@", patchPath); + } else { + NSLog(@"[shorebird] created AOT data"); + } +} + - (void)registerViewController:(FlutterViewController*)controller forIdentifier:(FlutterViewIdentifier)viewIdentifier { _macOSCompositor->AddView(viewIdentifier); diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index f1646d85eab08..149a3f4d71ded 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2309,8 +2309,12 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, // FIXME: This is probably the wrong place to call ConfigureShorebird, as // some platforms (i.e., Windows) need to to swap out the app path before // this point. + // + // Targets that do not use mixed-mode need to call ConfigureShorebird in their + // platform-specific code, prior to calling this function. + // // Begin shorebird -#if FML_OS_MACOSX +#if SHOREBIRD_USE_LINKER if (args->shorebird_args.shorebird_yaml_contents) { settings.application_library_path.push_back(args->shorebird_args.app_path); flutter::ConfigureShorebird(args->shorebird_args, settings); From 0127ab350ebd3a6f43499a47143e95389dc5cf26 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Thu, 23 Jan 2025 16:54:34 -0500 Subject: [PATCH 2/8] formatting --- .../macos/framework/Source/FlutterEngine.mm | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index fbce3ffbd9b66..7b086e5a70345 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -586,7 +586,7 @@ - (void)dealloc { } } -- (BOOL)setUpNonLinkerShorebird:(NSString**) patchPath { +- (BOOL)setUpNonLinkerShorebird:(NSString**)patchPath { NSLog(@"[shorebird] setting up non-linker shorebird"); NSString* bundlePath = [[NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL @@ -603,17 +603,18 @@ - (BOOL)setUpNonLinkerShorebird:(NSString**) patchPath { [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; NSString* appBuildNumber = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"]; // flutterArguments.shorebird_args.app_version = appVersion.UTF8String; - // flutterArguments.shorebird_args.app_build_number = appBuildNumber.UTF8String; + // flutterArguments.shorebird_args.app_build_number = + // appBuildNumber.UTF8String; std::string cache_path = fml::paths::JoinPaths({getenv("HOME"), "Library", "Application Support", "shorebird"}); // flutterArguments.shorebird_args.cache_path = cache_path.c_str(); - // flutterArguments.shorebird_args.shorebird_yaml_contents = shorebirdYamlContents.UTF8String; + // flutterArguments.shorebird_args.shorebird_yaml_contents = + // shorebirdYamlContents.UTF8String; flutter::ReleaseVersion release_version = {appVersion.UTF8String, appBuildNumber.UTF8String}; - flutter::ShorebirdConfigArgs shorebird_args( - cache_path, cache_path, bundlePath.UTF8String, - shorebirdYamlContents.UTF8String, release_version); + flutter::ShorebirdConfigArgs shorebird_args(cache_path, cache_path, bundlePath.UTF8String, + shorebirdYamlContents.UTF8String, release_version); NSLog(@"[shorebird] calling ConfigureShorebird"); std::string patch_path; auto res = flutter::ConfigureShorebird(shorebird_args, patch_path); @@ -706,7 +707,6 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { .thread_priority_setter = SetThreadPriority}; flutterArguments.custom_task_runners = &custom_task_runners; - NSString* bundlePath = [[NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL URLByAppendingPathComponent:@"App.framework"]] bundlePath]; @@ -729,23 +729,23 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { flutterArguments.shorebird_args.cache_path = cache_path.c_str(); flutterArguments.shorebird_args.shorebird_yaml_contents = shorebirdYamlContents.UTF8String; - #if SHOREBIRD_USE_LINKER - NSLog(@"[shorebird] Using Shorebird linker"); - FML_LOG(INFO) << "[shorebird][fml] Using shorebird linker"; +#if SHOREBIRD_USE_LINKER + NSLog(@"[shorebird] Using Shorebird linker"); + FML_LOG(INFO) << "[shorebird][fml] Using shorebird linker"; + [self loadAOTData:_project.assetsPath]; +#else + NSLog(@"[shorebird] Not using shorebird linker"); + FML_LOG(INFO) << "[shorebird][fml] Not using shorebird linker"; + NSString* patchPath; + auto configureShorebirdRes = [self setUpNonLinkerShorebird:&patchPath]; + if (configureShorebirdRes && ![patchPath isEqualToString:@""]) { + NSLog(@"[shorebird] successfully configured shorebird, loading aot data from %@", patchPath); + [self loadAOTDataFromPatch:patchPath]; + } else { + NSLog(@"[shorebird] failed to configure shorebird"); [self loadAOTData:_project.assetsPath]; - #else - NSLog(@"[shorebird] Not using shorebird linker"); - FML_LOG(INFO) << "[shorebird][fml] Not using shorebird linker"; - NSString* patchPath; - auto configureShorebirdRes = [self setUpNonLinkerShorebird:&patchPath]; - if (configureShorebirdRes && ![patchPath isEqualToString:@""]) { - NSLog(@"[shorebird] successfully configured shorebird, loading aot data from %@", patchPath); - [self loadAOTDataFromPatch:patchPath]; - } else { - NSLog(@"[shorebird] failed to configure shorebird"); - [self loadAOTData:_project.assetsPath]; - } - #endif + } +#endif if (_aotData) { flutterArguments.aot_data = _aotData; @@ -823,14 +823,15 @@ - (void)loadAOTData:(NSString*)assetsDir { } } -- (void)loadAOTDataFromPatch:(NSString *)patchPath { +- (void)loadAOTDataFromPatch:(NSString*)patchPath { NSLog(@"[shorebird] loading AOT data from patchPath: %@", patchPath); FML_LOG(INFO) << "[shorebird][fml] Loading AOT data from patchPath: " << patchPath.UTF8String; BOOL isDirOut = false; // required for NSFileManager fileExistsAtPath. NSFileManager* fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:patchPath isDirectory:&isDirOut]) { - NSLog(@"[shorebird] returning early from loadAOTDataFromPatch because patchPath does not exist"); + NSLog( + @"[shorebird] returning early from loadAOTDataFromPatch because patchPath does not exist"); return; } From c03a702f7d4a97b2517030dbc12c27971ebcd2d7 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Thu, 23 Jan 2025 16:55:15 -0500 Subject: [PATCH 3/8] formatting --- shell/platform/darwin/macos/framework/Source/FlutterEngine.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 7b086e5a70345..a87097d54b8e4 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -603,7 +603,7 @@ - (BOOL)setUpNonLinkerShorebird:(NSString**)patchPath { [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; NSString* appBuildNumber = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"]; // flutterArguments.shorebird_args.app_version = appVersion.UTF8String; - // flutterArguments.shorebird_args.app_build_number = + // flutterArguments.shorebird_args.app_build_number = // appBuildNumber.UTF8String; std::string cache_path = @@ -831,7 +831,7 @@ - (void)loadAOTDataFromPatch:(NSString*)patchPath { if (![fileManager fileExistsAtPath:patchPath isDirectory:&isDirOut]) { NSLog( - @"[shorebird] returning early from loadAOTDataFromPatch because patchPath does not exist"); + @"[shorebird] returning early from loadAOTDataFromPatch because patchPath does not exist"); return; } From 9baa6f2c4faea4ecc1dd03e4e9fb8c042c846701 Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Fri, 24 Jan 2025 10:33:54 -0500 Subject: [PATCH 4/8] don't use linker on macos --- common/config.gni | 4 -- shell/common/shorebird/shorebird.cc | 10 --- shell/common/shorebird/shorebird.h | 3 - .../macos/framework/Source/FlutterEngine.mm | 68 ++++--------------- shell/platform/embedder/BUILD.gn | 1 - shell/platform/embedder/embedder.cc | 17 ----- shell/platform/embedder/embedder.h | 39 ----------- 7 files changed, 12 insertions(+), 130 deletions(-) diff --git a/common/config.gni b/common/config.gni index 2eccb84a57a61..8ba90916da393 100644 --- a/common/config.gni +++ b/common/config.gni @@ -81,10 +81,6 @@ if (is_ios) { feature_defines_list += [ "SHOREBIRD_USE_LINKER=1" ] } -if (is_mac && (target_cpu == "arm" || target_cpu == "arm64")) { - feature_defines_list += [ "SHOREBIRD_USE_LINKER=1" ] -} - if (is_ios || is_mac) { flutter_cflags_objc = [ "-Werror=overriding-method-mismatch", diff --git a/shell/common/shorebird/shorebird.cc b/shell/common/shorebird/shorebird.cc index fbfcd156a5764..61e1f69987e9f 100644 --- a/shell/common/shorebird/shorebird.cc +++ b/shell/common/shorebird/shorebird.cc @@ -172,16 +172,6 @@ bool ConfigureShorebird(const ShorebirdConfigArgs& args, return true; } -void ConfigureShorebird(const ShorebirdFlutterProjectArgs& args, - Settings& settings) { - // cache_path is used for both code_cache and app_storage, as we don't persist - // any data between releases. args.app_path is appended to - // the settings.application_library_path vector at this function's call site. - ConfigureShorebird(args.cache_path, args.cache_path, settings, - args.shorebird_yaml_contents, args.app_version, - args.app_build_number); -} - void ConfigureShorebird(std::string code_cache_path, std::string app_storage_path, Settings& settings, diff --git a/shell/common/shorebird/shorebird.h b/shell/common/shorebird/shorebird.h index b4efa4c28321b..3e9ccce9ee3f6 100644 --- a/shell/common/shorebird/shorebird.h +++ b/shell/common/shorebird/shorebird.h @@ -33,9 +33,6 @@ struct ShorebirdConfigArgs { bool ConfigureShorebird(const ShorebirdConfigArgs& args, std::string& patch_path); -void ConfigureShorebird(const ShorebirdFlutterProjectArgs& args, - Settings& settings); - void ConfigureShorebird(std::string code_cache_path, std::string app_storage_path, Settings& settings, diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index a87097d54b8e4..f26752cd0c8f3 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -586,13 +586,12 @@ - (void)dealloc { } } -- (BOOL)setUpNonLinkerShorebird:(NSString**)patchPath { +- (BOOL)configureShorebird:(NSString**)patchPath { NSLog(@"[shorebird] setting up non-linker shorebird"); NSString* bundlePath = [[NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL URLByAppendingPathComponent:@"App.framework"]] bundlePath]; bundlePath = [bundlePath stringByAppendingString:@"/App"]; - // flutterArguments.shorebird_args.app_path = bundlePath.UTF8String; NSString* assetsPath = _project.assetsPath; NSURL* shorebirdYamlPath = [NSURL URLWithString:@"shorebird.yaml" relativeToURL:[NSURL fileURLWithPath:assetsPath]]; @@ -602,16 +601,8 @@ - (BOOL)setUpNonLinkerShorebird:(NSString**)patchPath { NSString* appVersion = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; NSString* appBuildNumber = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"]; - // flutterArguments.shorebird_args.app_version = appVersion.UTF8String; - // flutterArguments.shorebird_args.app_build_number = - // appBuildNumber.UTF8String; - std::string cache_path = fml::paths::JoinPaths({getenv("HOME"), "Library", "Application Support", "shorebird"}); - // flutterArguments.shorebird_args.cache_path = cache_path.c_str(); - // flutterArguments.shorebird_args.shorebird_yaml_contents = - // shorebirdYamlContents.UTF8String; - flutter::ReleaseVersion release_version = {appVersion.UTF8String, appBuildNumber.UTF8String}; flutter::ShorebirdConfigArgs shorebird_args(cache_path, cache_path, bundlePath.UTF8String, shorebirdYamlContents.UTF8String, release_version); @@ -707,46 +698,6 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { .thread_priority_setter = SetThreadPriority}; flutterArguments.custom_task_runners = &custom_task_runners; - NSString* bundlePath = - [[NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL - URLByAppendingPathComponent:@"App.framework"]] bundlePath]; - bundlePath = [bundlePath stringByAppendingString:@"/App"]; - flutterArguments.shorebird_args.app_path = bundlePath.UTF8String; - NSString* assetsPath = _project.assetsPath; - NSURL* shorebirdYamlPath = [NSURL URLWithString:@"shorebird.yaml" - relativeToURL:[NSURL fileURLWithPath:assetsPath]]; - NSString* shorebirdYamlContents = [NSString stringWithContentsOfURL:shorebirdYamlPath - encoding:NSUTF8StringEncoding - error:nil]; - NSString* appVersion = - [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; - NSString* appBuildNumber = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"]; - flutterArguments.shorebird_args.app_version = appVersion.UTF8String; - flutterArguments.shorebird_args.app_build_number = appBuildNumber.UTF8String; - - std::string cache_path = - fml::paths::JoinPaths({getenv("HOME"), "Library", "Application Support", "shorebird"}); - flutterArguments.shorebird_args.cache_path = cache_path.c_str(); - flutterArguments.shorebird_args.shorebird_yaml_contents = shorebirdYamlContents.UTF8String; - -#if SHOREBIRD_USE_LINKER - NSLog(@"[shorebird] Using Shorebird linker"); - FML_LOG(INFO) << "[shorebird][fml] Using shorebird linker"; - [self loadAOTData:_project.assetsPath]; -#else - NSLog(@"[shorebird] Not using shorebird linker"); - FML_LOG(INFO) << "[shorebird][fml] Not using shorebird linker"; - NSString* patchPath; - auto configureShorebirdRes = [self setUpNonLinkerShorebird:&patchPath]; - if (configureShorebirdRes && ![patchPath isEqualToString:@""]) { - NSLog(@"[shorebird] successfully configured shorebird, loading aot data from %@", patchPath); - [self loadAOTDataFromPatch:patchPath]; - } else { - NSLog(@"[shorebird] failed to configure shorebird"); - [self loadAOTData:_project.assetsPath]; - } -#endif - if (_aotData) { flutterArguments.aot_data = _aotData; } @@ -764,6 +715,17 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { }; FlutterRendererConfig rendererConfig = [_renderer createRendererConfig]; + + NSString* patchPath; + auto configureShorebirdRes = [self configureShorebird:&patchPath]; + if (configureShorebirdRes && ![patchPath isEqualToString:@""]) { + NSLog(@"[shorebird] successfully configured shorebird, loading aot data from %@", patchPath); + [self loadAOTDataFromPatch:patchPath]; + } else { + NSLog(@"[shorebird] failed to configure shorebird"); + [self loadAOTData:_project.assetsPath]; + } + FlutterEngineResult result = _embedderAPI.Initialize( FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine); if (result != kSuccess) { @@ -839,16 +801,10 @@ - (void)loadAOTDataFromPatch:(NSString*)patchPath { source.type = kFlutterEngineAOTDataSourceTypeElfPath; source.elf_path = [patchPath cStringUsingEncoding:NSUTF8StringEncoding]; - NSLog(@"!!!"); - NSLog(@"!!!"); NSLog(@"Creating AOT data from patchPath: %@", patchPath); - NSLog(@"!!!"); - NSLog(@"!!!"); auto result = _embedderAPI.CreateAOTData(&source, &_aotData); if (result != kSuccess) { NSLog(@"Failed to load AOT data from: %@", patchPath); - } else { - NSLog(@"[shorebird] created AOT data"); } } diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index c620e74761979..38c7e2db98e87 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -110,7 +110,6 @@ template("embedder_source_set") { "//flutter/lib/ui", "//flutter/runtime:libdart", "//flutter/shell/common", - "//flutter/shell/common/shorebird", "//flutter/skia", "//flutter/third_party/tonic", ] diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 149a3f4d71ded..2adf56c592e0a 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -50,7 +50,6 @@ extern const intptr_t kPlatformStrongDillSize; #include "flutter/fml/paths.h" #include "flutter/fml/trace_event.h" #include "flutter/shell/common/rasterizer.h" -#include "flutter/shell/common/shorebird/shorebird.h" #include "flutter/shell/common/switches.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/embedder/embedder_engine.h" @@ -2306,22 +2305,6 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, "Could not infer the Flutter project to run from given arguments."); } - // FIXME: This is probably the wrong place to call ConfigureShorebird, as - // some platforms (i.e., Windows) need to to swap out the app path before - // this point. - // - // Targets that do not use mixed-mode need to call ConfigureShorebird in their - // platform-specific code, prior to calling this function. - // - // Begin shorebird -#if SHOREBIRD_USE_LINKER - if (args->shorebird_args.shorebird_yaml_contents) { - settings.application_library_path.push_back(args->shorebird_args.app_path); - flutter::ConfigureShorebird(args->shorebird_args, settings); - } -#endif - // End shorebird - // Create the engine but don't launch the shell or run the root isolate. auto embedder_engine = std::make_unique( std::move(thread_host), // diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 482a4cad90f6c..9e9b875a2cc36 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -2204,42 +2204,6 @@ typedef void (*FlutterLogMessageCallback)(const char* /* tag */, /// FlutterEngine instance in AOT mode. typedef struct _FlutterEngineAOTData* FlutterEngineAOTData; -typedef struct { - /// The version of the app (e.g., 1.0.0). - /// - /// The string can be collected after the call to `FlutterEngineInitialize` - /// returns. The string must be NULL terminated. - const char* app_version; - - /// The build number of the app (e.g., 1). - /// - /// The string can be collected after the call to `FlutterEngineInitialize` - /// returns. The string must be NULL terminated. - const char* app_build_number; - - /// The text contents of the shorebird.yaml file bundled with the compiled - /// app. Note that this is _not_ the same as the shorebird.yaml that exists in - /// the user's project. - /// - /// The string can be collected after the call to `FlutterEngineInitialize` - /// returns. The string must be NULL terminated. - const char* shorebird_yaml_contents; - - /// The path to the directory where Shorebird will store patches and state - /// data. - /// - /// The string can be collected after the call to `FlutterEngineInitialize` - /// returns. The string must be NULL terminated. - const char* cache_path; - - /// The path to the executable file. This is a Mach-O executable file on - /// macOS. - /// - /// The string can be collected after the call to `FlutterEngineInitialize` - /// returns. The string must be NULL terminated. - const char* app_path; -} ShorebirdFlutterProjectArgs; - typedef struct { /// The size of this struct. Must be sizeof(FlutterProjectArgs). size_t struct_size; @@ -2539,9 +2503,6 @@ typedef struct { /// being registered on the framework side. The callback is invoked from /// a task posted to the platform thread. FlutterChannelUpdateCallback channel_update_callback; - - /// Data used to initialize Shorebird as part of engine initialization. - ShorebirdFlutterProjectArgs shorebird_args; } FlutterProjectArgs; #ifndef FLUTTER_ENGINE_NO_PROTOTYPES From 0713685583c9afb21db456c2d55288f53184b5ec Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Fri, 24 Jan 2025 13:40:33 -0500 Subject: [PATCH 5/8] cleanup --- shell/common/shorebird/shorebird.cc | 8 +-- .../macos/framework/Source/FlutterEngine.mm | 58 +++++-------------- 2 files changed, 17 insertions(+), 49 deletions(-) diff --git a/shell/common/shorebird/shorebird.cc b/shell/common/shorebird/shorebird.cc index 61e1f69987e9f..aedd0cff3e746 100644 --- a/shell/common/shorebird/shorebird.cc +++ b/shell/common/shorebird/shorebird.cc @@ -83,7 +83,7 @@ FileCallbacks ShorebirdFileCallbacks() { // FIXME: consolidate this with the other ConfigureShorebird bool ConfigureShorebird(const ShorebirdConfigArgs& args, std::string& patch_path) { - patch_path = ""; // args.release_app_library_path; + patch_path = args.release_app_library_path; auto shorebird_updater_dir_name = "shorebird_updater"; auto code_cache_dir = fml::paths::JoinPaths( @@ -126,12 +126,6 @@ bool ConfigureShorebird(const ShorebirdConfigArgs& args, // within Dart, including updating as part of login, etc. // https://github.com/shorebirdtech/shorebird/issues/950 - // We only set the base snapshot on iOS for now. - // TODO: this won't compile as we don't have a settings object here. - // #if FML_OS_IOS || FML_OS_MACOSX - // SetBaseSnapshot(settings); - // #endif - FML_LOG(INFO) << "Checking for active patch"; char* c_active_path = shorebird_next_boot_patch_path(); if (c_active_path != NULL) { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index f26752cd0c8f3..5cec987052a7f 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -698,6 +698,19 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { .thread_priority_setter = SetThreadPriority}; flutterArguments.custom_task_runners = &custom_task_runners; + NSString* elfPath; + BOOL configureShorebirdRes = [self configureShorebird:&elfPath]; + if (!configureShorebirdRes) { + // No patch exists, or we failed to configure shorebird. This is a fallback. + // Upstream, this code lives in -(void)loadAOTData:. + // + // This is the location where the test fixture places the snapshot file. + // For applications built by Flutter tool, this is in "App.framework". + elfPath = [NSString pathWithComponents:@[ _project.assetsPath, @"app_elf_snapshot.so" ]]; + } + + [self loadAOTData:elfPath]; + if (_aotData) { flutterArguments.aot_data = _aotData; } @@ -716,16 +729,6 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { FlutterRendererConfig rendererConfig = [_renderer createRendererConfig]; - NSString* patchPath; - auto configureShorebirdRes = [self configureShorebird:&patchPath]; - if (configureShorebirdRes && ![patchPath isEqualToString:@""]) { - NSLog(@"[shorebird] successfully configured shorebird, loading aot data from %@", patchPath); - [self loadAOTDataFromPatch:patchPath]; - } else { - NSLog(@"[shorebird] failed to configure shorebird"); - [self loadAOTData:_project.assetsPath]; - } - FlutterEngineResult result = _embedderAPI.Initialize( FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine); if (result != kSuccess) { @@ -755,9 +758,7 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { return YES; } -- (void)loadAOTData:(NSString*)assetsDir { - NSLog(@"[shorebird] loading AOT data from assetsDir: %@", assetsDir); - FML_LOG(INFO) << "[shorebird][fml] Loading AOT data from assetsDir: " << assetsDir.UTF8String; +- (void)loadAOTData:(NSString*)elfPath { if (!_embedderAPI.RunsAOTCompiledDartCode()) { return; } @@ -765,13 +766,9 @@ - (void)loadAOTData:(NSString*)assetsDir { BOOL isDirOut = false; // required for NSFileManager fileExistsAtPath. NSFileManager* fileManager = [NSFileManager defaultManager]; - // This is the location where the test fixture places the snapshot file. - // For applications built by Flutter tool, this is in "App.framework". - NSString* elfPath = [NSString pathWithComponents:@[ assetsDir, @"app_elf_snapshot.so" ]]; - FML_LOG(INFO) << "elf path is " << elfPath.UTF8String; - if (![fileManager fileExistsAtPath:elfPath isDirectory:&isDirOut]) { - FML_LOG(INFO) << "[shorebird][fml] elfPath does not exist: " << elfPath.UTF8String; + FML_LOG(INFO) << "in loadAOTData, elfPath does not exist: " + << elfPath.UTF8String; return; } @@ -785,29 +782,6 @@ - (void)loadAOTData:(NSString*)assetsDir { } } -- (void)loadAOTDataFromPatch:(NSString*)patchPath { - NSLog(@"[shorebird] loading AOT data from patchPath: %@", patchPath); - FML_LOG(INFO) << "[shorebird][fml] Loading AOT data from patchPath: " << patchPath.UTF8String; - BOOL isDirOut = false; // required for NSFileManager fileExistsAtPath. - NSFileManager* fileManager = [NSFileManager defaultManager]; - - if (![fileManager fileExistsAtPath:patchPath isDirectory:&isDirOut]) { - NSLog( - @"[shorebird] returning early from loadAOTDataFromPatch because patchPath does not exist"); - return; - } - - FlutterEngineAOTDataSource source = {}; - source.type = kFlutterEngineAOTDataSourceTypeElfPath; - source.elf_path = [patchPath cStringUsingEncoding:NSUTF8StringEncoding]; - - NSLog(@"Creating AOT data from patchPath: %@", patchPath); - auto result = _embedderAPI.CreateAOTData(&source, &_aotData); - if (result != kSuccess) { - NSLog(@"Failed to load AOT data from: %@", patchPath); - } -} - - (void)registerViewController:(FlutterViewController*)controller forIdentifier:(FlutterViewIdentifier)viewIdentifier { _macOSCompositor->AddView(viewIdentifier); From 5dc60a97477b6ca56acec6a9c742ee79b07d96fa Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Fri, 24 Jan 2025 13:41:01 -0500 Subject: [PATCH 6/8] formatting --- shell/platform/darwin/macos/framework/Source/FlutterEngine.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 5cec987052a7f..adc9a0534a910 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -767,8 +767,7 @@ - (void)loadAOTData:(NSString*)elfPath { NSFileManager* fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:elfPath isDirectory:&isDirOut]) { - FML_LOG(INFO) << "in loadAOTData, elfPath does not exist: " - << elfPath.UTF8String; + FML_LOG(INFO) << "in loadAOTData, elfPath does not exist: " << elfPath.UTF8String; return; } From dfe1eefcf491a4118b9d41b01ac43916a849337c Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Fri, 24 Jan 2025 13:58:52 -0500 Subject: [PATCH 7/8] bump updater rev --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index fcaa3a57e2877..0c1599c9eeed0 100644 --- a/DEPS +++ b/DEPS @@ -18,7 +18,7 @@ vars = { "dart_sdk_revision": "5c6f8122c1ee85f833ea3b69b3b85dc07303e8d2", "dart_sdk_git": "git@github.com:shorebirdtech/dart-sdk.git", "updater_git": "https://github.com/shorebirdtech/updater.git", - "updater_rev": "71b5ed65fab03fcf241edf0c74d027de9998da51", + "updater_rev": "ba52a62b5d1b064cce363ef98c6165b1e2f78059", # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From a069e91b62e7da53192bbb60dcd63f89f650d67c Mon Sep 17 00:00:00 2001 From: Bryan Oltman Date: Fri, 24 Jan 2025 14:36:26 -0500 Subject: [PATCH 8/8] SHOREBIRD_USE_LINKER -> SHOREBIRD_USE_INTERPRETER --- common/config.gni | 2 +- runtime/dart_snapshot.cc | 4 ++-- shell/common/shorebird/shorebird.cc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/config.gni b/common/config.gni index 8ba90916da393..351af4a41746d 100644 --- a/common/config.gni +++ b/common/config.gni @@ -78,7 +78,7 @@ if (is_ios || is_mac || is_android || is_win) { } if (is_ios) { - feature_defines_list += [ "SHOREBIRD_USE_LINKER=1" ] + feature_defines_list += [ "SHOREBIRD_USE_INTERPRETER=1" ] } if (is_ios || is_mac) { diff --git a/runtime/dart_snapshot.cc b/runtime/dart_snapshot.cc index 0990df96462f5..d735b299cad42 100644 --- a/runtime/dart_snapshot.cc +++ b/runtime/dart_snapshot.cc @@ -57,7 +57,7 @@ static std::shared_ptr SearchMapping( const std::vector& native_library_path, const char* native_library_symbol_name, bool is_executable) { -#if SHOREBIRD_USE_LINKER +#if SHOREBIRD_USE_INTERPRETER // Detect when we're trying to load a Shorebird patch. auto patch_path = native_library_path.front(); bool is_patch = patch_path.find(".vmcode") != std::string::npos; @@ -141,7 +141,7 @@ static std::shared_ptr SearchMapping( } } -#if SHOREBIRD_USE_LINKER +#if SHOREBIRD_USE_INTERPRETER } // !is_patch #endif diff --git a/shell/common/shorebird/shorebird.cc b/shell/common/shorebird/shorebird.cc index aedd0cff3e746..602a0521ae7b0 100644 --- a/shell/common/shorebird/shorebird.cc +++ b/shell/common/shorebird/shorebird.cc @@ -223,7 +223,7 @@ void ConfigureShorebird(std::string code_cache_path, // https://github.com/shorebirdtech/shorebird/issues/950 // We only set the base snapshot on iOS for now. -#if SHOREBIRD_USE_LINKER +#if SHOREBIRD_USE_INTERPRETER SetBaseSnapshot(settings); #endif @@ -233,7 +233,7 @@ void ConfigureShorebird(std::string code_cache_path, shorebird_free_string(c_active_path); FML_LOG(INFO) << "Shorebird updater: active path: " << active_path; -#if SHOREBIRD_USE_LINKER +#if SHOREBIRD_USE_INTERPRETER // On iOS we add the patch to the front of the list instead of clearing // the list, to allow dart_shapshot.cc to still find the base snapshot // for the vm isolate.