views:

100

answers:

2

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?

+1  A: 

See the other question.

fadden
Thanks! I didn't see that when I was looking for an answer. I'll repeat my question on the other thread though - can you post a quick example of how you would need to set up the Android.mk file (at least the two lines pertinent to linking)?
EboMike
I added a note to the other question. I don't know exactly what to do in the NDK build system, but if it works anything like the general Android makefiles you can add the flags to LOCAL_LDFLAGS.
fadden
+1  A: 

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.

EboMike