user14002455
user14002455

Reputation:

Calling C library from Rust gives "LINK : fatal error LNK1181: cannot open input file"

I'm trying to call the STM32 Cube Programmer C libraries from Rust.

The entire code, and branches showing various attempts, are available here: https://github.com/becky112358/rust_c_linking_stm32_cube_programmer

Attempt 1 (in my GitHub repository, branch main)

Following the Rust Bindgen tutorial: https://rust-lang.github.io/rust-bindgen/

This is my preferred method. A Rust crate wraps the C library. Other Rust crates can then include the Rust wrapper crate, and not have to worry about any C libraries.

... in theory.

The Rust crate wrapping the C library (libstm32_cube_programmer_sys) builds ok. Its tests run ok. The Rust crate calling the Rust crate which wraps the C library (caller) does not build, but reports:

    = note: LINK : fatal error LNK1181: cannot open input file '.\drivers\CubeProgrammer_API.lib'

Why is caller even trying to look for the C library? I expected libstm32_cube_programmer_sys to handle all C library to Rust conversion, and that any Rust crates then calling libstm32_cube_programmer_sys could be purely Rusty (with maybe some unsafeness).

println!("cargo:rustc-link-lib=C:/[blah blah]/drivers/CubeProgrammer_API");

I could not find how to feed in the path correctly, without Rust reporting:

    error: renaming of the library `C` was specified, however this crate contains no `#[link(...)]` attributes referencing this library.



Attempt 2 (branch all_in_one)

In the main branch it seemed like maybe the problem was that libstm32_cube_programmer_sys could find the C library but caller could not. So I tried discarding the separate Rust crate, and having a single Rust crate which both wraps the C library and calls the C functions.

This time I get the following error, plus a bonus warning:

    = note: caller.59pofysds2mkvvjr.rcgu.o : error LNK2019: unresolved external symbol disconnect referenced in function _ZN6caller4main17ha79648c0a9e86ed0E
    .\drivers\CubeProgrammer_API.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'



Attempt 3 (branch link_search)

I searched a lot on the internet and found lots of different ways to call a C library from Rust. One way is to use link-search rather than link-lib. This surely only makes things harder for the compiler because you make it do more work. But I am stuck and need to try different things!

This time I get the following error, plus the bonus warning:

    = note: caller.59pofysds2mkvvjr.rcgu.o : error LNK2019: unresolved external symbol __imp_disconnect referenced in function _ZN6caller4main17ha79648c0a9e86ed0E
    .\drivers\CubeProgrammer_API.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'



Question

How do I make this work? Ideally from Attempt 1, but I'll take anything!

Upvotes: 2

Views: 1549

Answers (1)

user14002455
user14002455

Reputation:

When we have:

C library <- Rust library <- Rust code

It seems that

  • when compiling, the Rust code needs to be able to see the C library, even though it is also calling the Rust library
  • when running, there may be C dlls which you need to store alongside the Rust exe

That was my main misunderstanding when I posted my original question.

Some other tips / reminders:

  • Make sure to use the correct lib file! (x64, x86 etc)
  • Resolve warnings too!

Upvotes: 1

Related Questions