Link libsodium statically for C code

I have a mixed application, that uses C code that is called from Rust. This C code uses the libsodium functions. What would be the best way to link the libsodium?

  1. I thought the easiest way would be to use an existing crate like "libsodium-sys", but the original symbols don't seem to be visible to the C code.

  2. I could port the makefile to a build.rs. But this is error prone and not very elegant

  3. I could statically link the prebuilt library. Now I have to generate and update binaries for every platform

How would you proceed in my position?

Thanks!

Would it be possible to go for option 1, but to simply define your own FFI rather than trying to reuse lo sodium's?

If that's a possibility then that seems simplest to me.

I don't really need a FFI, because I am using the libsodium only in the C code. All I need is that the library is linked to the binary and the original libsodium symbols are available in the global namespace. This does not work for me with libsodium-sys.

But I agree using a crate would definitely be the most attractive solution.

Edit: oh well, and I need the C headers somewhere. I don't think they are available with the rust crate, are they?

Don't port the Makefile, just the make invocation:

//! build.rs

use ::std::{ops::Not, process};

const PATH_TO_C_PROJECT: &str = "relative/path/to/c/project";

fn main ()
{
    let mut make_cmd = process::Command::new("make");
    let status =
        make_cmd
            .current_dir(PATH_TO_C_PROJECT)
            .args(&["libmy_lib.a", ...]) // or `.arg("build")` if the Makefile is set up for that
            .status()
            .unwrap_or_else(|err| panic!(
                "Error, failed to run command `{:?}`: {}", make_cmd, err,
            ))
    ;
    if status.success().not() {
        panic!("Error, command `{:?}` failed", make_cmd);
    }
    println!("cargo:rustc-link-lib=static=my_lib"); // -l mylib
    println!("cargo:rustc-link-search=native={}", PATH_TO_C_PROJECT); // -L ...
}

so that

extern "C" {
    // translation of my_lib.h to rust (_e.g._, through `bindgen`)
}

Just Works.

3 Likes

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.