-
Notifications
You must be signed in to change notification settings - Fork 396
Description
Hello David,
Firstly, thank you for your amazing contributions to the world of Rust!
Secondly, I have begun testing your crate and have experienced some problems with the adoption on a small, but real-world example library I am starting on. I am very eager to start using the crate!
I have made an example project on GitHub to potentially help others, but also to explain the issues that I'm having.
https://github.com/david-cattermole/cxx-demo-example
Linking Errors
When building and linking the Rust library into a shared library (.so / .dll), I am getting linking errors on both Windows MSVC and CentOS Linux with GCC.
GCC 6.3.1:
CMakeFiles/mmscenegraph_tests.dir/tests/test_b.cpp.o: In function `test_b()':
test_b.cpp:(.text+0x65): undefined reference to `rust::cxxbridge05::Str::Str(std::string const&)'
CMakeFiles/mmscenegraph_tests.dir/src/lib.cpp.o: In function `mmscenegraph::make_demo(rust::cxxbridge05::Str)':
lib.cpp:(.text+0x14b): undefined reference to `rust::cxxbridge05::Str::operator std::string() const'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `mmscenegraph$cxxbridge05$make_demo':
_cxxbridge.cpp:(.text+0x10): undefined reference to `rust::cxxbridge05::Str::Str()'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `mmscenegraph$cxxbridge05$do_thing':
_cxxbridge.cpp:(.text+0x9c): undefined reference to `cxxbridge05$box$mmscenegraph$ThingR$drop'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `mmscenegraph::print_r(mmscenegraph::ThingR const&)':
_cxxbridge.cpp:(.text+0xb1): undefined reference to `mmscenegraph$cxxbridge05$print_r'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `rust::cxxbridge05::Box<mmscenegraph::ThingR>::uninit()':
_cxxbridge.cpp:(.text+0x131): undefined reference to `cxxbridge05$box$mmscenegraph$ThingR$uninit'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `rust::cxxbridge05::Box<mmscenegraph::ThingR>::drop()':
_cxxbridge.cpp:(.text+0x141): undefined reference to `cxxbridge05$box$mmscenegraph$ThingR$drop'
Visual Studio 2015:
CMakeFiles/mmscenegraph_tests.dir/tests/test_b.cpp.o: In function `test_b()':
test_b.cpp:(.text+0x65): undefined reference to `rust::cxxbridge05::Str::Str(std::string const&)'
CMakeFiles/mmscenegraph_tests.dir/src/lib.cpp.o: In function `mmscenegraph::make_demo(rust::cxxbridge05::Str)':
lib.cpp:(.text+0x14b): undefined reference to `rust::cxxbridge05::Str::operator std::string() const'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `mmscenegraph$cxxbridge05$make_demo':
_cxxbridge.cpp:(.text+0x10): undefined reference to `rust::cxxbridge05::Str::Str()'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `mmscenegraph$cxxbridge05$do_thing':
_cxxbridge.cpp:(.text+0x9c): undefined reference to `cxxbridge05$box$mmscenegraph$ThingR$drop'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `mmscenegraph::print_r(mmscenegraph::ThingR const&)':
_cxxbridge.cpp:(.text+0xb1): undefined reference to `mmscenegraph$cxxbridge05$print_r'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `rust::cxxbridge05::Box<mmscenegraph::ThingR>::uninit()':
_cxxbridge.cpp:(.text+0x131): undefined reference to `cxxbridge05$box$mmscenegraph$ThingR$uninit'
CMakeFiles/mmscenegraph_tests.dir/src/_cxxbridge.cpp.o: In function `rust::cxxbridge05::Box<mmscenegraph::ThingR>::drop()':
_cxxbridge.cpp:(.text+0x141): undefined reference to `cxxbridge05$box$mmscenegraph$ThingR$drop'
I am using CMake for the C++ side, and Cargo for the Rust side, with a Bash and Windows Batch script gluing them together.
My approach is to generate the headers using cxx, and cbindgen, then compile the Rust crate as a "staticlib" and link the Rust static library with a C++ shared library, combining the Rust symbols into the C++ shared library, with a single C++ interface.
I have noticed that most (but not all) of the problem functions are defined in the extern "Rust" block here:
https://github.com/david-cattermole/cxx-demo-example/blob/main/src/cxxbridge.rs#L22
I have also noticed that the generated C++ functions do not implement those functions and that is the true cause for the missing symbols at linking stage. For example mmscenegraph$cxxbridge05$print_r:
https://github.com/david-cattermole/cxx-demo-example/blob/main/src/_cxxbridge.cpp#L243
You can see the full output of the build_linux.bash and build_windows.bat scripts:
output_gcc_6_3_1.log or here on GitHub
output_msvc_19_0_24215_1.log or here on GitHub
I have also attempted to use "cxx v0.4.7", but I seem to get the same problem.
Am I missing something? Is my use case not supported? Is this a bug in cxx? I am I misusing cxx?
Example Project Goals
For context, the goal for the example project is to write a cross platform Rust and C++ library, with the main client being an existing C++ application, taking advantage of Rust whenever possible.
I also intend to call other C++ library dependencies, integrating well established C++ libraries that are dominate in my industry (Visual Effects).
Therefore I will use cxx/cxxbridge to create the C++ bindings, and then fallback on cbindgen whenever I hit a missing feature.
Thank you,
David Cattermole