I have been trying to compile a simple rust cdylib
crate in windows and linking it with a simple c program. Despite all my efforts I fail to link the dll
file.
Minimal example
First of all my rustc
version is:
C:\Users\User> rustc --version
rustc 1.50.0 (cb75ad5db 2021-02-10)
I have a basic Cargo.toml
which includes a cbindgen
and sets the crate type:
[package]
name = "mycrate"
version = "0.1.0"
authors = ["PauMAVA <--REDACTED-->"]
edition = "2018"
[lib]
name = "mycrate"
crate-type = ["cdylib"]
[build-dependencies]
cbindgen = "0.18.0"
Then the lib.rs
only declares a really simple extern hello world function:
#[no_mangle]
pub extern "C" fn test_fn() {
println!("Hello world from Rust!")
}
Finally, I generate the header file via cdbindgen
in build.rs
:
extern crate cbindgen;
use std::env;
use std::path::Path;
use cbindgen::{Config, Builder};
fn main() {
let crate_env = env::var("CARGO_MANIFEST_DIR").unwrap();
let crate_path = Path::new(&crate_env);
let config = Config::from_root_or_default(crate_path);
Builder::new().with_crate(crate_path.to_str().unwrap())
.with_config(config)
.generate()
.expect("Cannot generate header file!")
.write_to_file("testprogram/headers/mycrate.h");
}
The generated header is the following:
/* Generated with cbindgen:0.18.0 */
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
void test_fn(void);
The C code I have is the following simple program:
#include <stdio.h>
#include "headers/mycrate.h"
int main() {
printf("Hello world from C!\n");
test_fn();
}
Just to clarify, my file structure is the following:
testprogram
|-- headers
| |-- mycrate.h
|
|-- main.c
|-- mycrate.dll
When I try to compile and link I get a linker error:
C:\Users\User\...\testprogram> gcc .\main.c -L.\mycrate.dll -o .\main
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Pau\AppData\Local\Temp\cccQGbDk.o:main.c:(.text+0x1b): undefined reference to `test_fn'
collect2.exe: error: ld returned 1 exit status
Additional Information
The weird thing is that when compiling in WSL (Linux) I get a .so
Linux library that just links correctly:
$ gcc main.c -L./mycrate.so -o main
$ ./main
Hello world from C!
Hello world from Rust!
What am I missing here? I guess this is merely a linking issue but I can't find the source of it. Any help is appreciated!
EDIT
I have also tried using an absolute path when linking.
I am currently using MinGW
.
EDIT 2
Also tried linking with the include library mycrate.dll.lib
generated by cargo:
C:\Users\User\...\testprogram> gcc .\main.c -L.\mycrate.dll.lib -o .\main
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Pau\AppData\Local\Temp\ccL0sH7B.o:main.c:(.text+0x1b): undefined reference to `test_fn'
collect2.exe: error: ld returned 1 exit status
The rustc --version --verbose
output is:
C:\Users\User\...\testprogram> rustc --version --verbose
rustc 1.50.0 (cb75ad5db 2021-02-10)
binary: rustc
commit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b
commit-date: 2021-02-10
host: x86_64-pc-windows-msvc
release: 1.50.0