Migrate C code to Rust

Last update: May 24, 2022

Travis Build Status GitHub Actions Status Azure Build Status Latest Version Rustc Version

C2Rust helps you migrate C99-compliant code to Rust. The translator (or transpiler) produces unsafe Rust code that closely mirrors the input C code. The primary goal of the translator is to preserve functionality; test suites should continue to pass after translation. Generating safe and idiomatic Rust code from C ultimately requires manual effort. However, we are building a scriptable refactoring tool that reduces the tedium of doing so. You can also cross-check the translated code against the original (tutorial).

Here's the big picture:

C2Rust overview

To learn more, check out our RustConf'18 talk on YouTube and try the C2Rust translator online at www.c2rust.com.

Documentation

To learn more about using and developing C2Rust, check out the manual. The manual is still a work-in-progress, so if you can't find something please let us know.

Installation

Prerequisites

C2Rust requires LLVM 6 or later with its corresponding clang compiler and libraries. Python 3.4 or later, CMake 3.4.3 or later, and openssl (1.0) are also required. These prerequisites may be installed with the following commands, depending on your platform:

  • Ubuntu 16.04, 18.04 & 18.10:

      apt install build-essential llvm-6.0 clang-6.0 libclang-6.0-dev cmake libssl-dev pkg-config python3
    
  • Arch Linux:

      pacman -S base-devel llvm clang cmake openssl python
    
  • NixOS / nix:

      nix-shell
    
  • OS X: XCode command-line tools and recent LLVM (we recommend the Homebrew version) are required.

      xcode-select --install
      brew install llvm python3 cmake openssl
    

Finally, installing the correct nightly Rust compiler with Rustup is required on all platforms. You will also need to add rustfmt and rustc-dev:

rustup install nightly-2019-12-05
rustup component add --toolchain nightly-2019-12-05 rustfmt rustc-dev

Installing from crates.io

cargo +nightly-2019-12-05 install c2rust

On OS X with Homebrew LLVM, you need to point the build system at the LLVM installation as follows:

LLVM_CONFIG_PATH=/usr/local/opt/llvm/bin/llvm-config cargo +nightly-2019-12-05 install c2rust

On Linux with Linuxbrew LLVM, you need to point the build system at the LLVM installation as follows:

LLVM_CONFIG_PATH=/home/linuxbrew/.linuxbrew/opt/llvm/bin/llvm-config cargo +nightly-2019-12-05 install c2rust    

Note: adjust LLVM_CONFIG_PATH accordingly if Linuxbrew was installed to your home directory.

On Gentoo, you need to point the build system to the location of libclang.so and llvm-config as follows:

LLVM_CONFIG_PATH=/path/to/llvm-config LIBCLANG_PATH=/path/to/libclang.so cargo +nightly-2019-12-05 install c2rust 

If you have trouble with building and installing, or want to build from the latest master, the developer docs provide more details on the build system.

Installing from Git

If you'd like to check our recently developed features or you urgently require a bugfixed version of c2rust you can install it directly from Git:

cargo +nightly-2019-12-05 install --git https://github.com/immunant/c2rust.git c2rust

Please note that the master branch is under constant development and you may expirience issues or crashes.

You should also set LLVM_CONFIG_PATH accordingly if required as described above.

Translating C to Rust

To translate C files specified in compile_commands.json (see below), run the c2rust tool with the transpile subcommand:

c2rust transpile compile_commands.json

(The c2rust refactor tool is also available for refactoring Rust code, see refactoring).

The translator requires the exact compiler commands used to build the C code. This information is provided via a compilation database file named compile_commands.json. (Read more about compilation databases here and here). Many build systems can automatically generate this file; we show a few examples below.

Once you have a compile_commands.json file describing the C build, translate the C code to Rust with the following command:

c2rust transpile path/to/compile_commands.json

To generate a Cargo.toml template for a Rust library, add the -e option:

c2rust transpile --emit-build-files path/to/compile_commands.json

To generate a Cargo.toml template for a Rust binary, do this:

c2rust transpile --binary myprog path/to/compile_commands.json

Where --binary myprog tells the transpiler to use the main method from myprog.rs as the entry point for a binary.

The translated Rust files will not depend directly on each other like normal Rust modules. They will export and import functions through the C API. These modules can be compiled together into a single static Rust library or binary.

There are several known limitations in this translator. The translator will emit a warning and attempt to skip function definitions that cannot be translated.

Generating compile_commands.json files

The compile_commands.json file can be automatically created using either cmake, intercept-build, or bear.

