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

Rust does not dynamically export functions in Android shared library #27541

Closed
FuegoFro opened this issue Aug 5, 2015 · 7 comments
Closed

Rust does not dynamically export functions in Android shared library #27541

FuegoFro opened this issue Aug 5, 2015 · 7 comments
Labels
O-android Operating system: Android

Comments

@FuegoFro
Copy link

FuegoFro commented Aug 5, 2015

I've been trying to compile Rust for Android and call exported JNI functions directly from Java, without a C++ shim in between. I found that if I marked a function as #[no_mangle] pub extern "C" it would show up in the symbol table just like JNI exported functions in C++, but it wasn't in the dynamic symbol table. That is to say, when running arm-linux-androideabi-nm on the .so produced by Rust, the symbol was there, but when running the same command with the -D flag, the symbol wasn't there. Since Java looks up its JNI calls dynamically, this meant that it couldn't find the functions I was referencing.

I was able to get around this by setting my linker to a wrapper script around arm-linux-androideabi-gcc which also passed in the additional -Wl,--export-dynamic flag. This solved the issue and allowed Android to find the functions. This is kind of a pain and, more importantly, only fixes the issue for me. It'd be great if, when compiling for Android, Rust automatically dynamically exported all extern functions. Alternatively, I could imagine some directive similar to #[no_mangle] that specifies that a function should be exported dynamically. Rust could use the --Wl,--dynamic-list= flag when invoking the linker to specify which functions should be exported dynamically.

I'd be happy to create a sample project which demonstrates the problem if that would be useful for diagnosing it.

I looked through the existing bugs and didn't see anything that described this exactly, but #10356 looked like it might be exhibiting the same problems.

Only somewhat relatedly, the deprecated wiki for how to get Rust to compile for Android was a) quite hard to find and b) super useful. Is there a reason that has been deprecated? Is there a place to put this information (about the dynamic exports) such that other people will be able to find it easily if they're also trying to use Rust with Android's JNI?

@ProtectedMode
Copy link

I encountered the same issues when trying to use the LuaJIT FFI to call Rust's exported C functions. Wouldn't Cargo support to pass these flags be the easiest solution?

@Aatch
Copy link
Contributor

Aatch commented Aug 6, 2015

Note that you should be able to pass the extra flag to the linker by using -Clink-args=--export-dynamic. I'm not really sure what to do here though, as it seems this is normally unecessary as you can use dlsym to access any exposed symbol, not just those in the dynamic symbol table.

I think the best option would be to add support for setting the link args to Cargo, which would be a Cargo issue.

@alexcrichton thoughts?

@alexcrichton
Copy link
Member

I'm somewhat surprised that we've never run into this before, so I'd want to take some time to investigate what's going on and learn why this is different than dynamic library usage on other situations. Regardless, though, in #27416 we'll gain the ability to tell the linker the exact set of symbols that must be exported from a dynamic library, so I suspect that infrastructure can just be re-used to handle this case as well.

@FuegoFro
Copy link
Author

The documentation and tutorials I saw suggested using a C++ shim in between the Java and Rust code, relying on ndk-build to statically link to the Rust library at compile time and export its corresponding symbols properly. But I do agree that it's odd that this doesn't seem to have been run into elsewhere, and I'm more than willing to entertain the possibility that I messed something up. Again, if it'd be useful, I can provide a small sample project that reproduces the issue for me.

@alexcrichton
Copy link
Member

If you compile just a standard C program without any special linker flags, is it accessible from the Android side of things? That's basically what all Rust code is, and it'd be good to know what the bare minimum is needed to get C working as we'd just do the same thing.

@steveklabnik
Copy link
Member

Triage: @alexcrichton asked for some clarifications, but hasn't gotten any yet. @FuegoFro are you still struggling with this?

@Mark-Simulacrum
Copy link
Member

I'm going to close this. @FuegoFro if this is still a problem for you please answer the questions @alexcrichton asked and we'll reopen. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-android Operating system: Android
Projects
None yet
Development

No branches or pull requests

6 participants