Search code examples
rustcompiler-errorsdpdk

Why Rust build.rs is unable to find C headers?


Basically I am trying to cargo build a crate which has a build.rs file. This crate is located inside a bigger project and it's supposed to be a lib crate. And inside this build.rs file, I am trying to compile a .C file which includes a couple of headers.

Fun fact: I got this build.rs file and crate structure from another little demo crate, and in that demo crate I had no problem to compile this exact C file with these headers.

FULL ERROR HERE:

Here is a link to github: https://github.com/mihaidogaru2537/FirecrackerPlayground/tree/dpdk_component/firecracker/src/dpdk_component

There is the crate I am talking about and you can also see the bigger project in which it resides. In the README file you can see the full error.

Either I do cargo build from the root of the big project or from the root of this problematic crate, the error is the same.

"cargo:warning=/usr/include/asm-generic/errno.h:5:10: fatal error: asm-generic/errno-base.h: No such file or directory cargo:warning= 5 | #include <asm-generic/errno-base.h>"

The missing file might change depending on the .flag("-I/path/..") calls I am doing inside the build.rs

As you can see, right now it's unable to find errno-base.h, but I am including the path to asm-generic.

Here is the code of the build.rs file from the crate where the compilation of this C file works, as you can see, I did not have to add any include flags before calling compile.

fn main() {
// Tell cargo to tell rustc to link the system bzip2
// shared library.
// println!("cargo:rustc-link-lib=rte_ring");
// println!("cargo:rustc-link-lib=rte_mempool");

// Tell cargo to invalidate the built crate whenever the wrapper changes
// println!("cargo:rerun-if-changed=wrapper.h");

let _src = ["src/static-functions.c"];
println!("cargo:rerun-if-changed=build.rs");

let mut builder = cc::Build::new();

let build = builder
    .file("src/static-functions.c")
    .flag("-Wno-unused-parameter");
build.compile("foo");

}

Additional info:

  1. The problematic crate is pretty small, see the link above. There is the build.rs file, C file and header file is inside the include directory.

  2. One thing that I suspect, is that the target of the bigger project:

TARGET = Some("x86_64-unknown-linux-musl")

might affect the way the C file is compiled.

In the project where the compilation is working, I am not using that linux-musl stuff.

  1. I am a total noob when it comes to Rust, but I do have a decent understanding of how C/C++ works.

  2. I am running the project on Ubuntu 20.04

  3. Those missing headers are a result of importing DPDK headers, I have DPDK libraries installed on the machine in question.

Let me know if you have any questions, sorry for the long read and thank you.


Solution

  • I somehow managed to fix it by adjusting the cargo build command to use x86_64-unknown-linux-gnu as target instead of x86_64-unknown-linux-musl (By default cargo build was doing the musl target somehow)

    So if you are trying to build a rust app which is using DPDK libraries and you are getting missing headers, make sure to try the following:

    cargo build --target=x86_64-unknown-linux-gnu
    

    Well if you have to use musl and there is no alternative, I don't have an answer. But to me this was enough.

    If someone has an explanation why musl is not working in this scenario, please let us know.

    Reddit Rust community helped me as well, check this link out if you are interested: https://www.reddit.com/r/rust/comments/mo3i08/unable_to_compile_c_file_inside_buildrs_headers/

    So Why build.rs was unable to find .C headers?

    ANSWER

    Because I was using x86_64-unknown-linux-musl as target.