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 二进制机器码。

相关推荐
君蓦11 小时前
Flutter 本地存储与数据库的使用和优化
flutter
problc21 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
lqj_本人1 天前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人1 天前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
起司锅仔2 天前
Flutter启动流程(2)
flutter
hello world smile2 天前
最全的Flutter中pubspec.yaml及其yaml 语法的使用说明
android·前端·javascript·flutter·dart·yaml·pubspec.yaml
lqj_本人2 天前
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
flutter·harmonyos
iFlyCai2 天前
极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
flutter
lqj_本人2 天前
Flutter&鸿蒙next 中使用 MobX 进行状态管理
flutter·华为·harmonyos