I am trying to develop on android NDK. I actually have a project + subfolder with modules (compiled as static libraries) and linked together with the main project files (libs .a + main object .o --> executable). Everything done via ndk-build.
I am trying to make use of constructors, after digging for some hours I figured out that constructors are NOT called as long as a function of that lib (.o) is not invoked.
e.g.
__attribute__ ((__constructor__))
void pre_func(void) {
printf("pre_func2\n");
}
void my_init(){
printf ("tutto funge!");
//return 0;
}
called only when (and before) my_init(); is explicitly invoked in test.c
$ adb shell /data/local/tmp/test
pre_func2
tutto funge!
now, my issue is very simple. By architecture I need some modules I prepared to be initialized when the object is loaded... I searched several stuff (--init, _init()) none of them helps.
Since the same code on standard linux (glibc and no bionic linker) looks to work fine, is there something wrong in my compilation gcc statement which avoids the constructor to be executed at .a loading time? how can I solve?
Compile thumb :
modules <= libtest.c
/opt/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm- linux-androideabi-gcc -MMD -MP -MF ./obj/local/armeabi/objs/modules/libtest.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -g -DNDEBUG -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Ijni/modules -DANDROID -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -Wa,--noexecstack -I/opt/android-ndk-r8e/platforms/android-3/arch-arm/usr/include -c jni/modules/libtest.c -o ./obj/local/armeabi/objs/modules/libtest.o
StaticLibrary : libmodules.a
rm -f obj/local/armeabi/libmodules.a
/opt/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar crs ./obj/local/armeabi/libmodules.a ./obj/local/armeabi/objs/modules/libtest.o ./obj/local/armeabi/objs/modules/module.o
I guess that the problem is that if some .o is not called from test.c, it is not linked into the test executable. That's how the liner treats static libraries (.a files). To force all compilation units (a.k.a. .o files) to be present in the executable, use
-Wl,-whole-archive libmodules.a -Wl,-no-whole-archive
for building. You can achieve this in NDK by specifying
LOCAL_WHOLE_STATIC_LIBRARIES := modules
but I must confess that I have never tried this with $(BUILD_EXECUTABLE). It works fine for $(BUILD_SHARED_LIBRARY). If something goes wrong, simply write
LOCAL_LDFLAGS := -Wl,-whole-archive $(PATH_TO_LIBMODULES)/libmodules.a -Wl,-no-whole-archive
and don't forget to set PATH_TO_LIBMODULES correctly.
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