Linking a C static library with Rust, and then using that in a dylib


#1

I’m having trouble linking with native dependencies again…

I have a crate called glsl_optimizer which links to libglsl_optimizer.a inside.
Then I require glsl_optimizer in another crate rust_to_glsl_lint, which is a compiler plugin and thus has a crate type of dylib.
Compilation of glsl_optimizer works fine, but when it then fails when trying to link rust_to_glsl_lint, saying there are 1424 duplicate symbols.

I’ve checked the actual file libglsl_optimizer.a with nm glsl_optimizer/lib/libglsl_optimizer.a | grep '__mesa_bitcount_64' (that’s one of the many duplicate names) and I can only find one entry. I think Rust must be trying to link the static library twice.

here is glsl_optimizer/Cargo.toml

[package]
name = "glsl_optimizer"
version = "0.1.0"
build = "build.rs"
links = "glsl_optimizer"

[dependencies]
libc = "*"
bitflags = "*"

Here is rust_to_glsl_lint/Cargo.toml:

[package]
name = "rust_to_glsl_lint"
version = "0.1.0"

[lib]
name = "rust_to_glsl_lint"
crate-type = ["dylib"]

[features]
optimize_shaders = ["glsl_optimizer"]

[dependencies]
clippy = "*"
itertools = "0.4"
regex = "*"
regex_macros = "*"
maplit = "*"
linked-hash-map = "0.0.6"
glsl_optimizer = { optional = true, path = "../glsl_optimizer" }

And also glsl_optimizer/build.rs

use std::path::Path;

fn main() {
    let current_path = Path::new(file!());
    let lib_path = Path::new(env!("PWD")).join(current_path.parent().unwrap().join("lib"));
    println!("cargo:rustc-link-lib=static=glsl_optimizer");
    println!("cargo:rustc-link-search=native={}", lib_path.to_str().unwrap());
}

Thanks very much if you could assist me


#2

Turns out running nm target/debug/deps/libglsl_optimizer-680458b41ce736ba.rlib | grep '__mesa_strdup' (or another symbol name) does list exactly two entries:

0000000000000910 T __mesa_strdup
0000000000000910 T __mesa_strdup

Does that mean that my glsl_optimizer crate has linked in the library twice somehow? How could that happen.

I must apologise Rust is my first language that I’ve used where I have to deal with things like ‘linking’ object files and static libraries. If there is something obvious I am missing please let me know.