Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiling cdylib #1331

Open
smvoss opened this issue Mar 28, 2024 · 4 comments
Open

Compiling cdylib #1331

smvoss opened this issue Mar 28, 2024 · 4 comments

Comments

@smvoss
Copy link

smvoss commented Mar 28, 2024

Hi,

I am attempting to compile my rust / c++ project into a single .so file that can be dynamically loaded by another application (implementation of a c++ headerfile that uses some rust calls, linked from a c++ app). This seems to generally work when using a static library with only needing to link the top-level library:

-Ltarget/debug -lmylib

(assuming target/debug/libmylib.a)

however when attempting to do the same for a cdylib I need to also link the library created during the build script as such:

-Ltarget/debug -lmylib ${OUT_DIR}/lib-built-by-cxxbuild.a

(assuming targ/debug/libmylib.so)

If I do not explicitly include the static library built as part of build.rs (cxx_build::[..].compile("built-by-cxxbuiild")) I have missing symbols.

Any advice on how to bridge this gap, so that all symbols are exported in the .so. I have attempted to add some linking flags to my build script, such as println!("cargo::rustc-link-lib=static={..}) to no avail.

If it makes a difference, the code exclusively calls from c++ to rust, and not the other way. This is being used as a C++ "shim" to provide a rust implementation of a c++ interface for a shared library.

Thanks!

@jwhear
Copy link

jwhear commented Apr 24, 2024

I was tinkering with this myself today. My workaround solution at the moment is to build the rust code as a static library. Here's my setup (crate name is sqlite_adaptor).

// Cargo.toml
[lib]
crate-type = ["staticlib"]

This produces target/debug/sqlite_adaptor.a

The next step is to link this static library with the cxxbridge static library built by your build.rs into a shared library:

// Makefile
debug: target/debug/libsqlite_adaptor.so
bridge = $(shell find target/debug/ -name libcppbridge.a)

target/debug/libsqlite_adaptor.so:
	gcc -shared -Wl,--whole-archive target/debug/libsqlite_adaptor.a \
		-Wl,--no-whole-archive $(bridge) \
		-o target/debug/libsqlite_adaptor.so

This is pretty janky right now as I'm still hacking on it, but it produces a shared library with the symbols from Rust library and the needed bridge code in target/debug/libsqlite_adaptor.so

@tusooa
Copy link

tusooa commented Aug 6, 2024

Having the same issue here. If I set crate-type = cdylib then I will have missing symbols when linking to the dynamic library.

downstream: https://iron.lily-is.land/T128

@smvoss
Copy link
Author

smvoss commented Aug 9, 2024

I ended up basically doing the exact same thing, doing it as a staticlib and then adding an extra stage in a top-level Makefile that really just converts it to a shared object. It's very awkward and I wish it didn't have to be done that way, but it seems like with the current tooling that's what has to be done.

I tested every rustc / cargo option I could find on this and nothing changed the behavior at all, so an extra toolchain on top pretty much is the solution at this point.

@BaxHugh
Copy link

BaxHugh commented Aug 15, 2024

Just to add, that I also have this issue and would love a solution.

redstrate added a commit to redstrate/vodozemac-cpp that referenced this issue Aug 31, 2024
There's a pretty nasty bug where Cargo can't generate the shared library
itself, and we need to do in CMake. This isn't a huge deal, as we can
simply link to the static library created by Cargo.

This is an upstream issue where Rust marks unknown symbols as local, and
they never appear in the dynamic symbol table. There is an open issue
to allow more granular filtering
(rust-lang/rust#104130) as well as an upstream
CXX issue (dtolnay/cxx#1331)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants