Let's say we're building a shared library A that needs to link to 2 external static libs B and C. All you've got are libB.a and libC.a, along with their header files.
Here's a simplified Android.mk for libA:
LOCAL_LDLIBS := ../external/libB.a ../external/libC.a
include $(BUILD_SHARED_LIBRARY)
AFAIK, the way linking works for shared libraries is:
- grab all object files of B and C
- strip out object files that A doesn't reference
- resolve references in B and C
This gives link errors because B and C call each other, specifically they call functions that got stripped out in step 2 because A didn't call them.
If we built the static libs ourselves, then it's simply a matter of replacing LOCAL_STATIC_LIBRARIES with LOCAL_WHOLE_STATIC_LIBRARIES, which prevents code stripping (at the expense of code size). Under the hood, it passes --whole-archive to the linker.
Since we didn't build B and C (and don't even have the source to rebuild them), what are the options?
- manually reference the missing functions from A, so that they don't get stripped
- figure out how to pass --whole-archive to the linker for the external static libraries
- use the PREBUILT_STATIC_LIBRARY (seen it mentioned, but never used it, and the according to the docs it doesn't sound applicable in this case)
- build an executable instead of a shared library (which won't strip code the same way)
- move/rename external libs to trick the NDK build system into thinking they're mine, so that I can add them to LOCAL_WHOLE_STATIC_LIBRARIES.
I've gone with option 1 because it's the first thing that worked, but obviously it's not great. I'm asking whether there's a better solution.
The answer to this question ( Linking issue when prebuilt static and shared libraries with the Android NDK ) made me wonder if I need to re-evaluate my build setup (shared library linking to external static library). I'm unable to comment there, so I asked my own question here.