本项目将在c2rust已有工作的基础之上,实现一个可将不安全的Rust代码转换为更安全的Rust代码的原型系统,该系统可删除重复的类型定义,移除部分不必要的unsafe标记,并将部分裸指针转换为安全引用。
本系统原型由三部分组成:
翻译前端 - c2rust
将c2rust作为本系统原型的翻译前端,进行C到Rust的翻译;将得到的翻译结果作为优化工具better的输入。
优化工具 - safer
对c2rust翻译得到的初始版本的Rust代码进行优化,主要分为三个优化模块:Imports Resolver、Lifetime Resolver和Unsafe Fixer,进行重复类型定义的去除和安全性的提升。
统计工具 - stat
项目结构
c2rust/
+ docs/ -- 项目文档
+ exmamples/ -- 测试例
+ safe-analyzer/ -- 安全指标分析工具
+ scripts/ -- 辅助脚本,包括三个优化模块的默认前处理脚本
+ src/ -- 项目源代码文件
+ results/ -- (运行创建)结果数据,可由config.toml定义
+ bin/ -- (运行创建)编译后的可执行文件,可由config.toml定义
+ logs/ -- (运行创建)日志文件
- build.py -- 自动构建脚本
- run.py -- 运行入口脚本
- config.toml -- 项目配置文件
- pyproject.toml -- python环境配置文件
项目结构
C Program
|
| C2Rust(翻译前端)
V
Unsafe rust program:重复类型定义 + extern + unsafe
|
| ResolveImports (优化工具better)
V
Unsafe rust program:已去除重复类型定义,消除非必要的extern,使用use引入,消除非必要的unsafe
|
| ResolveLifetimes (优化工具better)
V
unsafe rust program: unsafe范围过大
|
| unsafe-fixer (优化工具unsafe-fixer)
V
Safer rust program:去除重复类型定义,消除非必要的unsafe,改写部分裸指针
安装前置依赖
openEuler/CentOS
sudo yum update
sudo yum install git gcc gcc-c++ llvm llvm-devel clang clang-devel make cmake ninja-build openssl-devel pkgconfig python3
Ubuntu/Debian
sudo apt-get update
sudo apt-get install git build-essential llvm llvm-dev clang libclang-dev make cmake ninja-build libssl-dev pkg-config python3
克隆项目仓库到本地
git clone https://gitee.com/openeuler/c2rust.git
安装rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
注:如因网络问题失败,可尝试更换国内源
将本地rust的lib加入LD_LIBRARY_PATH
环境变量,文件夹位于$HOME/.rustup/toolchains/nightly-2021-11-22-<PLATFORM>-<OS>/lib
与$HOME/.rustup/toolchains/nightly-2021-11-22-<PLATFORM>-<OS>/lib/rustlib/<PLATFORM>-<OS>/lib
内,其中<PLATFORM>
与<OS>
依赖于具体的架构与操作系统:
如在操作系统为openEuler
、架构为arm64
的情况下,运行:
echo 'export LD_LIBRARY_PATH="$HOME/.rustup/toolchains/nightly-2021-11-22-aarch64-unknown-linux-gnu/lib/":$LD_LIBRARY_PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="$HOME/.rustup/toolchains/nightly-2021-11-22-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib/":$LD_LIBRARY_PATH' >> ~/.bashrc
如在操作系统为Ubuntu
、架构为x86_64
平台上,则运行:
echo 'export LD_LIBRARY_PATH="$HOME/.rustup/toolchains/nightly-2021-11-22-x86_64-unknown-linux-gnu/lib/":$LD_LIBRARY_PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="$HOME/.rustup/toolchains/nightly-2021-11-22-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/":$LD_LIBRARY_PATH' >> ~/.bashrc
最后运行:
source ~/.bashrc
安装safer-c2rust
自动构建与运行的python环境,在项目目录下运行:
pip3 install -e .
注:如因网络问题失败,可尝试更换国内pip源
运行自动构建脚本:
python3 build.py -a
注:过程中可能因为github访问、或cargo源的网络问题而失败,可以尝试更换网络或者cargo源再次运行
safer-c2rust
的运行入口是根目录中的run.py
文件,运行命令
python3 run.py --help
可以获取脚本的使用方法,run.py
脚本包括了三个子命令,分别是:
c2rust
: 原生c2rust
的命令接口safer
: safer-c2rust
的命令接口stat
: 结果统计命令可以通过在子命令后加入--help
选项获取帮助信息,如:
python3 run.py safer --help
run.py
的子命令可以链式调用或者单独使用,例如将path/to/c_project
的C语言项目,直接转换为优化后的Rust项目,并获得优化统计结果,可以直接运行:
python3 run.py c2rust --local_path path/to/c_project safer stat
如果想使用safer
子命令对已经使用c2rust
工具转换的项目进行优化,需要这样运行:
python3 run.py -w path/to/result safer --project path/to/c2rust_result_project
这条命令将已经使用原生c2rust
工具转换的结果path/to/c2rust_result_project
使用safer
工具优化,并将最终结果存储在path/to/result
文件夹中
osc
获取原始项目运行通过设置项目名与osc
分支名,可以直接远程获取C项目与默认编译选项,其中osc
的的源地址可以在config.toml
中进行配置,运行命令如下:
python3 run.py c2rust --src osc --project_name NAME --osc_branch BRANCH safer stat
C2Rust
转换默认情况下,--mode
选项为auto
,此时运行脚本会选择使用cmake
或者make
(默认)工具进行原生c2rust转换,但是用户可以通过将自定义脚本进行原生c2rust转换,通过将--mode
设为script
并使用--script
指定一个shell或者python脚本运行。
python3 run.py c2rust --local_path path/to/c_project --mode script --script FILE safer stat
在没有指定work_dir
的情况下,运行结果或生成在项目目录下的results/<c_project_foldername>_<date>_<time>
文件夹中,其中包括以下文件:
-P0_original
: 输入c项目的备份
-P1_after_c2rust
: 经过原生c2rust转换之后的项目
-P2_after_resolve_imports
: 经过imports resolver模块优化后的项目
-P3_after_resolve_lifetime
: 经过lifetime resolver模块优化后的项目
-P4_result
: 经过unsafe fixer模块优化后的最终结果
-report_detail.json
: 优化后的各种指标的详细记录
-report_summary.json
: 优化后指标的统计结果
-w, --work_dir
: 工具的工作文件夹,默认情况下,会生成在./results/<project-name>_<datetime>
文件中c2rust
子命令选项-s, --src
: 该选项的值可以为local
(默认)或者osc
,为local
时需要--local_path
指定C项目文件夹,为osc
时,需要--project_name
指定项目名称与--osc_branch
指定osc
分支名称--local_path
: 指定C项目文件夹--project_name
: 指定osc
上的项目名称--osc_branch
: 指定osc
分支名称,默认为:openEuler-22.03-LTS-SP1--mode
: 该选项的值可以为auto
(默认)或者script
,选择auto
的情况下将获取--gencc
的值自动进行c2rust
转换,而如果选择script
,则执行--script
的脚本进行转换--gencc
: 该选项的值可以为cmake
或者makefile
(默认),这里将决定该用什么工具生成compile_commands.json
文件--script
: 如果--mode
的值为script
,那么程序将执行这里给出的shell
或者python
脚本进行转换,需要注意的是,转换脚本必须接收且只接收两个参数,第一个为需要转换c项目地址,第二个为输出地址。safer
子命令,包括以下子选项--project
: 如果要单独调用safer
子命令,该选项可以设置safer工具进行优化的目标,通常为c2rust转换后的结果,--is_resolve_imports
: 是否使用imports-resolver模块进行优化,默认为True
;--is_resolve_lifetime
: 同--is_resolve_imports
;--is_fix_unsafe
: 同--is_resolve_imports
;stat
子命令没有选项详见目录中 example/jsonc
文件夹
详见目录中 example/libxml2
文件夹
详见目录中 example/curl
文件夹
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型