Bindings linking conflicts

Hello everyone
I use two crates which are bindings to c++ libraries.
Both c++ libraries link to the same third c++ library they depend on.

When trying to compile the program cargo failed on linking step with the error:

b\\rustlib\\etc\\libstd.natvis"
 = note: libllama_cpp_sys_2-1131e8f6e28c8598.rlib(ggml-backend.obj) : error LNK2005: ggml_backend_buft_name already defined in libwhisper_rs_sys-f2fa5877d4809bf3.rlib(ggml-backend.obj)
         libllama_cpp_sys_2-1131e8f6e28c8598.rlib(ggml-backend.obj) : error LNK2005: ggml_backend_buft_alloc_buffer already defined in libwhisper_rs_sys-f2fa5877d4809bf3.rlib(ggml-backend.obj)

Seems like both llama-cpp-2 and whisper-rs crates uses ggml library and it failed to compile because of that.
Is there a known cross platform solution for this issue?

Thanks

I suppose that might be a C++ problem. The solution might be enable dynamic linking, make the 2 C++ library share the same 3rd library.

If you are not an expert of C++, you may open issues in both llama-cpp-2 and whisper-rs crates, let the crate owner update their build script to add the dynamic linking operation.

(I have no idea whether it is correct, but file an issue is always an acceptable option.)

1 Like

The Rust solution is to create a ggml-backend-sys crate and change both llama-cpp-2 and whisper-rs to import that crate instead of directly linking to the library.

1 Like

If the 3rd library linked dynamically twice it shouldn't be a problem?

Sounds good but I think that whisper.cpp and llama.cpp manage it in Cmake. do I need to tell them to provide option not to link it?

Ah, then yes this would need to be dynamic linking to ggml to resolve the issue at all.

In the mean time while you wait for those projects to get fixed so they can be used in the same program, consider exploring a multi process program design where you split the work across two binaries.

I've forgotten the details, thus file issues to both crate is acceptable.


After several attempts (all of them compile), I finally recognize that, it might be a bug related to MSVC.

A simple search shows that, 请将 /FORCE:MULTIPLE 添加到链接器命令行选项

Thus modify your rustflags to "-C link-arg=/FORCE:MULTIPLE" might be enough.

To be specific, add these lines into Cargo.toml should help:

[target.'cfg(all())']
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

(Actually, target.(msvc's triple) should be better than target.'cfg(all())', but I'm lazy finding the triple.)

I have no MSVC thus have no idea whether it works. Good luck.