problem with armeabi-v7a library on ICS

2,240 views
Skip to first unread message

Alex Cohn

unread,
Feb 19, 2012, 1:10:34 PM2/19/12
to android-ndk, android-...@googlegroups.com
We have found recently that on ICS, unlike previous versions, the JNI
libraries are picked up from armeabi directory even if the armeabi-v7a
directory is present, and the device does have appropriate CPU (also
manifested as Build.CPU_ABI).

We have seen this repeat on two devices: out-of-the-box on Galaxy
Nexus, and Motorola XOOM with the official upgrade.

Looking at the platform source code, I can see the root of this
problem: the logic to unpack libraries has been moved from Java to /
base/core/jni/com_android_internal_content_NativeLibraryHelper.cpp,
and there seems to be a bug in the native code, that the loop for a
library (line 287) does not check that there already exists a match in
APK for cpuAbi, and overwrites this file with a match for cpuAbi2
(around line 317).

We can work around this bug in an ugly manner: give all lib files
different names... Anyway, that's what we are forced to do today to
provide support both fro Tegra and Neon devices. But I am looking for
a cleaner solution.

Sincerely,
Alex

Yuku Sugianto

unread,
Feb 20, 2012, 10:38:12 AM2/20/12
to andro...@googlegroups.com, android-...@googlegroups.com
Hi Alex,

2 weeks ago I posted this issue that seems to be the same problem,

and around the same time I also took a look at the source code,
and I think the issue is the same as your findings, which is, the installation
routine just iterates through the apk and copies the .so files that is
compatible with either CPU_ABI or CPU_ABI2. But if the CPU_ABI2 lib 
is present in the apk file *after* the CPU_ABI lib, the CPU_ABI2 lib
is overwritten over the CPU_ABI lib.

