0

I have multiple C libraries that I want to link to my Rust project. To do this I use multiple link attributes on the same extern block.

use libc::{c_int};

#[link(name = "zlib", kind = "static")]
#[link(name = "libpng", kind = "static")]
#[link(name = "vec", kind = "static")] 
extern "C" {        
    pub fn entrypoint(argc: c_int, argv: *mut *mut u8) -> c_int;
    pub fn just_crash() -> c_int;
}

I then use a build.rs script to add a search path on the directory containing my C libraries (.a files).

fn main() {
    stop_if_unknown_os();
    let dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let cwd = Path::new(&dir);

    println!("cargo:rustc-link-search=native={}", cwd.display());
    println!("cargo:rustc-link-search=native={}/../install/lib", cwd.display());
}

When I go to run cargo build -vv, I get some errors indicating that the definition of libpng functions used in the vec library, could not be found.

When I place the link attributes on multiple extern blocks it compiles successfully.

#[link(name = "vec", kind = "static")] 
extern "C" {        
    pub fn entrypoint(argc: c_int, argv: *mut *mut u8) -> c_int;
    pub fn just_crash() -> c_int;
}

#[link(name = "png16", kind = "static")]
extern "C" {}

#[link(name = "zlib", kind = "static")]
extern "C" {}

My question is why did the previous option not work?

Samuel Jenks
  • 1,137
  • 4
  • 21
  • 34

1 Answers1

1

Somnium was correct, in mentioning that the order the link attributes are defined in, can fix this problem.

Samuel Jenks
  • 1,137
  • 4
  • 21
  • 34