2 个不稳定版本

0.2.0 2020年5月15日
0.1.1 2020年5月13日
0.1.0 2020年5月13日

#520编程语言

MIT 许可证

1.5MB
44K SLoC

C 41K SLoC // 0.1% comments GNU Style Assembly 1K SLoC // 0.1% comments Rust 750 SLoC // 0.0% comments Perl 306 SLoC // 0.2% comments Batch 171 SLoC Shell 28 SLoC

libtcc

CI (Linux) codecov crate.io

Rust 对 tcc 的绑定。

TinyCC(或tcc)是Tiny C Compiler的简称。它是一个小巧、快速、无限、安全的C语言编译器。此crate为libtcc提供安全包装,支持即时编译和代码生成的低级控制。

使用方法

要使用 libtcc,请将以下内容添加到您的 Cargo.toml

[dependencies]
libtcc = "0.1.1"

安装 tcc

尽管这个crate将 tcc 作为自身的一部分,您仍然需要在您的环境中安装 tcc。原因如下

  1. libtcc.a 需要小的但必要的运行时库(例如 libtcc1.a)和一些由 tcc 定义的头部文件(例如 stddef.h)
  2. 将 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();
}

更多示例

有关更多信息,请参阅 示例

贡献

欢迎所有贡献,如果您有功能请求,请毫不犹豫地提出问题!

许可证

本项目受

依赖项