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

相关推荐
jcLee9510 小时前
Flutter/Dart:使用日志模块Logger Easier
flutter·log4j·dart·logger
tmacfrank11 小时前
Flutter 异步编程简述
flutter
tmacfrank11 小时前
Flutter 基础知识总结
flutter
叫我菜菜就好12 小时前
【Flutter_Web】Flutter编译Web第三篇(网络请求篇):dio如何改造方法,变成web之后数据如何处理
前端·网络·flutter
AiFlutter16 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
m0_748247802 天前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
迷雾漫步者2 天前
Flutter组件————PageView
flutter·跨平台·dart
迷雾漫步者2 天前
Flutter组件————FloatingActionButton
前端·flutter·dart
coder_pig2 天前
📝小记:Ubuntu 部署 Jenkins 打包 Flutter APK
flutter·ubuntu·jenkins
捡芝麻丢西瓜2 天前
flutter自学笔记5- dart 编码规范
flutter·dart