If you ever get this cryptic error when loading an Android native app:

java.lang.RuntimeException: Unable to start activity ComponentInfo{org.wikibooks.OpenGL/android.app.NativeActivity}: java.lang.IllegalArgumentException: Unable to load native library: /data/data/org.wikibooks.OpenGL/lib/libnative-activity.so
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
       at android.app.ActivityThread.access$1500(ActivityThread.java:123)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:130)
       at android.app.ActivityThread.main(ActivityThread.java:3835)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:507)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
       at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Unable to load native library: /data/data/org.wikibooks.OpenGL/lib/libnative-activity.so
       at android.app.NativeActivity.onCreate(NativeActivity.java:199)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
       ... 11 more

This may mean that Java couldn't find the ANativeActivity_onCreate function in your code, because it was stripped by the compiler.

If you use the native_app_glue NDK module, you may have noticed this strange code:

    // Make sure glue isn't stripped.

Let's experiment what happens with and without this line:

Calling app_dummy:

$ arm-linux-androideabi-objdump -T libs/armeabi/libnative-activity.so  | grep ANativeActivity_onCreate
000067fc g    DF .text  000000f8 ANativeActivity_onCreate

Not calling app_dummy :

$ arm-linux-androideabi-objdump -T libs/armeabi/libnative-activity.so | grep ANativeActivity_onCreate
$   # nothing

native_app_glue mainly defines Android callbacks. Since none of them are called directly by your code, the compiler strips the android_native_app_glue.o module entirely. If you use app_dummy however, it embeds it. Fortunately the compiler cannot strip the module on a per-function basis ;)

That's why you need to call app_dummy when using the native_app_glue NDK module.

This looks like a ugly work-around though - isn't there a cleaner way?

Oh, but the compiler/linker can strip down by function, e.g. with -ffunction-sections or LTO. It’s a great optimisation. You just have to tell it what to include in the native part and that it makes a native library… all a matter of calling the toolchain correctly.
Comment by Anonymous Wed Feb 8 15:08:21 2012


It's already a native lib (obj/local/armeabi/libandroid_native_app_glue.a), but it's stripped nonetheless. Can you precise what you meant?

Comment by beuc Thu Feb 9 22:55:48 2012
If it’s a .a archite, it’s not a native library (.so/.dll). Those archives are made for the precise PURPOSE of only including the files referenced by other code. So using these is doing it wrong ;-) You basically must compile the C part to the equivalent of a plugin.
Comment by Anonymous Sat Feb 11 14:05:53 2012

Note that it's Google/Android doing, not mine ;)

The use case if indeed uncommon: bundled a set of standard entry points in your .so library. Plus, since the final .so is loaded by JNI it's probably inconvenient to ship 2 .so (one with the standard entry points, one with your additions).

Not sure there's a good answer here.

Comment by beuc Sun Feb 12 23:26:11 2012

Thanks for the info, it helped a lot! However, the function was stripped anyway because I had the -fvisibility=hidden attribute set in my APP_CFLAGS. I don't know exactly why I had it set but I guess it came from the Xcode project which is compiling my engine/game for iOS. Hope this will save someone time :) Cheers! Alex

Comment by Anonymous Sat Sep 8 14:54:18 2012