FFI C binding / Rust project deps

Hello.
I have a problem with adding to deps mylib.
Mylib is written in C (Makefile).
Output Lib file: stack/lib/mylibc.a
My Lib Rust path: mylibc/stack/lib/rust

Rust Project

Cargo.toml:

mylib_rs = { git = "ssh://fakedomain.com/mylib.git", branch = "master" }

Error in Rust project:

error: could not find native static library `mylibc`, perhaps an -L flag is missing?
error: aborting due to previous error
error: could not compile `mylib_sys`.

How to fix? How to integrate with Rust?

You may be interested in the following post about -sys crates, especially the part that mentions building from source: https://kornel.ski/rust-sys-crate#source

The idea is that, instead of using the Cargo.toml file, since it is intended to be used for Rust libraries only, to use a build.rs script that will compile the the C lib;

  • either directly, through some calls to the C compiler (cc),

  • or through some build system, such as make, which can be called directly, assuming it is installed on the target machine (fair assumption, to start with, I'd say), by using Process::Command:

    //! build.rs
    use ::std::{io, process, ops::Not};
    
    fn main ()
      -> io::Result<()>
    {Ok({
        // cd /some/path && make all ...
        let make_cmd = &mut process::Command::new("make");
        let make_cmd =
            make_cmd
                .working_dir("/some/path")
                .args(&["all", ...])
        ;
        let status = make_cmd.status()?; // run the command
        if status.success().not() {
            panic!("Command `{:?}` failed", make_cmd);
        }
    
        // Now add `-L /some/path/` and `-l some_name`
        println!(r#"cargo:rustc-link-lib=static=/some/path/"#)
        println!(r#"cargo:rustc-link-search=native=some_name"#); // <- can also be achieved by annotating an `extern {}` block with `#[link(name = "some_name")]`
    })}
    

And as shown in this example, once the lib has compiled, you "just" have to emit the appropiate -l and -L flags so that the linker manages to find the C (static) library.

Finally, you should, although don't strictly have to, add a links = "some_name" line to your Cargo.toml, to improve the error message when multiple Rust crates attempt to link to the same library.

1 Like

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.