Would it make a difference if I said that we don't intend to expose any C or C++ APIs to our end users at all? The expected workflow is that the end user codes against our Java API, and our Java API makes use of the included native components. Actually, for the purposes of .NET (which cannot easily link with C++) libnative.so has a complete and usable C API, and all C++ symbols are hidden. That being said, when libnativeJNI.so is built it uses some header only C++ components. I don't directly develop the JNI library, but I have been directly involved with the libnative.so development so I can't say for sure if any linker script is used (though I suspect not) to hide things.
So if I understand correctly, libnative.so is already c++ static safe? And JNI can be made so if everything aside from JNI_OnLoad is hidden (the other JNI calls via "native" marked Java functions will still be usable right? The things that look like com_whatever_native_function, or should those be listed in global as well?).
Before these very helpful insights, I have been attempting to do the following:
Modify all libnative.so and libnativeJNI.so to use c++_shared, and include libc++_shared.so in our maven package. I don't mind if it is clobbered by the app's one, if it even includes one (which I am assuming the majority of our users don't) since we already keep a pretty old C++ API usage. I get fuzzy here since I don't know if there have been any libc++ ABI breaks between say r18b and now. My plan was to build an app which links with NDK r18b, and have it clobber our libc++_shared so ensure that everything still works (the support matrix of Clang indicates that clang 7 is plenty new enough for the features we use). I also wasn't sure if modern gradle would just fail the build outright with two identically named libraries, or if it just warns and clobbers. I also wasn't sure that if the two were identical if that was still an error condition.
However with this new information, it looks like I should be working back toward c++ static again?