How can I link object file for final executable file from build.rs in rlib?

In NativeAOT in .NET 8 or later, we need to link libbootstrapperdll.o/bootstrapperdll.obj to final executable to initialize NativeAOT.
(this code is compiled to libbootstrapperdll.o and distributed as a part of NativeAOT runtime.)

I'm making rlib library crate with NativeATO staticlib so I have to ask cargo to link libbootstrapperdll.o for final binary linker.

What's the best way to link some object file for executable file?

What I tried

  • I added println!("cargo:rustc-link-arg={bootstrapper}"); to build.rs of the rlib crate. but it does not add bootstrapperdll.o for linking executable.
  • I craeated libbootstrapper.a which contains libbootstrapper.o and added println!("cargo:rustc-link-lib=static=bootstrapperdll"); to build.rs of the rlib crate.
    • This adds libbootstrapper.o to the rlib file but the linker does include nothing from libbootstrapper.o since any symbols in libbootstrapper.o is referenced from nowhere.

What I know

  • I know full path to libbootstrapperdll.o in build.rs of rlib crate.
  • I have full control of build.rs of bin crate for my usage so I can add some code in bin crate. (However, build.rs of bin crate does not know where bootstrapperdll.o is at.)
1 Like

Did you have any success with this? I am currently hitting a similar issue

In my case, the contents of bootstrapperdll is small so I rewrite bootstrapperdll with rust and call it before calling before ffi function as a workaround.

I think you want #[link]. Even if you don't directly link to any symbols, you can tell the Rust code it needs to link to a dylib with

#[link(name = "bootstrapperdll")]
extern {}
1 Like

Today I tried again and I found that creating libbootstrapperdll.a (or bootstrapper.lib) and linking with +whole-archive works well.