文章目录
  1. 1. rinf命令行的实现方式
  2. 2. rinf template创建项目模板的过程
  3. 3. rinf message生成protobuf代码的过程
  4. 4. Rinf项目构建过程

前一篇文章中分析了Rinf生成的项目的部分代码, 本篇将对Rinf在github的源代码进行情境分析。

Rinf项目的源代码结构如下图, 顶层有4个目录, automate里包含一个项目作者用于方便开发的python脚本, documentation是项目官网的源代码, flutter_ffi_plugin为fultter相关的代码, rust_crate为rust相关的源代码,将生成rinf。

rinf-src

将要进行入如下的情境分析:

  • rinf命令行的实现方式
  • rinf template创建项目模板的过程
  • rinf message生成protobuf代码的过程
  • Rinf项目构建过程

参考:
https://github.com/cunarist/rinf

rinf命令行的实现方式

从之前介绍Rinf文章中知道, 使用命令cargo install rinf来安装的rinf命令行工具,则可知其是在Rust中实现的,主要源代码在rust_crate/src/main.rs中。main.rs中主要内容是main()主函数的实现,lib.rs则是用于生成的项目中使用。

rinf-src

main()的大体流程是,先检查是否存在protoc命令,不存在则安装;拼接flutter/dart执行路径后,将protoc命令与dart执行路径加入PATH环境,最后调用dart命令dart run rinf,并传递执行命令行时剩余的参数。代码中使用宏#[cfg(not(target_family = "wasm"))]#[cfg(target_family = "wasm")]来区分是否web wasm环境, 同样使用 #[cfg(target_family = "windows")] #[cfg(target_family = "unix")]区分windows与unix环境,进行有条件分别执行。

  1. 引用crate which来执行linux/linux下的which命令,查找是否存在protoc命令: which::which("protoc")
  2. 引用crate home来获取当前用户的主目录 let home_path = home::home_dir().unwrap();
  3. 引用crate protoc_prebuilt, let install_result = protoc_prebuilt::init("25.2");
  4. 使用process::Command来执行dart命令,处理命令行参数;执行的命令为dart run rinf,真正执行的逻辑又回到了dart代码中
    rinf-src

rinf template创建项目模板的过程

在分析rust代码可知, 执行的dart命令为dart run rinf, 对应的主文件为flutter_ffi_plugin/bin/rinf.dart, 代码如下图所示, 是dart中的main()方法。它对传入的第一个参数使用switch-case进行, 对config/template/message/wasm等子命令分别进行处理, template命令对应于函数applyRustTemplate(), 实现位于文件flutter_ffi_plugin/bin/src/helpers.dart中, 使用import 'src/helpers.dart'引入。

函数applyRustTemplate() 执行的大致流程如下,大多是文件复制与修改操作:

  1. 获取当前应用项目的包路径,并会读取项目中的pubspec.yaml,得到rinf包的路径
  2. 复制模板文件,将rinf包文件夹下的example/native/的内容复制到项目下native/,将example/messages/复制到messages/
  3. 通过拼接字符串生成Rust项目的Cargo.toml, 更新.gitgnore文件, 并生成README.md文件
  4. 格式化dart文件./lib/main.dart, 然后进行修改操作,比如添加一行import './messages/generated.dart';, 在主函数main()的最开始部分加入调用await initializeRust();
  5. 最后调用generateMessageCode()生成protobuf文件

rinf-src

rinf message生成protobuf代码的过程

rinf message命令的实现方法为generateMessageCode(), 位于文件flutter_ffi_plugin/bin/src/message.dart中。从.proto文件生成编程语言的代码,主要是通过protoc命令行编译工具来生成,rinf message命令的确也是通过命令行调用protoc命令进行的。

  1. 先收集proto文件的列表,将文件中syntax开始的行替换为syntax = "proto3";即使用版本3,并插入一行package $resourceName;语句, 保证文件配置的完整
  2. 命令行调用protoc分别生成rust与dart的代码: rust代码使用参数--prost_out=$rustFullPath, 会自动安装rust crate protoc-gen-prost, 并为生成的包创建一个mod.rs文件; 生成dart代码使用参数--dart_out=$dartFullPath
  3. 修改生成的protobuf message代码,添加相互传递消息的实现代码: rust文件中添加函数get_dart_signal_receiver()send_signal_to_dart()的实现, 在generated.rs文件中添加handle_dart_signal()实现代码; dart文件中添加函数sendSignalToRust()的实现与变量rustSignalStream的定义,生成handleRustSignal()的实现。

Rinf项目构建过程

rinf项目的构建过程就是flutter/dart的项目的构建,因为项目主体是flutter,而rust是作为动态链接库存在, 在构建过程中使用dart自动化rust插件的编译过程即可。

rinf使用了dart库Cargokit来编译rust, 源代码在flutter_ffi_plugin/cargokit目录下。

文章目录
  1. 1. rinf命令行的实现方式
  2. 2. rinf template创建项目模板的过程
  3. 3. rinf message生成protobuf代码的过程
  4. 4. Rinf项目构建过程