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

相关推荐
科昂2 小时前
Dart 单线程异步模型:从原理到工程实践的系统化解析
android·flutter·dart
fundroid3 小时前
2025 跨平台技术如何选:KMP 与 Flutter 的核心差异
flutter·kotlin·kmp
耳東陈5 小时前
Flutter开箱即用一站式解决方案-新增企业级日志
flutter
顾林海5 小时前
Flutter 图片组件全面解析:从基础加载到高级应用
android·前端·flutter
眼镜会飞5 小时前
Flutter window和Mac中webview2使用Cef替代
windows·flutter·mac
淡写成灰5 小时前
Flutter自定义带有Badger组件组
flutter
好的佩奇6 小时前
Dart 之任务
android·flutter·dart
豪冷啊19 小时前
Flutter Invalid constant value.
flutter
顾林海1 天前
Flutter容器组件深度解析
android·前端·flutter
xq95271 天前
mac os flutter 配置环境变量
flutter