AspectD 编译过程

flutter而为了提升整体的编译效率,大部分模块都被提前编译成了 snapshot 文件( 一种 Dart 的编译产物,可被 Dart VM 所运行,用于提升执行效率)

1、frontend_server:前端编译器生成 kernel 文件

2、gen_snapshot :将 dart 代码编译成 AOT 产物

1. frontend_server命令

KernelCompiler.compile() 过程等价于如下命令:

可见,通过 dart 虚拟机启动 frontend_server.dart.snapshot,将 dart 代码转换成 app.dill 形式的 kernel 文件。

frontend_server 前端编译器将 dart 代码转换为 AST,并生成 app.dill 文件,其中 bytecode 生成过程默认是关闭的。

ini 复制代码
static Future<bool> checkAspectdFlutterFrontendServerSnapshot(String packagesPath) async { 
        final Directory flutterFrontendServerDirectory = await getFlutterFrontendServerDirectory(packagesPath);  
        final String aspectdFlutterFrontendServerSnapshot = globals.fs.path.join(flutterFrontendServerDirectory.absolute.path, frontendServerDartSnapshot);  
        final String defaultFlutterFrontendServerSnapshot = globals.artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);  
            if (!globals.fs.file(aspectdFlutterFrontendServerSnapshot).existsSync()) {    
                final String dartSdkDir = await getDartSdkDependency((await getPackagePathFromConfig(packagesPath, 'aspectd')).absolute.path);    
                final String frontendServerPackageConfigJsonFile = '${flutterFrontendServerDirectory.absolute.path}/package_config.json';  
                final String rebasedFrontendServerPackageConfigJsonFile = '${flutterFrontendServerDirectory.absolute.path}/rebased_package_config.json';    
                String frontendServerPackageConfigJson = globals.fs.file(frontendServerPackageConfigJsonFile).readAsStringSync();   
                frontendServerPackageConfigJson = frontendServerPackageConfigJson.replaceAll('../../../third_party/dart', dartSdkDir);    
                globals.fs.file(rebasedFrontendServerPackageConfigJsonFile).writeAsStringSync(frontendServerPackageConfigJson);   
                final List<String> commands = <String>[     
                     globals.artifacts.getArtifactPath(Artifact.engineDartBinary),      
                    '--deterministic',     
                    '--packages=$rebasedFrontendServerPackageConfigJsonFile',      
                    '--snapshot=$aspectdFlutterFrontendServerSnapshot',      
                    '--snapshot-kind=kernel',     
                    '${flutterFrontendServerDirectory.absolute.path}/starter.dart'];
                final ProcessResult processResult = await globals.processManager.run(commands);    
                globals.fs.file(rebasedFrontendServerPackageConfigJsonFile).deleteSync();    
                if (processResult.exitCode != 0 || globals.fs.file(aspectdFlutterFrontendServerSnapshot).existsSync() == false) {     
                     throwToolExit('Aspectd unexpected error: ${processResult.stderr.toString()}');   
                }  
                String res = "";
                for (String command in commands) {  
                    res += command;
                }
                print("command args:" + res);            } else {   
                 print("aspectdFlutterFrontendServerSnapshot exist:"+aspectdFlutterFrontendServerSnapshot);  
            }  
            if (globals.fs.file(defaultFlutterFrontendServerSnapshot).existsSync()) {    
                globals.fs.file(defaultFlutterFrontendServerSnapshot).deleteSync(); 
            }  
            globals.fs.file(aspectdFlutterFrontendServerSnapshot).copySync(defaultFlutterFrontendServerSnapshot);  
            return true;
      }

命令的参数:

bash 复制代码
command args:/Users/warren/env/flutter/bin/cache/dart-sdk/bin/dart--deterministic--packages=/Users/warren/Project/openSource/aspectd/lib/src/flutter_frontend_server/rebased_
package_config.json--snapshot=/Users/warren/Project/openSource/aspectd/lib/src/flutter_frontend_server/frontend_server.dart.snapshot--snapshot-kind=kernel/Users/warr
en/Project/openSource/aspectd/lib/src/flutter_frontend_server/starter.dart

这个dart命令,其实就是把我们aspectD中的starter.dart文件编译成为了frontend_server.dart.snapshot这个文件。starter.dart文件就是我们aspectD插入的编译过程的入口:

arduino 复制代码
void main(List<String> args) async {
  final int exitCode = await starter(args);
  if (exitCode != 0) {
    exit(exitCode);
  }
}

最后一段:

scss 复制代码
globals.fs
 .file(aspectdFlutterFrontendServerSnapshot)
 .copySync(defaultFlutterFrontendServerSnapshot);

这个逻辑就是把生成的frontend_server.dart.snapshot文件拷贝至flutter sdk中的对应位置

结合aspectd的编译过程:

运行之后aop方法用以下命令可查看编译后的app.dill文件内容:

dart dump_kernel.dart /Users/warren/Project/openSource/aspectd/lib/src/flutter_frontend_server/frontend_server.dart.snapshot ~/app.dill.text

2.gen_snapshot 命令

GenSnapshot.run 具体命令根据前面的封装,针对 Android 和 iOS 平台各有不同:

针对 Android:

上述命令主要是将 dart kernel 转换为机器码,对应流程图为

此处的 gen_snapshot 是一个二进制可执行文件,主要作用是将 dart 代码生成 AOT 二进制机器码。

相关推荐
子春一1 小时前
Flutter for OpenHarmony:构建一个 Flutter 四色猜谜游戏,深入解析密码逻辑、反馈算法与经典益智游戏重构
算法·flutter·游戏
铅笔侠_小龙虾1 小时前
Flutter 实战: 计算器
开发语言·javascript·flutter
微祎_3 小时前
Flutter for OpenHarmony:构建一个 Flutter 重力弹球游戏,2D 物理引擎、手势交互与关卡设计的工程实现
flutter·游戏·交互
一起养小猫3 小时前
Flutter for OpenHarmony 实战_魔方应用UI设计与交互优化
flutter·ui·交互·harmonyos
hudawei9964 小时前
flutter和Android动画的对比
android·flutter·动画
一只大侠的侠4 小时前
Flutter开源鸿蒙跨平台训练营 Day7Flutter+ArkTS双方案实现轮播图+搜索框+导航组件
flutter·开源·harmonyos
一只大侠的侠5 小时前
Flutter开源鸿蒙跨平台训练营 Day9分类数据的获取与渲染实现
flutter·开源·harmonyos
一只大侠的侠5 小时前
Flutter开源鸿蒙跨平台训练营 Day 5Flutter开发鸿蒙电商应用
flutter·开源·harmonyos
ZH15455891316 小时前
Flutter for OpenHarmony Python学习助手实战:GUI桌面应用开发的实现
python·学习·flutter
一只大侠的侠7 小时前
Flutter开源鸿蒙跨平台训练营 Day6ArkUI框架实战
flutter·开源·harmonyos