I have a static library that contains some JNICALL functions, i.e. they are expected to be called from the JVM and are never referenced by the shared library that links the static library.
However, it seems like function stripping is exterminating the JNICALL function (it's not visible in arm-eabi-objdump -t). I'm working around it by adding a dummy function with an impossible condition that calls the JNICALL function, but that's dirty. I know that there is a link option to prevent certain modules from getting their unused data stripped, but what is it? And how do I specify that option in the .mk file? I didn't see anything immediately obvious in arm-eabi-ld.
Incidentally, the function stripping doesn't strip out JNICALL functions in the shared library itself, but it will remove those from the static library that the shared library is linking. What's the reason for that?
It actually looks like the NDK team started supporting that (or stopped?), and there are traces of it in the build system, but some vital parts are missing. The good news is that it can be easily implemented.
Go to the "build" directory in the NDK installation and search for all instances of LOCAL_STATIC_LIBRARIES. Copy and paste all of them and add a version that version that does the same thing with LOCAL_STATIC_WHOLE_LIBRARIES.
To be precise: In build/core/build-binary.mk, you'll need:
LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))
LOCAL_STATIC_WHOLE_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_WHOLE_LIBRARIES))
[...]
static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
static_whole_libraries := $(call map,static-library-path,$(LOCAL_STATIC_WHOLE_LIBRARIES))
[...]
$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_LIBRARIES))
$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_WHOLE_LIBRARIES))
[...]
$(LOCAL_BUILT_MODULE): $(static_libraries) $(static_whole_libraries) $(shared_libraries)
[...]
$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
$(LOCAL_BUILT_MODULE): PRIVATE_WHOLE_STATIC_LIBRARIES := $(static_whole_libraries)
Note the discrepancy between STATIC_WHOLE and WHOLE_STATIC - that's how it is in the NDK, I chose to keep it that way even though it's inconsistent.
Now, finally, in build/toolchains/arm-eabi-4.4.0/setup.mk: There's already the PRIVATE_WHOLE_STATIC_LIBRARIES block for shared libraries. You can choose to add that for executables as well, although that's most likely not necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With