Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__attribute__ ((__constructor__)) in android

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
like image 492
Vito Avatar asked Mar 07 '26 18:03

Vito


1 Answers

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.

like image 142
Alex Cohn Avatar answered Mar 09 '26 08:03

Alex Cohn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!