2 个不稳定版本
0.2.0 | 2020年5月15日 |
---|---|
0.1.1 | 2020年5月13日 |
0.1.0 |
|
#520 在 编程语言
1.5MB
44K SLoC
libtcc
Rust 对 tcc 的绑定。
- API 文档(发布版本)
- Cargo 包: libtcc
TinyCC(或tcc)是Tiny C Compiler的简称。它是一个小巧、快速、无限、安全的C语言编译器。此crate为libtcc提供安全包装,支持即时编译和代码生成的低级控制。
使用方法
要使用 libtcc
,请将以下内容添加到您的 Cargo.toml
[dependencies]
libtcc = "0.1.1"
安装 tcc
尽管这个crate将 tcc
作为自身的一部分,您仍然需要在您的环境中安装 tcc。原因如下
- libtcc.a 需要小的但必要的运行时库(例如 libtcc1.a)和一些由 tcc 定义的头部文件(例如 stddef.h)
- 将 tcc 作为此 crate 的一部分使用的目的是支持交叉编译,您仍然需要在您的目标环境中安装 tcc,并且目标环境中 tcc 的安装不应更改安装前缀。
初始化保护
Tcc 在一次编译期间使用全局变量,这意味着用户不能同时编译程序。为了防止误用,我们提供了 Guard
。特定范围内只能存在一个保护,每个 tcc 实例都持有对保护的可变引用,以便 Rust 编译器可以通过借用检查器检测误用。
use libtcc::{Guard, Context};
fn main(){
let mut g1 = Guard::new();
assert!(g1.is_ok());
// let mut g2 = Guard::new();
// assert!(g2.is_err());
let ctx1 = Context::new(&mut g1).unwrap();
// compile error
// let ctx2 = Context::new(&mut g1).unwrap();
}
内存编译
use libtcc::{Guard, Context, OutputType};
use std::ffi::CString;
fn main(){
let p = CString::new(r#"
#include<stdio.h>
void greet(){
printf("hello world\n");
}
"#.as_bytes()).unwrap();
let mut g = Guard::new().unwrap();
let mut ctx = Context::new(&mut g).unwrap();
assert!(ctx.compile_string(&p).is_ok());
let mut relocated = ctx.relocate().unwrap();
let addr = unsafe {
relocated
.get_symbol(CStr::from_bytes_with_nul_unchecked("greet\0".as_bytes()))
.unwrap()
};
let greet: fn() = unsafe { transmute(addr) };
greet();
}
更多示例
有关更多信息,请参阅 示例。
贡献
欢迎所有贡献,如果您有功能请求,请毫不犹豫地提出问题!
许可证
本项目受
- MIT 许可证 (LICENSE-MIT 或 https://opensource.org/licenses/MIT)