0

I am building a C++ library for android. I have X.so shared library which ends up in the android app and it's accessed through JNI. I also have a Y.a static library which has few generic functions that is used by X.so. Y.a also has some JNI interface functions as well that should be accessible by the android app. Currently the problem I'm having is that, after building Y.a, I can see all the symbols I need to be exported. But after linking that to X.so, linker discards all the JNI interface functions because they are not used internally. I tried the following 2 options without any luck,

1.

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL myImportantFunction(JNIEnv*, jclass);
.
.
.

void* volatile tmp = (void*)&myImportantFunction;
#ifdef __cplusplus
}
#endif

2.

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void __attribute__((used)) JNICALL myImportantFunction(JNIEnv*, jclass);
.
.
.

#ifdef __cplusplus
}
#endif

If there are any clang attributes or hacks which can force the linker not to discard specific functions I need (when I'm building Y.a) it would be ideal. Thank you all for any help in this regards.

  • See e.g. https://stackoverflow.com/questions/7253801/how-to-force-symbols-from-a-static-library-to-be-included-in-a-shared-library-bu Though it sounds like you're going about this the wrong way. Why don't you just put all your exported functions in the code of the shared library instead? – Michael Sep 23 '20 at 15:26
  • Hi Michael, Thanks for the reference. However, the functions that are needed by X.so does not reside in the same object file as the functions that should be exported. So --whole-archive shouldn't work I think? Also the reason for the separation is that Y.a is used by multiple shared libraries (basically Y.a is my licensing library which is used by all of my products) – Dulaj Viduranga Sep 23 '20 at 15:29
  • Every product (X.so etc) will use the licensing library to check the status. Android side (Java) should access the licensing library to initialise with his license key. – Dulaj Viduranga Sep 23 '20 at 15:32

1 Answers1

1

If you want to keep the entire Y.a, then -Wl,--whole-archive -lY -Wl,--no-whole-archive is indeed the way to go.

If you want to keep only specific symbols from Y.a, but let the linker discard other (unused) object files from it, then you need to tell the linker that these functions are used, like so:

g++ -u myImportantFunction x1.o x2.o ... -lY -shared -o X.so
Employed Russian
  • 199,314
  • 34
  • 295
  • 362