cxx icon indicating copy to clipboard operation
cxx copied to clipboard

undefined reference to sliceInit

Open mayeul-zama opened this issue 4 years ago • 2 comments

I built a Rust staticlib with the following interface:

#[cxx::bridge]
mod ffi {
    extern "Rust" {
        fn test(slice: &[u8]);
    }
}

The C++ code is as simple as

int main()
{
    auto a = rust::Slice<const uint64_t>(nullptr, 0);
    return 0;
}

When trying to link C++ code with librust.a (with some code generated by cxx-bridge), I get undefined reference to rust::cxxbridge1::sliceInit(void*, void const*, unsigned long)'

I guess this function is not exported in the librust.a.

However, when adding to the interface a function returning a Result (for exemple: fn test2() -> Result<bool>) the linking works

mayeul-zama avatar Sep 10 '21 16:09 mayeul-zama

It's defined here. You would need to make sure that whatever linker invocation you are making includes all the C++ and Rust code that this library contains.

dtolnay avatar Sep 10 '21 19:09 dtolnay

Thanks for your quick answer!

So from what I understand I should have a copy of cxx.cc locally in my project

I have two remarks (if my understanding is correct):

  • This implies that I must update this file when updating the cxx dependency and the cxxbridge binary (not sure about compatibility between versions). This is not a big problem but still something not to forget.
  • I find surprising that this file has to be included in some cases but not anymore when a new function is added to the interface so I'm wondering if this is intended (I guess when adding the function test2 in my previous example, the cxx-bridge binary adds the sliceInit wrappers in the exported c++ code, but I don't understand why)

I would find it simpler is the cxxbridge binary always included the needed wrappers from cxx.cc into the exported code (but I guess there's something I don't get)

mayeul-zama avatar Sep 21 '21 14:09 mayeul-zama

It should be automatically built and linked if you're using cargo (or corrosion in CMake etc.). The library and symbols generated from cxx.cc are automatically linked when you include the cxx dependency in your crate as per the build script and links.

However, it may be that cargo decides that the library and by extension its dependencies and in particular cxx is unreachable. cargo's linker may then prune all symbols which would appear as if they were never linked. Make sure that all crates with cxx-dependencies are a publicly visible dependency of the output library.

In my experience, it suffices to have a module like this in your top-level library:

mod _usage {
    pub use crate_with_cxx::*;
}

197g avatar Sep 26 '22 13:09 197g