It may be a good idea to remove optimizations(-OX) from the compile commands file, as there are optimization builtins which we do not support translating.

... with cmake

When creating the initial build directory with cmake specify -DCMAKE_EXPORT_COMPILE_COMMANDS=1. This only works on projects configured to be built by cmake. This works on Linux and MacOS.

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ...

... with intercept-build

intercept-build (part of the scan-build tool) is recommended for non-cmake projects. intercept-build is bundled with clang under tools/scan-build-py but a standalone version can be easily installed via PIP with:

pip install scan-build

Usage:

intercept-build <build command>

You can also use intercept-build to generate a compilation database for compiling a single C file, for example:

intercept-build sh -c "cc program.c"

... with bear (linux only)

If you have bear installed, it can be used similarly to intercept-build:

bear <build command>

Contact

To report issues with translation or refactoring, please use our Issue Tracker.

To reach the development team, join our discord channel or email us at [email protected].

FAQ

I translated code on platform X but it didn't work correctly on platform Y

We run the C preprocessor before translation to Rust. This specializes the code to the host platform. For this reason, we do not support cross compiling translated code at the moment.

What platforms can C2Rust be run on?

The translator and refactoring tool support both macOS and Linux. Other features, such as cross checking the functionality between C and Rust code, are currently limited to Linux hosts.

Acknowledgements and Licensing

This material is available under the BSD-3 style license as found in the LICENSE file.

The C2Rust translator is inspired by Jamey Sharp's Corrode translator. We rely on Emscripten's Relooper algorithm to translate arbitrary C control flows.

This material is based upon work supported by the United States Air Force and DARPA under Contract No. FA8750-15-C-0124. Any opinions, findings and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the United States Air Force and DARPA. Distribution Statement A, “Approved for Public Release, Distribution Unlimited.”

GitHub

