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

Add ability to set symbol visibility #219

Closed
adetaylor opened this issue Jun 11, 2020 · 2 comments · Fixed by #231
Closed

Add ability to set symbol visibility #219

adetaylor opened this issue Jun 11, 2020 · 2 comments · Fixed by #231
Labels
integration How cxx fits into the big picture of an organization's codebase and builds

Comments

@adetaylor
Copy link
Collaborator

TL;DR:

I've needed to hack my generated .cc files to change:

extern "C" {
void base$cxxbridge03$log_string(::rust::Str::Repr msg) noexcept {
  void (*log_string$)(::rust::Str) = log_string;
  log_string$(msg);
}
} // extern "C"

to

extern "C" {
__attribute__((visibility("default"))) void base$cxxbridge03$log_string(::rust::Str::Repr msg) noexcept {
  void (*log_string$)(::rust::Str) = log_string;
  log_string$(msg);
}

I would like to add the ability to do that, possibly with an additional parameter to the cxx::bridge macro alongside the existing namespace parameter.

Here's why.

Our final build products are:

  • C++ library libservices.so. This C++ depends upon APIs exported from...
  • C++ library libbase.so

Each contains a blob of Rust code:

  • Rust rlib librust_services.rlib
  • Rust rlib librust_base.rlib

librust_services.rlib uses APIs exported publicly by librust_base.rlib. Specifically, the code in librust_services.rlib uses a log() API within librust_base.rlib, which in turn uses native code within the rest of libbase.so.

The only officially approved way to make these C++ binaries is by generating two Rust staticlibs:

  • Rust staticlib libservices_rust_deps.a
  • Rust staticlib libbase_rust_deps.a
    and then linking them into the .so files with all the rest of the C++ code.

So we hope to achieve this call stack:

  • Rust code in librust_services.rlib (which gets built into libservices.so). It calls
  • Rust code in librust_base.rlib, which calls
  • Native code elsewhere in libbase.so

So, where should the code in librust_base.rlib end up? Specifically this log() Rust API?

Ideally, that Rust API would only be in libbase.so and so the Rust code within libservices.so would call other Rust code in libbase.so. But as far as I know, that's impossible. Rust doesn't provide a way to mark Rust code as exported from a staticlib - there is no equivalent to the C directive __attribute__((visibility("default"))). (Again, as far as I understand it) Rust will only attempt to keep C-facing APIs marked with #[no_mangle] directive; there's no way to ask that a given Rust API is exported from a .so which is downstream of a staticlib. (Maybe this merits an issue filed against rust - I'd be interested in opinions - this conflation of exporting vs naming seems to cause trouble now and again, e.g. rust-lang/rust#54135 (comment)).

Given that we can't export the Rust log() API from libbase.so, we need to build the Rust code into libservices.so. But now the Rust code has to depend upon the C++ implementations, which means we need to export them from libbase.so. Hence - the need for the generated C++ code to export the symbols from libbase.so.

Would you accept a PR to add this exporting ability?

@dtolnay
Copy link
Owner

dtolnay commented Jun 12, 2020

Thanks for the detailed explanation. I would accept a PR for a c++ code generator command line flag or an attribute (#[cxx::bridge(namespace = base, dso_export)]?) or whatever you think is more appropriate. Or is it something that would be reasonable to emit unconditionally?

@adetaylor
Copy link
Collaborator Author

Thanks! I've decided to poke the bear of the underlying issue first, and we'll see how that goes, but I fully expect a PR to land on your virtual desk at some point here.

@dtolnay dtolnay added the integration How cxx fits into the big picture of an organization's codebase and builds label Aug 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integration How cxx fits into the big picture of an organization's codebase and builds
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants