How to build C static library into a rust crate for no_std environmrnt

Hi

I am trying to create a rust crate from mbedtls C library that I compiled separately for my Cortex M4. But I ran into issue for what I believe is no_std related. My steps are following.

  1. I created a cargo lib project called mbedtls-sys with .toml below:

    [package]
    name = "mbedtls-sys"
    version = "0.1.0"
    authors = ["feplooptest"]
    edition = "2018"
    build = "build.rs"
    
    [build-dependencies]
    bindgen = "*"
    
  2. I created a binding using bindgen after looked at reference below:

    https://rust-embedded.github.io/book/interoperability/c-with-rust.html

    Since I need this to be no_std, I used "--ctypes-prefix=cty" and "--use-core" flag for bindgen.

    bindgen --ctypes-prefix=cty --use-core wrapper.h > src/lib.rs

  3. Finally I created a build.rs under to build this crate by following bindgen user guide.

    https://rust-lang.github.io/rust-bindgen/tutorial-3.html

    And my build.rs is following:

    extern crate bindgen;
    
    use std::env;
    use std::path::PathBuf;
    
    fn main() {
        println!("cargo:rustc-link-search=native=./mbedtls");
        println!("cargo:rustc-link-lib=static=mbedtls");
        println!("cargo:rustc-link-lib=static=mbedx509");
        println!("cargo:rustc-link-lib=static=mbedcrypto");
    
        // Tell cargo to invalidate the built crate whenever the wrapper changes
        println!("cargo:rerun-if-changed=wrapper.h");
    
        // The bindgen::Builder is the main entry point
        // to bindgen, and lets you build up options for
        // the resulting bindings.
        let bindings = bindgen::Builder::default()
            // The input header we would like to generate
            // bindings for.
            .header("wrapper.h")
            // Tell cargo to invalidate the built crate whenever any of the
            // included header files changed.
            .parse_callbacks(Box::new(bindgen::CargoCallbacks))
            // Finish the builder and generate the bindings.
            .generate()
            // Unwrap the Result and panic on failure.
            .expect("Unable to generate bindings");
    
        // Write the bindings to the $OUT_DIR/bindings.rs file.
        let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
        bindings
            .write_to_file(out_path.join("bindings.rs"))
            .expect("Couldn't write bindings!");
    }
    

Now when I try to run cargo build it spits out a lot of error like this:

    --> src/lib.rs:3180:43
     |
3180 |     pub fn mbedtls_rsa_self_test(verbose: cty::c_int) -> cty::c_int;
     |                                           ^^^ use of undeclared type or module `cty`

Does anyone know how to resolve this issue?
Thanks

Please read Forum Code Formatting and Syntax Highlighting and edit the above post by using the edit button under your post. All you need to do is place three back-ticks (```) on new lines before and after the code part(s) of your post.

Is your project set to use edition 2018? Have you added cty crate to the project?

Hi Thanks for the information.
Adding cty did get rid of that error, but now I am seeing another error when cargo build with rust project that reference that mebedtls-sys. For some reasons it still try to find std while building it. I feel that I am not setting mbedtls-sys crate correctly for no_std but I am not sure what is the correct way to do so.

error[E0463]: can't find crate for std
|
= note: the thumbv7em-none-eabi target may not be installed

error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error: could not compile mbedtls-sys.

Just realize that I need to add
#![no_std]
in my lib.rs to resolve that.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.