The workaround (I haven't tested yet) is probably to alter the order 
of the .so files in the apk file, so that CPU_ABI2 lib appears before 
the CPU_ABI lib. (e.g. armeabi/libyourlib.so, then armeabi-v7a/libyourlib.so)

Maybe we can star the issue to help it receive attention?

David Turner

unread,
Feb 20, 2012, 12:48:16 PM2/20/12
to andro...@googlegroups.com
I looked deeper into this issue and I confirm that the bug exists in all ICS releases to date, it's a platform bug, unrelated to the NDK itself :-(.

The fix has been already submitted internally and should be part of the next minor platform update (sorry, can't give any ETAs here).

I'm really sorry, this is really very unfortunate. At this point, there are two ways to work-around the issue:

1/ As mentioned previously, ensure that the armeabi-v7a binaries are packaged _after_ the armeabi ones in the final .apk. This is not trivial, but one way to do it is remove the armeabi-v7a files from the package, then add them back, manually.

2/ I believe a second way is to provide separate packages on market for different devices on Market, but it is also very painful.

- David

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/android-ndk/-/VU2hklB1LrgJ.

To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

Olivier Guilyardi

unread,
Feb 21, 2012, 2:56:33 AM2/21/12
to andro...@googlegroups.com
Hello David,

On Mon, Feb 20, 2012 at 6:48 PM, David Turner <di...@android.com> wrote:
> I looked deeper into this issue and I confirm that the bug exists in all ICS
> releases to date, it's a platform bug, unrelated to the NDK itself :-(.
>
> The fix has been already submitted internally and should be part of the next
> minor platform update (sorry, can't give any ETAs here).
>
> I'm really sorry, this is really very unfortunate. At this point, there are
> two ways to work-around the issue:

It's pretty unfortunate indeed, but I found that automatic ABI
selection was already unreliable in the past on specific device (eg:
Milestone). This is of course different from a platform bug, but it
led me to decide not to rely on it, a long time ago.

> 1/ As mentioned previously, ensure that the armeabi-v7a binaries are
> packaged _after_ the armeabi ones in the final .apk. This is not trivial,
> but one way to do it is remove the armeabi-v7a files from the package, then
> add them back, manually.
>
> 2/ I believe a second way is to provide separate packages on market for
> different devices on Market, but it is also very painful.

I have a different approach. I put both arm and armv7 binaries into
the armeabi directory, and I then use the cpu-features library in
order to decide whether I load the optimized library or not, using
dlopen(). It works just great.

To avoid wasting space, this only concerns critical routines in my
code, but I suppose that a more global approach, eg implementing
JNI_OnLoad() as a wrapper, and registering native methods from the
dlopen()'ed object should be pretty easy.

--
Olivier

Alex Cohn

unread,
Feb 21, 2012, 9:47:43 AM2/21/12
to android-ndk
Hello Olivier,

On Feb 21, 9:56 am, Olivier Guilyardi <olivier.guilya...@gmail.com>
wrote:
You're right that we can work around the platform choice of installed
libraries. Unfortunately, even regardless the ICS bug, this platform
choice has limited value because it lacks the wisdom to understand to
choose between neon and Tegra.

As for the global approach, you can simply use LoadLibrary() from your
Java code based on the CPU features. If you use a cpu-neutral JNI
library that should choose between v7 or neon specific libraries, you
should load these optimized libraries before you load the JNI library.
This way, you can avoid dlopen() altogether.

Sincerely,
Alex

Olivier Guilyardi

unread,
Feb 22, 2012, 12:28:16 AM2/22/12
to andro...@googlegroups.com
Le 02/21/2012 03:47 PM, Alex Cohn a �crit :

> On Feb 21, 9:56 am, Olivier Guilyardi<olivier.guilya...@gmail.com>
> wrote:

>> I have a different approach. I put both arm and armv7 binaries into
>> the armeabi directory, and I then use the cpu-features library in
>> order to decide whether I load the optimized library or not, using
>> dlopen(). It works just great.
>>
>> To avoid wasting space, this only concerns critical routines in my
>> code, but I suppose that a more global approach, eg implementing
>> JNI_OnLoad() as a wrapper, and registering native methods from the
>> dlopen()'ed object should be pretty easy.
>>
>> --
>> Olivier
>
> You're right that we can work around the platform choice of installed
> libraries. Unfortunately, even regardless the ICS bug, this platform
> choice has limited value because it lacks the wisdom to understand to
> choose between neon and Tegra.

For what's it's worth, the cpufeatures library included with the NDK can
detect neon supp�rt.

> As for the global approach, you can simply use LoadLibrary() from your
> Java code based on the CPU features. If you use a cpu-neutral JNI
> library that should choose between v7 or neon specific libraries, you
> should load these optimized libraries before you load the JNI library.
> This way, you can avoid dlopen() altogether.

Ah yeah right, LoadLibrary() is even better. You'd then just need a
minimal library that wraps cpufeatures, used to decide which object to
load from Java.

--
Olivier

Alex Cohn

unread,
Feb 22, 2012, 2:58:08 AM2/22/12
to android-ndk
On Feb 22, 7:28 am, Olivier Guilyardi <olivier.guilya...@gmail.com>
wrote:
>
> Ah yeah right, LoadLibrary() is even better. You'd then just need a
> minimal library that wraps cpufeatures, used to decide which object to
> load from Java.
>
> --
>    Olivier

You can find an example of Java code that reads and interprets /proc/
cpuinfo here:
http://neurodroid.googlecode.com/git-history/af260ccffb8a2f70de42f56b98ca7f65dd58c0d5/neurodroid/src/org/neurodroid/NeuroDroid.java

Enjoy,
Alex

Maxime BRÉNON

unread,
Mar 20, 2012, 5:56:40 AM3/20/12
to andro...@googlegroups.com
Hi everyone,

I wrote a detailed post to explain a workaround for this bug, available here: http://www.moodstocks.com/2012/03/20/ice-cream-sandwich-why-native-code-support-sucks/
From my experience, trying to change the files order in the apk is not much reliable, but implementing a solution using loadLibrary combined with cpufeatures works perfectly!

Max
Reply all
Reply to author
Forward
0 new messages