Description
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?