https://github.com/immunant/c2rust
Comments
  • 1. Translation of C's `va_copy` into Rust's `std::ffi::VaList::copy`

    There is no good way to perform syntax-directed translation of all possible C functions using va_list into a corresponding Rust function using std::ffi::VaList::copy. VaLists copy has the following signature:

    pub unsafe fn copy<F, R>(&self, f: F) -> R
                where F: for<'copy> FnOnce(VaList<'copy>) -> R;
    

    copy takes a closure whose input VaList cannot outlive the closure (e.g. it cannot be passed back as a result of the closure). This is so that va_end can be called on the input VaList once the closure returns.

    Since copy takes an immutable reference to the original va_list and std::ffi::VaList::arg requires a mutable reference, it is not possible to call std::ffi::VaList::arg inside the closure passed to copy. Therefore, a C function that calls va_arg on two va_lists (with one being a va_copy of the other) in the same basic block, cannot be expressed using the current Rust variadic function API

    Reviewed by thedataking at 2019-03-15 19:29
  • 2. StmtExpr dropped during translation (was lseek not translated)

    example:

    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    
    uintptr_t virt_to_phys(void* virt) {
    	long pagesize = sysconf(_SC_PAGESIZE);
    	int fd = open("/proc/self/pagemap", O_RDONLY);
    	lseek(fd, (uintptr_t) virt / pagesize * sizeof(uintptr_t), SEEK_SET);
    	uintptr_t phy = 0;
    	read(fd, &phy, sizeof(phy));
    	return (phy & 0x7fffffffffffffULL) * pagesize + ((uintptr_t) virt) % pagesize;
    }
    

    is translated to

    #![allow(dead_code,
             mutable_transmutes,
             non_camel_case_types,
             non_snake_case,
             non_upper_case_globals,
             unused_assignments,
             unused_mut)]
    extern crate libc;
    extern "C" {
        #[no_mangle]
        fn read(__fd: libc::c_int, __buf: *mut libc::c_void, __nbytes: size_t)
         -> ssize_t;
        #[no_mangle]
        fn sysconf(__name: libc::c_int) -> libc::c_long;
        #[no_mangle]
        fn open(__file: *const libc::c_char, __oflag: libc::c_int, _: ...)
         -> libc::c_int;
    }
    (...)
    #[no_mangle]
    pub unsafe extern "C" fn virt_to_phys(mut virt: *mut libc::c_void)
     -> intptr_t {
        let mut pagesize: libc::c_long = sysconf(_SC_PAGESIZE as libc::c_int);
        let mut fd: libc::c_int =
            open(b"/proc/self/pagemap\x00" as *const u8 as *const libc::c_char,
                 0i32);
        let mut phy: intptr_t = 0i32 as intptr_t;
        read(fd, &mut phy as *mut intptr_t as *mut libc::c_void,
             ::std::mem::size_of::<intptr_t>() as libc::c_ulong);
        panic!("Reached end of non-void function without returning");
    }
    
    Reviewed by emmericp at 2019-10-23 15:16
  • 3. c2rust not compiling on arch linux - c2rust build.rs terminating

    Hello all,

    I am trying to install c2rust on an arch Linux system. The cargo build --release fails. All dependencies are current and the rust toolchain is nightly-2019-12-05. The following is the messages that appear, with back trace at 1

    thats for any help tsmith9876

    [[email protected] c2rust-master]$ cargo fetch [[email protected] c2rust-master]$ cargo build --release Compiling libc v0.2.69 Compiling cfg-if v0.1.10 Compiling proc-macro2 v1.0.10 Compiling unicode-xid v0.2.0 Compiling syn v1.0.18 Compiling autocfg v1.0.0 Compiling log v0.4.8 Compiling serde v1.0.106 Compiling lazy_static v1.4.0 Compiling pkg-config v0.3.17 Compiling memchr v2.3.3 Compiling version_check v0.1.5 Compiling bitflags v1.2.1 Compiling getrandom v0.1.14 Compiling ryu v1.0.4 Compiling smallvec v1.4.0 Compiling ppv-lite86 v0.2.6 Compiling itoa v0.4.5 Compiling matches v0.1.8 Compiling byteorder v1.3.4 Compiling regex-syntax v0.6.17 Compiling autocfg v0.1.7 Compiling rand_core v0.4.2 Compiling unicode-width v0.1.7 Compiling quick-error v1.2.3 Compiling typenum v1.12.0 Compiling siphasher v0.3.3 Compiling lazycell v1.2.1 Compiling failure_derive v0.1.7 Compiling rustc-demangle v0.1.16 Compiling fnv v1.0.6 Compiling glob v0.3.0 Compiling termcolor v1.1.0 Compiling yaml-rust v0.3.5 Compiling ansi_term v0.11.0 Compiling strsim v0.8.0 Compiling proc-macro2 v0.4.30 Compiling percent-encoding v2.1.0 Compiling vec_map v0.8.1 Compiling siphasher v0.2.3 Compiling same-file v1.0.6 Compiling maplit v1.0.2 Compiling unicode-xid v0.1.0 Compiling ucd-trie v0.1.3 Compiling semver-parser v0.7.0 Compiling syn v0.15.44 Compiling version_check v0.9.1 Compiling new_debug_unreachable v1.0.4 Compiling unicode-segmentation v1.6.0 Compiling shlex v0.1.1 Compiling openssl-probe v0.1.2 Compiling curl v0.4.28 Compiling bindgen v0.52.0 Compiling mac v0.1.1 Compiling httparse v1.3.4 Compiling maybe-uninit v2.0.0 Compiling traitobject v0.1.0 Compiling rustc-hash v1.1.0 Compiling crc32fast v1.2.0 Compiling utf-8 v0.7.5 Compiling foreign-types-shared v0.1.1 Compiling remove_dir_all v0.5.2 Compiling openssl v0.10.29 Compiling precomputed-hash v0.1.1 Compiling peeking_take_while v0.1.2 Compiling safemem v0.3.3 Compiling ident_case v1.0.1 Compiling utf8parse v0.1.1 Compiling adler32 v1.0.4 Compiling percent-encoding v1.0.1 Compiling either v1.5.3 Compiling language-tags v0.2.2 Compiling byte-tools v0.3.1 Compiling hex v0.3.2 Compiling typeable v0.1.2 Compiling half v1.5.0 Compiling slab v0.4.2 Compiling bytesize v1.0.0 Compiling rustc-workspace-hack v1.0.0 Compiling opener v0.4.1 Compiling shell-escape v0.1.4 Compiling hex v0.4.2 Compiling modifier v0.1.0 Compiling home v0.5.3 Compiling c2rust-refactor v0.14.0 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust-refactor) Compiling c2rust-ast-builder v0.14.0 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust-ast-builder) Compiling sequence_trie v0.3.6 Compiling pulldown-cmark v0.5.3 Compiling json v0.12.4 Compiling slotmap v0.4.0 Compiling pulldown-cmark v0.6.1 Compiling opaque-debug v0.2.3 Compiling diff v0.1.12 Compiling strum v0.16.0 Compiling fake-simd v0.1.2 Compiling dtoa v0.4.5 Compiling pathdiff v0.1.0 Compiling is-match v0.1.0 Compiling glob v0.2.11 Compiling pulldown-cmark v0.2.0 Compiling strum v0.15.0 Compiling open v1.4.0 Compiling c2rust-asm-casts v0.1.1 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust-asm-casts) Compiling thread_local v1.0.1 Compiling crossbeam-utils v0.6.6 Compiling num-traits v0.2.11 Compiling num-integer v0.1.42 Compiling crossbeam-utils v0.7.2 Compiling indexmap v1.3.2 Compiling unicode-normalization v0.1.12 Compiling unicode-bidi v0.3.4 Compiling unicase v1.4.2 Compiling nom v4.2.3 Compiling rand_core v0.3.1 Compiling rand_jitter v0.1.4 Compiling textwrap v0.11.0 Compiling getopts v0.2.21 Compiling humantime v1.3.0 Compiling phf_shared v0.8.0 Compiling rand_pcg v0.1.2 Compiling rand_chacha v0.1.1 Compiling rand v0.6.5 Compiling clang-sys v0.28.1 Compiling walkdir v2.3.1 Compiling pest v2.1.3 Compiling heck v0.3.1 Compiling futf v0.1.4 Compiling unicase v2.6.0 Compiling error-chain v0.12.2 Compiling unsafe-any v0.4.2 Compiling foreign-types v0.3.2 Compiling vte v0.3.3 Compiling miniz_oxide v0.3.6 Compiling itertools v0.8.2 Compiling block-padding v0.1.5 Compiling gitignore v1.0.6 Compiling rand_isaac v0.1.1 Compiling rand_xorshift v0.1.1 Compiling rand_hc v0.1.0 Compiling idna v0.2.0 Compiling idna v0.1.5 Compiling phf v0.8.0 Compiling tendril v0.4.1 Compiling typemap v0.3.3 Compiling strip-ansi-escapes v0.1.0 Compiling pest_meta v2.1.3 Compiling jobserver v0.1.21 Compiling time v0.1.43 Compiling atty v0.2.14 Compiling num_cpus v1.13.0 Compiling rand_os v0.1.3 Compiling filetime v0.2.9 Compiling which v3.1.1 Compiling socket2 v0.3.12 Compiling iovec v0.1.4 Compiling net2 v0.2.33 Compiling fs2 v0.4.3 Compiling inotify-sys v0.1.3 Compiling quote v1.0.3 Compiling log v0.3.9 Compiling c2rust-ast-printer v0.14.0 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust-ast-printer) Compiling ena v0.13.1 Compiling aho-corasick v0.7.10 Compiling bstr v0.2.12 Compiling base64 v0.9.3 Compiling url v2.1.1 Compiling url v1.7.2 Compiling sized-chunks v0.3.1 Compiling generic-array v0.12.3 Compiling quote v0.6.13 Compiling plugin v0.2.6 Compiling cc v1.0.52 Compiling rand_core v0.5.1 Compiling clap v2.33.0 Compiling colored v1.9.3 Compiling tar v0.4.26 Compiling bytes v0.4.12 Compiling mio v0.6.21 Compiling inotify v0.7.0 Compiling mime v0.2.6 Compiling regex v1.3.7 Compiling crossbeam-channel v0.4.2 Compiling cexpr v0.3.6 Compiling phf_shared v0.7.24 Compiling block-buffer v0.7.3 Compiling digest v0.8.1 Compiling rand_chacha v0.2.2 Compiling rand_pcg v0.2.1 Compiling cmake v0.1.42 Compiling mio-extras v2.0.6 Compiling hyper v0.10.16 Compiling openssl-sys v0.9.55 Compiling libz-sys v1.0.25 Compiling backtrace-sys v0.1.36 Compiling libnghttp2-sys v0.1.3 Compiling libssh2-sys v0.2.17 Compiling libloading v0.5.2 Compiling curl-sys v0.4.30+curl-7.69.1 Compiling libgit2-sys v0.9.2 Compiling rlua v0.17.0 Compiling chrono v0.4.11 Compiling env_logger v0.7.1 Compiling env_logger v0.6.2 Compiling globset v0.4.5 Compiling synstructure v0.12.3 Compiling pest_generator v2.1.3 Compiling phf v0.7.24 Compiling phf_generator v0.7.24 Compiling sha-1 v0.8.2 Compiling darling_core v0.8.6 Compiling pulldown-cmark-to-cmark v1.2.4 Compiling rand v0.7.3 Compiling notify v4.0.15 Compiling fern v0.5.9 Compiling ignore v0.4.14 Compiling serde_derive v1.0.106 Compiling html5ever v0.25.1 Compiling derive_more v0.99.5 Compiling c2rust-macros v0.14.0 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust-macros) Compiling strum_macros v0.16.0 Compiling c2rust-bitfields-derive v0.2.1 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust-bitfields-derive) Compiling phf_codegen v0.7.24 Compiling pest_derive v2.1.0 Compiling phf_generator v0.8.0 Compiling tempfile v3.1.0 Compiling ws v0.9.1 Compiling strum_macros v0.15.0 Compiling darling_macro v0.8.6 Compiling mime_guess v1.8.8 Compiling phf_codegen v0.8.0 Compiling string_cache_codegen v0.5.1 Compiling c2rust-bitfields v0.3.0 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust-bitfields) Compiling flate2 v1.0.14 Compiling backtrace v0.3.46 Compiling darling v0.8.6 Compiling crypto-hash v0.3.4 Compiling failure v0.1.7 Compiling serde_json v1.0.51 Compiling semver v0.9.0 Compiling toml v0.5.6 Compiling string_cache v0.8.0 Compiling hashbrown v0.5.0 Compiling serde_bytes v0.10.5 Compiling serde_bytes v0.11.3 Compiling serde_cbor v0.10.2 Compiling serde_ignored v0.1.1 Compiling toml-query_derive v0.9.2 Compiling rustc_version v0.2.3 Compiling rustfix v0.4.6 Compiling elasticlunr-rs v2.3.6 Compiling handlebars v3.0.1 Compiling handlebars v2.0.4 Compiling serde_bencode v0.2.1 Compiling markup5ever v0.10.0 Compiling crates-io v0.28.0 Compiling iron v0.6.1 Compiling toml-query v0.9.2 Compiling im-rc v13.0.0 Compiling c2rust v0.14.0 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust) Compiling mount v0.4.0 error: failed to run custom build command for c2rust v0.14.0 (/home/tsmith/source/c-2-rust/c2rust-master/c2rust)

    Caused by: process didn't exit successfully: /home/tsmith/source/c-2-rust/c2rust-master/target/release/build/c2rust-a77143204259fa86/build-script-build (exit code: 101) --- stdout the build process entered the build.rs file in crust dir

    --- stderr thread 'main' panicked at 'Could not parse expected toolchain version', src/libcore/option.rs:1188:5 stack backtrace: 0: backtrace::backtrace::libunwind::trace at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88 1: backtrace::backtrace::trace_unsynchronized at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66 2: std::sys_common::backtrace::_print_fmt at src/libstd/sys_common/backtrace.rs:84 3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt at src/libstd/sys_common/backtrace.rs:61 4: core::fmt::write at src/libcore/fmt/mod.rs:1024 5: std::io::Write::write_fmt at src/libstd/io/mod.rs:1428 6: std::sys_common::backtrace::_print at src/libstd/sys_common/backtrace.rs:65 7: std::sys_common::backtrace::print at src/libstd/sys_common/backtrace.rs:50 8: std::panicking::default_hook::{{closure}} at src/libstd/panicking.rs:193 9: std::panicking::default_hook at src/libstd/panicking.rs:210 10: std::panicking::rust_panic_with_hook at src/libstd/panicking.rs:471 11: rust_begin_unwind at src/libstd/panicking.rs:375 12: core::panicking::panic_fmt at src/libcore/panicking.rs:82 13: core::option::expect_failed at src/libcore/option.rs:1188 14: build_script_build::main 15: std::rt::lang_start::{{closure}} 16: std::rt::lang_start_internal::{{closure}} at src/libstd/rt.rs:52 17: std::panicking::try::do_call at src/libstd/panicking.rs:292 18: __rust_maybe_catch_panic at src/libpanic_unwind/lib.rs:78 19: std::panicking::try at src/libstd/panicking.rs:270 20: std::panic::catch_unwind at src/libstd/panic.rs:394 21: std::rt::lang_start_internal at src/libstd/rt.rs:51 22: main 23: __libc_start_main 24: _start note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.

    warning: build failed, waiting for other jobs to finish... error: build failed [[email protected] c2rust-master]$

    Reviewed by tsmith9876 at 2020-04-28 22:42
  • 4. error: cannot find derive macro `BitfieldStruct` in this scope

    I tried to manually fix it for about a half hour and wasn't able to, so I don't think it is trivial. (from https://github.com/ctaggart/openconnect-rust/issues/5)

    Camerons-MacBook-Pro:openconnect-rust cameron$ cargo build
       Compiling openconnect-rust v0.0.0 (/Users/cameron/github/openconnect-rust)
    error: cannot find derive macro `BitfieldStruct` in this scope
        --> src/tun.rs:1198:29
         |
    1198 |     #[derive ( Copy, Clone, BitfieldStruct )]
         |                             ^^^^^^^^^^^^^^
    
    error: cannot find derive macro `BitfieldStruct` in this scope
        --> src/gpst.rs:1086:29
         |
    1086 |     #[derive ( Copy, Clone, BitfieldStruct )]
         |                             ^^^^^^^^^^^^^^
    

    It is complaining about:

    https://github.com/ctaggart/openconnect-rust/blob/28ff0a3ca51386d841638c7fff9fe6a862e7465d/src/tun.rs#L1198-L1215

        #[derive ( Copy, Clone, BitfieldStruct )]
        #[repr(C)]
        #[src_loc = "81:1"]
        pub struct ip {
            #[bitfield(name = "ip_hl", ty = "u_int", bits = "0..=3")]
            #[bitfield(name = "ip_v", ty = "u_int", bits = "4..=7")]
            pub ip_hl_ip_v: [u8; 1],
            pub ip_tos: u_char,
            pub ip_len: u_short,
            pub ip_id: u_short,
            pub ip_off: u_short,
            pub ip_ttl: u_char,
            pub ip_p: u_char,
            pub ip_sum: u_short,
            pub ip_src: in_addr,
            pub ip_dst: in_addr,
            /* source and dest address */
        }
    
    Reviewed by ctaggart at 2019-10-24 22:38
  • 5. Add --preserve-unused-functions

    to keep otherwise pruned static / inline functions.

    Closes: https://github.com/immunant/c2rust/issues/287


    This is an initial simple approach to #287. It looks like it's generating valid code, but I'm too early in my whole evaluation of c2rust to say whether what comes out of this will work, so please take it with due care. (Also, tests don't pass, but neither do they pass on my machine on current master, so...)

    I'm playing fast and lose with API stability here, as I don't have the overview to tell whether prune_unused_decls is part of any practically public API. If it is, I can replace the added parameter with a second function prune_unused_decls_but_not_functions and rename the current implementation to a private impl one.

    Reviewed by chrysn at 2020-09-03 12:41
  • 6. hex literal error

    This: static const uint8_t access_conditions_and_gpb_bytes[4] = "\x78\x77\x88\xcb";

    Got translated as: static mut access_conditions_and_gpb_bytes: [uint8_t; 4] = [120, 119, -120, -53];

    Generating rust error:

    1532 | [120, 119, -120, -53]; | ^^^^ cannot apply unary operator -

    Expected result: static mut access_conditions_and_gpb_bytes: [uint8_t; 4] = [0x78, 0x77, 0x88, 0xcb];

    Reviewed by mmacedoeu at 2019-09-20 17:42
  • 7. there are some errors while translating tinyexpr c library

    How to reproduce:

    1. go to https://c2rust.com/. I tried to use the online demo because establishing environment is boring.
    2. copy tinyexpr.h and tinyexpr.c as c source code https://raw.githubusercontent.com/codeplea/tinyexpr/master/tinyexpr.h https://raw.githubusercontent.com/codeplea/tinyexpr/master/tinyexpr.c
    3. run "Translate"
    4. cargo new a test app and copy the result .rs to the project
    5. compile and found below errors
    image
    Reviewed by piaoger at 2018-10-13 11:17
  • 8. Error on install: "subslice patterns are unstable"

    Hi,

    I recently tried to install c2rust using the README instructions. I installed the nightly-2019-12-05 toolchain, and ran cargo +nightly-2019-12-05 install c2rust. Unfortunately, I kept getting the following build error in several places.

    error[E0658]: subslice patterns are unstable --> /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/object-0.23.0/src/read/mod.rs:162:41 | 162 | [0x7f, b'E', b'L', b'F', 1, ..] => FileKind::Elf32, | ^^ | = note: for more information, see https://github.com/rust-lang/rust/issues/62254 = help: add #![feature(slice_patterns)] to the crate attributes to enable

    However, when I compile on the latest version I get past this error. However, I get a different one:

    error[E0462]: found staticlib rustc instead of rlib or dylib --> /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/c2rust-ast-builder-0.15.0/src/lib.rs:2:1 | 2 | extern crate rustc; | ^^^^^^^^^^^^^^^^^^^ | = help: please recompile that crate using --crate-type lib = note: the following crate versions were found:

    Is it possible that the targeted version of Nightly has changed without updating the README? Is there anything else I should try to install c2rust successfully?

    Reviewed by zdb999 at 2021-01-23 08:51
  • 9. Doesn't build with nightly-2020-01-31

    error[E0463]: can't find crate for `syntax_pos`
     --> github.com-1ecc6299db9ec823/c2rust-ast-builder-0.14.0/src/lib.rs:5:1
      |
    5 | extern crate syntax_pos;
      | ^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
    
    error: aborting due to previous error
    
    For more information about this error, try `rustc --explain E0463`.
    error: could not compile `c2rust-ast-builder`.
    
    ➤ rustc --version
    rustc 1.42.0-nightly (cd1ef390e 2020-01-31)
    
    Reviewed by berkus at 2020-02-03 00:01
  • 10. Failed translating declaration due to error: Unsupported vector default initializer: Int x 4, kind: Some(Function { is_extern: true, is_inline: true, is_implicit: false, typ: CTypeId(10934), name: "MyGetIP_comp", parameters: [CDeclId(23294)], body: Some(CStmtId(23293)) })'

    I used the following input:

    a.zip

    Here's the result:

    [19:27:38]  [email protected]:/tmp(101) > /home/d33tah/workspace/src/c2rust/target/release/c2rust transpile compile_commands.json --fail-on-error
    Transpiling a.c
    thread 'main' panicked at 'Failed translating declaration due to error: Unsupported vector default initializer: Int x 4, kind: Some(Function { is_extern: true, is_inline: true, is_implicit: false, typ: CTypeId(10934), name: "MyGetIP_comp", parameters: [CDeclId(23294)], body: Some(CStmtId(23293)) })', c2rust-transpile/src/translator/mod.rs:305:9
    note: Run with `RUST_BACKTRACE=1` for a backtrace.
    

    Are there any plans to add support for this feature?

    Reviewed by d33tah at 2019-03-28 18:28
  • 11. ast_exporter error after each file about -p

    ast_exporter: for the -p option: may only occur zero or one times!

    This error gets printed after each file and it stops. However if I rerun it, it progresses anyways and skips previously translated files, which after a quick visual inspection, didn't simply get outputted as empty files. I couldn't find anywhere this error might be coming from or any similar errors from Googling. I can complete this anyways, but it means running c2rust once for every file, or which the project I'm currently working on has 866.

    Reviewed by boomshroom at 2019-03-01 21:42
  • 12. Keep original label names from C code

    I have added an Option<Rc<str>> field to the cfg::Label::FromC. This allows to preserve the names of blocks which are provided in the C source, potentially increasing the readability of transpiled code and making it easier to match original and transpiled code blocks. The label names are used as control flow variable values when --ddebug-labels is enabled. Unfortunately, Relooper really likes to dump those names in the _ branch of matches, bringing the automatic label names to the front. Still, there are some situations where the old labels can be traced in the transpiled code. This will also significantly increase readability if Relooper is changed to use labeled blocks & breaks instead of a match on variable: the C label names can be directly used as block label names.

    I had to make Label non-Copy. This is not a painful transition, and arguably there was no reason to make it Copy in the first place, since it was likely to carry some non-Copy data.

    Reviewed by afetisov at 2022-05-21 01:38
  • 13. assembly translation ignores clang asm variants

    the following C code:

    int mul2_3(int var64)
    {
        int out;
        int dummy = 2;
        asm("add {%0, %2 | %2 %0}\n\t"
            "add %1, %1"
            : "=r"(out)
            : "r"(dummy), "0"(var64));
        return out;
    }
    

    will have the following LLVM assembly string: "add $($0, $2 $| $2 $0$)\n\tadd $1, $1"

    which gets translated into the following Rust

    #[no_mangle]
    pub unsafe extern "C" fn rust_mul2_3(mut var64: libc::c_int) -> libc::c_int {
        let mut out: libc::c_int = 0;
        let mut dummy: libc::c_int = 2 as libc::c_int;
        let fresh9 = &mut out;
        let fresh10;
        let fresh11 = var64;
        asm!(
            "add ({0}, {0} | {0} {0})\n\tadd {1}, {1}", inlateout(reg)
            c2rust_asm_casts::AsmCast::cast_in(fresh9, fresh11) => fresh10, inlateout(reg)
            dummy => _, options(preserves_flags, pure, readonly, att_syntax)
        );
        c2rust_asm_casts::AsmCast::cast_out(fresh9, fresh11, fresh10);
        return out;
    }
    

    In these cases it will be necessary to parse and identify which variant is which at some level of confidence, and choose an option to output.

    Reviewed by aneksteind at 2022-05-13 22:12
  • 14. Upgrade cmake-rs for AST explorer

    The bug is fixed in upstream but is yet released. This is needed to try to build AST explorer on Windows, in particular VS2022 and MSVC, this is so far the obstacle

    Reviewed by stevefan1999-personal at 2022-05-12 19:40
  • 15. inline assembly translator doesn't check dialect against host clang version

    Unlike GCC, inline assembly with Intel syntax is only supported in clang versions >= 14. There should be a check that at least warns the user that their inline assembly may not be interpreted correctly if their clang version is less than 14.

    Reviewed by aneksteind at 2022-05-11 00:05
Minimal, flexible framework for implementing solutions to Advent of Code in Rust

This is advent_of_code_traits, a minimal, flexible framework for implementing solutions to Advent of Code in Rust.

Apr 17, 2022
Simplified glue code generation for Deno FFI libraries written in Rust.

deno_bindgen This tool aims to simplify glue code generation for Deno FFI libraries written in Rust. Quickstart # install CLI deno install -Afq -n den

May 19, 2022
Easy to use Rust i18n library based on code generation

rosetta-i18n rosetta-i18n is an easy-to-use and opinionated Rust internationalization (i18n) library powered by code generation. rosetta_i18n::include

May 7, 2022
A simple code boilerplate generator written in Rust.

?? Cgen What is Cgen? A modern, cross-platform, multi-language boilerplate generator aimed to make your code generation less hectic! If you wish to su

Dec 25, 2021
A code coverage tool for Rust projects

Tarpaulin Tarpaulin is a code coverage reporting tool for the Cargo build system, named for a waterproof cloth used to cover cargo on a ship. Currentl

May 25, 2022
Rust macro that uses GPT3 codex to generate code at compiletime

gpt3_macro Rust macro that uses GPT3 codex to generate code at compiletime. Just describe what you want the function to do and (optionally) define a f

May 11, 2022
Generate bindings to use Rust code in Qt and QML
Generate bindings to use Rust code in Qt and QML

Rust Qt Binding Generator This code generator gets you started quickly to use Rust code from Qt and QML. In other words, it helps to create a Qt based

May 27, 2022
A rollup plugin that compile Rust code into WebAssembly modules

rollup-plugin-rust tl;dr -- see examples This is a rollup plugin that loads Rust code so it can be interop with Javascript base project. Currently, th

Mar 10, 2022
Common utilities code used across Fulcrum Genomics Rust projects

fgoxide Common utilities code used across Fulcrum Genomics Rust projects. Why? There are many helper functions that are used repeatedly across project

Feb 17, 2022
A library for generating TypeScript definitions from rust code.

Tsify is a library for generating TypeScript definitions from rust code. Using this with wasm-bindgen will automatically output the types to .d.

Apr 27, 2022
Rust library to scan files and expand multi-file crates source code as a single tree

syn-file-expand This library allows you to load full source code of multi-file crates into a single syn::File. Features: Based on syn crate. Handling

Apr 7, 2022
A simple quote-based code generator for Rust

flexgen A flexible, yet simple quote-based code generator for creating beautiful Rust code Why? Rust has two types of macros, and they are both very p

May 6, 2022
A cargo subcommand that displays the assembly generated for Rust source code

cargo-show-asm A cargo subcommand that displays the assembly generated for Rust source code.

May 26, 2022
Mix async code with CPU-heavy thread pools using Tokio + Rayon

tokio-rayon Mix async code with CPU-heavy thread pools using Tokio + Rayon Resources Documentation crates.io TL;DR Sometimes, you're doing async stuff

May 12, 2022
Waits until the exit code of a program is zero

Waitz A rust utility to wait that a program exits with 0. You need to wait for something to start up and don't know when it finishes?

Apr 10, 2022
Sample code for compute shader 101 training

Sample code for Compute Shader 101 This repo contains sample code to help you get started writing applications using compute shaders.

May 26, 2022
Detect if code is running inside a virtual machine (x86 and x86-64 only).

inside-vm Detect if code is running inside a virtual machine. Only works on x86 and x86-64. How does it work Measure average cpu cycles when calling c

Nov 15, 2021
Doku is a framework for building documentation with code-as-data methodology in mind.
Doku is a framework for building documentation with code-as-data methodology in mind.

Doku is a framework for building documentation with code-as-data methodology in mind. Say goodbye to stale, hand-written documentation - with D

May 12, 2022
A tool to run web applications on AWS Lambda without changing code.
A tool to run web applications on AWS Lambda without changing code.

AWS Lambda Adapter A tool to run web applications on AWS Lambda without changing code. How does it work? AWS Lambda Adapter supports AWS Lambda functi

May 25, 2022