-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
(Background: using SWIG requires adding and exporting the contents of a single .o file into the resulting .so/.dll)
Using cc
in build.rs
I add a small C library to my crate:
let out_dir = std::env::var("OUT_DIR").expect("cannot build in non-UTF8 target directory");
cc::Build::new()
.cargo_metadata(false)
.file("automerge_wrap.c")
.compile("automerge_wrap");
println!("cargo:rustc-link-lib=static:+whole-archive=automerge_wrap");
println!("cargo:rustc-link-search={}", out_dir);
This results in the required symbols being exported from target/debug/libmycrate.a
, like so:
> nm target/debug/libmycrate.a
...
0000000000000000 T CSharp_new_AMvalue
However, the dynamic library target/debug/libmycrate.so
does not contain this symbol. I can add it by using it:
pub mod other_sym {
extern "C" {
pub fn CSharp_new_AMvalue();
}
#[no_mangle] pub unsafe fn __dummy() {
CSharp_new_AMvalue();
}
}
The result is that the symbol is present, but it is not exported (note the small t
instead of a capital T
):
> nm target/debug/libmycrate.so
...
0000000000130eef t CSharp_new_AMvalue
I tried with Rust 1.61 and 1.62, played with linker options, e.g. by linking automerge_wrap.o
instead of the library, but I found no way to change this. Adding wrapper functions is impossible (well, hard at least) because the symbols already have the exact name in the auto-generated .c file that I have to use in the .so file.
To me, this qualifies as a bug. If this is not a bug, then please let me know how I can get an extern "C"
symbol into the cdylib with public visibility.