diff --git a/doc/Rust-to-LLGO-Migration-Guide.md b/doc/Rust-to-LLGO-Migration-Guide.md new file mode 100644 index 00000000..253aca82 --- /dev/null +++ b/doc/Rust-to-LLGO-Migration-Guide.md @@ -0,0 +1,125 @@ +# Rust to LLGO Migration Document + +### Add Dependencies & Build Configuration + +Edit `Cargo.toml` to include necessary dependencies and configuration: + +```toml +[dependencies] +libc = "0.2" +csv = "1.1" + +[lib] +crate-type = ["cdylib"] # The generated dynamic library will conform to the C standard +``` + +### Import C Language Types + +Use types from the libc package for interoperability with C: + +```rust +use libc::{c_int, c_char, strlen}; +``` + +### Function Decoration and Attributes + +To ensure that Rust functions can be correctly called by C and LLGO, use the following decorators: + +- `#[no_mangle]` prevents the compiler from mangling the function name. + +- `unsafe` is used to mark operations that are unsafe, especially when dealing with raw pointers. + +- `extern "C"` specifies the use of C calling conventions. + +### Memory Management + +Use `Box` to manage dynamic memory to ensure correct memory release between Rust and C: + +```rust +pub unsafe extern "C" fn sled_create_config() -> \*mut Config { +Box::into_raw(Box::new(Config::new())) +} + +#[no_mangle] +pub unsafe extern "C" fn sled_free_config(config: \*mut Config) { +drop(Box::from_raw(config)); +} +``` + +### Handling Generic Pointers + +Address the interfacing issues between generic pointers in C and Rust: + +```rust +#[no_mangle] +pub extern "C" fn csv_reader_new(file_path: *const c_char) -> *mut c_void { /* ... */ } + +#[no_mangle] +pub extern "C" fn csv_reader_free(ptr: *mut c_void) { /* ... */ } +``` + +### String Handling + +Convert strings between C and Rust: + +```rust +#[no_mangle] +pub extern "C" fn csv_reader_read_record(ptr: *mut c_void) -> *const c_char { /* ... */ } + +#[no_mangle] +pub extern "C" fn free_string(s: *mut c_char) { + unsafe { + let c_string = CString::from_raw(s); + drop(c_string); + } +} +``` + +### Compilation and Installation + +Build the dynamic library and use `dylib-installer` to install it to the system path: + +```sh +cargo build --release +cargo install --git https://github.com/hackerchai/dylib-installer +sudo dylib_installer ./target/release/ +``` + +### Generate Header File + +Use cbindgen to generate a C header file, automating this process through a `build.rs` script: + +```rust +fn main() { + let config = cbindgen::Config::from_file("cbindgen.toml").expect("Config file not found."); + cbindgen::generate_with_config(&crate_dir, config).unwrap().write_to_file("target/include/csv_wrapper.h"); +} + +``` + +### LLGO Package Mapping + +Map functions from the Rust library to an LLGO package, ensuring type consistency: + +```go +const ( + LLGoPackage = "link: $(pkg-config --libs csv_wrapper); -lcsv_wrapper" +) + +type Reader struct { + Unused [8]byte +} + +//go:linkname NewReader C.csv_reader_new +func NewReader(file_path *c.Char) *Reader + +//llgo:link (*Reader).Free C.csv_reader_free +func (reader *Reader) Free() {} + +//llgo:link (*Reader).ReadRecord C.csv_reader_read_record +func (reader *Reader) ReadRecord() *c.Char { return nil } +``` + +### Writing Examples and README + +Provide example code and a detailed README file to help users understand how to use the generated library.