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

相关推荐
我要最优解6 小时前
关于在mac中配置Java系统环境变量
java·flutter·macos
江上清风山间明月2 天前
Flutter开发的应用页面非常多时如何高效管理路由
android·flutter·路由·页面管理·routes·ongenerateroute
Zsnoin能2 天前
flutter国际化、主题配置、视频播放器UI、扫码功能、水波纹问题
flutter
早起的年轻人2 天前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
HappyAcmen2 天前
关于Flutter前端面试题及其答案解析
前端·flutter
coooliang2 天前
Flutter 中的单例模式
javascript·flutter·单例模式
coooliang2 天前
Flutter项目中设置安卓启动页
android·flutter
JIngles1232 天前
flutter将utf-8编码的字节序列转换为中英文字符串
java·javascript·flutter
B.-3 天前
在 Flutter 中实现文件读写
开发语言·学习·flutter·android studio·xcode
freflying11193 天前
使用jenkins构建Android+Flutter项目依赖自动升级带来兼容性问题及Jenkins构建速度慢问题解决
android·flutter·jenkins